mirror of
https://github.com/github/codeql.git
synced 2026-04-24 00:05:14 +02:00
Merge branch 'main' into rust-data-flow-consistency
This commit is contained in:
2
.github/codeql/codeql-config.yml
vendored
2
.github/codeql/codeql-config.yml
vendored
@@ -9,3 +9,5 @@ paths-ignore:
|
||||
- '/python/'
|
||||
- '/javascript/ql/test'
|
||||
- '/javascript/extractor/tests'
|
||||
- '/rust/ql/test'
|
||||
- '/rust/ql/integration-tests'
|
||||
|
||||
7
.github/workflows/rust-analysis.yml
vendored
7
.github/workflows/rust-analysis.yml
vendored
@@ -55,12 +55,7 @@ jobs:
|
||||
with:
|
||||
tools: ${{ steps.codeql.outputs.nightly_bundle }}
|
||||
languages: ${{ matrix.language }}
|
||||
config: |
|
||||
disable-default-queries: true
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
paths-ignore:
|
||||
- '/rust/ql/tests'
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@main
|
||||
|
||||
@@ -196,6 +196,8 @@ private predicate isInvalidFunction(Function func) {
|
||||
expr.getEnclosingFunction() = func and
|
||||
not exists(expr.getType())
|
||||
)
|
||||
or
|
||||
count(func.getEntryPoint().getLocation()) > 1
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,31 +5,5 @@
|
||||
|
||||
import cpp as C
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
private module Impl implements InlineExpectationsTestSig {
|
||||
private newtype TExpectationComment = MkExpectationComment(C::CppStyleComment c)
|
||||
|
||||
/**
|
||||
* A class representing a line comment in the CPP style.
|
||||
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
|
||||
* include the preceding comment marker (`//`).
|
||||
*/
|
||||
class ExpectationComment extends TExpectationComment {
|
||||
C::CppStyleComment comment;
|
||||
|
||||
ExpectationComment() { this = MkExpectationComment(comment) }
|
||||
|
||||
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
|
||||
string getContents() { result = comment.getContents().suffix(2) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = comment.toString() }
|
||||
|
||||
/** Gets the location of this comment. */
|
||||
Location getLocation() { result = comment.getLocation() }
|
||||
}
|
||||
|
||||
class Location = C::Location;
|
||||
}
|
||||
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import Make<Impl>
|
||||
|
||||
21
cpp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
cpp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import cpp as C
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
module Impl implements InlineExpectationsTestSig {
|
||||
private newtype TExpectationComment = MkExpectationComment(C::CppStyleComment c)
|
||||
|
||||
/**
|
||||
* A class representing a line comment in the CPP style.
|
||||
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
|
||||
* include the preceding comment marker (`//`).
|
||||
*/
|
||||
class ExpectationComment extends TExpectationComment {
|
||||
C::CppStyleComment comment;
|
||||
|
||||
ExpectationComment() { this = MkExpectationComment(comment) }
|
||||
|
||||
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
|
||||
string getContents() { result = comment.getContents().suffix(2) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = comment.toString() }
|
||||
|
||||
/** Gets the location of this comment. */
|
||||
Location getLocation() { result = comment.getLocation() }
|
||||
}
|
||||
|
||||
class Location = C::Location;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.implementation.raw.PrintIR
|
||||
@@ -0,0 +1,7 @@
|
||||
int foo(int i);
|
||||
|
||||
int foo(int i) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
int bar();
|
||||
@@ -0,0 +1,3 @@
|
||||
int foo(int i) {
|
||||
return i;
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
Critical/SizeCheck.ql
|
||||
query: Critical/SizeCheck.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -13,8 +13,8 @@ void free(void *ptr);
|
||||
|
||||
void bad0(void) {
|
||||
|
||||
float *fptr = malloc(3); // BAD -- Too small
|
||||
double *dptr = malloc(5); // BAD -- Too small
|
||||
float *fptr = malloc(3); // $ Alert -- Too small
|
||||
double *dptr = malloc(5); // $ Alert -- Too small
|
||||
free(fptr);
|
||||
free(dptr);
|
||||
}
|
||||
@@ -29,8 +29,8 @@ void good0(void) {
|
||||
|
||||
void bad1(void) {
|
||||
|
||||
float *fptr = malloc(sizeof(short)); // BAD -- Too small
|
||||
double *dptr = malloc(sizeof(float)); // BAD -- Too small
|
||||
float *fptr = malloc(sizeof(short)); // $ Alert -- Too small
|
||||
double *dptr = malloc(sizeof(float)); // $ Alert -- Too small
|
||||
free(fptr);
|
||||
free(dptr);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ typedef union _myUnion
|
||||
|
||||
void test_union() {
|
||||
MyUnion *a = malloc(sizeof(MyUnion)); // GOOD
|
||||
MyUnion *b = malloc(sizeof(MyStruct)); // BAD (too small)
|
||||
MyUnion *b = malloc(sizeof(MyStruct)); // $ Alert (too small)
|
||||
}
|
||||
|
||||
// --- custom allocators ---
|
||||
@@ -66,6 +66,6 @@ void *MyMalloc2(size_t size);
|
||||
|
||||
void customAllocatorTests()
|
||||
{
|
||||
float *fptr1 = MyMalloc1(3); // BAD (too small) [NOT DETECTED]
|
||||
float *fptr2 = MyMalloc2(3); // BAD (too small) [NOT DETECTED]
|
||||
float *fptr1 = MyMalloc1(3); // $ MISSING: BAD (too small)
|
||||
float *fptr2 = MyMalloc2(3); // $ MISSING: BAD (too small)
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Security/CWE/CWE-022/TaintedPath.ql
|
||||
query: Security/CWE/CWE-022/TaintedPath.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -5,7 +5,7 @@
|
||||
#define PATH_MAX 4096
|
||||
///// Test code /////
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int argc, char** argv) { // $ Source=argv
|
||||
char *userAndFile = argv[2];
|
||||
|
||||
{
|
||||
@@ -14,7 +14,7 @@ int main(int argc, char** argv) {
|
||||
size_t len = strlen(fileName);
|
||||
strncat(fileName+len, userAndFile, FILENAME_MAX-len-1);
|
||||
// BAD: a string from the user is used in a filename
|
||||
fopen(fileName, "wb+");
|
||||
fopen(fileName, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
@@ -29,30 +29,30 @@ int main(int argc, char** argv) {
|
||||
|
||||
{
|
||||
char *fileName = argv[1];
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
fopen(fileName, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
char fileName[20];
|
||||
scanf("%s", fileName);
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
scanf("%s", fileName); // $ Source=scanf_output1
|
||||
fopen(fileName, "wb+"); // $ Alert=scanf_output1
|
||||
}
|
||||
|
||||
{
|
||||
char *fileName = (char*)malloc(20 * sizeof(char));
|
||||
scanf("%s", fileName);
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
scanf("%s", fileName); // $ Source=scanf_output2
|
||||
fopen(fileName, "wb+"); // $ Alert=scanf_output2
|
||||
}
|
||||
|
||||
{
|
||||
char *tainted = getenv("A_STRING");
|
||||
fopen(tainted, "wb+"); // BAD
|
||||
char *tainted = getenv("A_STRING"); // $ Source=getenv1
|
||||
fopen(tainted, "wb+"); // $ Alert=getenv1
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[1024];
|
||||
strncpy(buffer, getenv("A_STRING"), 1024);
|
||||
fopen(buffer, "wb+"); // BAD
|
||||
strncpy(buffer, getenv("A_STRING"), 1024); // $ Source=getenv2
|
||||
fopen(buffer, "wb+"); // $ Alert=getenv2
|
||||
fopen(buffer, "wb+"); // (we don't want a duplicate result here)
|
||||
}
|
||||
|
||||
@@ -66,14 +66,14 @@ int main(int argc, char** argv) {
|
||||
|
||||
{
|
||||
void readFile(const char *fileName);
|
||||
readFile(argv[1]); // BAD
|
||||
readFile(argv[1]); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[1024];
|
||||
read(0, buffer, 1024);
|
||||
read(0, buffer, 1024);
|
||||
fopen(buffer, "wb+"); // BAD [duplicated with both sources]
|
||||
read(0, buffer, 1024); // $ Source=read_output1
|
||||
read(0, buffer, 1024); // $ Source=read_output2
|
||||
fopen(buffer, "wb+"); // $ SPURIOUS: Alert=read_output1 $ Alert=read_output2 [duplicated with both sources]
|
||||
}
|
||||
|
||||
{
|
||||
@@ -81,7 +81,7 @@ int main(int argc, char** argv) {
|
||||
char fileBuffer[PATH_MAX];
|
||||
snprintf(fileBuffer, sizeof(fileBuffer), "/home/%s", userAndFile);
|
||||
// BAD: a string from the user is used in a filename
|
||||
fopen(fileBuffer, "wb+");
|
||||
fopen(fileBuffer, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
@@ -95,7 +95,7 @@ int main(int argc, char** argv) {
|
||||
char fileBuffer[PATH_MAX];
|
||||
snprintf(fileBuffer, sizeof(fileBuffer), "/home/user/files/%s", fileName);
|
||||
// GOOD: We know that the filename is safe and stays within the public folder. But we currently get an FP here.
|
||||
FILE *file = fopen(fileBuffer, "wb+");
|
||||
FILE *file = fopen(fileBuffer, "wb+"); // $ SPURIOUS: Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Inline expectation tests for CSharp.
|
||||
* Inline expectation tests for C#.
|
||||
* See `shared/util/codeql/util/test/InlineExpectationsTest.qll`
|
||||
*/
|
||||
|
||||
|
||||
21
csharp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
csharp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import csharp
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,3 @@
|
||||
import semmle.code.csharp.dataflow.internal.ExternalFlow
|
||||
import codeql.dataflow.test.ProvenancePathGraph
|
||||
import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults<interpretModelForTest/2>
|
||||
|
||||
from string relation, int row, int column, string data
|
||||
where results(relation, row, column, data)
|
||||
select relation, row, column, data
|
||||
|
||||
82
csharp/ql/test/TestUtilities/inline-tests/InlineTests.cs
Normal file
82
csharp/ql/test/TestUtilities/inline-tests/InlineTests.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
class C
|
||||
{
|
||||
void Problems()
|
||||
{
|
||||
// correct expectation comment, but only for `problem-query`
|
||||
var x = "Alert"; // $ Alert
|
||||
|
||||
// irrelevant expectation comment, will be ignored
|
||||
x = "Not an alert"; // $ IrrelevantTag
|
||||
|
||||
// incorrect expectation comment
|
||||
x = "Also not an alert"; // $ Alert
|
||||
|
||||
// missing expectation comment, but only for `problem-query`
|
||||
x = "Alert";
|
||||
|
||||
// correct expectation comment
|
||||
x = "Alert"; // $ Alert[problem-query]
|
||||
}
|
||||
|
||||
void PathProblems()
|
||||
{
|
||||
// correct expectation comments, but only for `path-problem-query`
|
||||
var source = "Source"; // $ Source
|
||||
var sink = "Sink"; // $ Sink
|
||||
var x = "Alert:2:1"; // $ Alert
|
||||
|
||||
// incorrect expectation comments
|
||||
source = "Source"; // $ Source
|
||||
sink = "Sink"; // $ Sink
|
||||
x = "Not an alert:2:1"; // $ Alert
|
||||
|
||||
// missing expectation comments, but only for `path-problem-query`
|
||||
source = "Source";
|
||||
sink = "Sink";
|
||||
x = "Alert:2:1";
|
||||
|
||||
// correct expectation comments
|
||||
source = "Source"; // $ Source[path-problem-query]
|
||||
sink = "Sink"; // $ Sink[path-problem-query]
|
||||
x = "Alert:2:1"; // $ Alert[path-problem-query]
|
||||
|
||||
// correct expectation comments; the alert location coincides with the sink location
|
||||
source = "Source"; // $ Source[path-problem-query]
|
||||
x = "Alert:1:0"; // $ Alert[path-problem-query]
|
||||
|
||||
// correct expectation comments; the alert location coincides with the source location
|
||||
sink = "Sink"; // $ Sink[path-problem-query]
|
||||
x = "Alert:0:1"; // $ Alert[path-problem-query]
|
||||
|
||||
// correct expectation comments, using an identifier tag
|
||||
source = "Source"; // $ Source[path-problem-query]=source1
|
||||
sink = "Sink"; // $ Sink[path-problem-query]=source1
|
||||
x = "Alert:2:1"; // $ Alert[path-problem-query]=source1
|
||||
|
||||
// incorrect expectation comment, using wrong identifier tag at the sink
|
||||
source = "Source"; // $ Source[path-problem-query]=source2
|
||||
sink = "Sink"; // $ Sink[path-problem-query]=source1
|
||||
x = "Alert:2:1"; // $ Alert[path-problem-query]=source2
|
||||
|
||||
// incorrect expectation comment, using wrong identifier tag at the alert
|
||||
source = "Source"; // $ Source[path-problem-query]=source3
|
||||
sink = "Sink"; // $ Sink[path-problem-query]=source3
|
||||
x = "Alert:2:1"; // $ Alert[path-problem-query]=source2
|
||||
|
||||
// correct expectation comments, using an identifier tag; the alert location coincides with the sink location
|
||||
source = "Source"; // $ Source[path-problem-query]=source4
|
||||
x = "Alert:1:0"; // $ Alert[path-problem-query]=source4
|
||||
|
||||
// incorrect expectation comments, using an identifier tag; the alert location coincides with the sink location
|
||||
source = "Source"; // $ Source[path-problem-query]=source5
|
||||
x = "Alert:1:0"; // $ Alert[path-problem-query]=source4
|
||||
|
||||
// correct expectation comments, using an identifier tag; the alert location coincides with the source location
|
||||
sink = "Sink"; // $ Sink[path-problem-query]=sink1
|
||||
x = "Alert:0:1"; // $ Alert[path-problem-query]=sink1
|
||||
|
||||
// incorrect expectation comments, using an identifier tag; the alert location coincides with the source location
|
||||
sink = "Sink"; // $ Sink[path-problem-query]=sink2
|
||||
x = "Alert:0:1"; // $ Alert[path-problem-query]=sink1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#select
|
||||
| InlineTests.cs:26:17:26:27 | "Alert:2:1" | InlineTests.cs:24:22:24:29 | "Source" | InlineTests.cs:25:20:25:25 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:36:13:36:23 | "Alert:2:1" | InlineTests.cs:34:18:34:25 | "Source" | InlineTests.cs:35:16:35:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:41:13:41:23 | "Alert:2:1" | InlineTests.cs:39:18:39:25 | "Source" | InlineTests.cs:40:16:40:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:45:13:45:23 | "Alert:1:0" | InlineTests.cs:44:18:44:25 | "Source" | InlineTests.cs:45:13:45:23 | "Alert:1:0" | This is a problem |
|
||||
| InlineTests.cs:49:13:49:23 | "Alert:0:1" | InlineTests.cs:49:13:49:23 | "Alert:0:1" | InlineTests.cs:48:16:48:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:54:13:54:23 | "Alert:2:1" | InlineTests.cs:52:18:52:25 | "Source" | InlineTests.cs:53:16:53:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:59:13:59:23 | "Alert:2:1" | InlineTests.cs:57:18:57:25 | "Source" | InlineTests.cs:58:16:58:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:64:13:64:23 | "Alert:2:1" | InlineTests.cs:62:18:62:25 | "Source" | InlineTests.cs:63:16:63:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:68:13:68:23 | "Alert:1:0" | InlineTests.cs:67:18:67:25 | "Source" | InlineTests.cs:68:13:68:23 | "Alert:1:0" | This is a problem |
|
||||
| InlineTests.cs:72:13:72:23 | "Alert:1:0" | InlineTests.cs:71:18:71:25 | "Source" | InlineTests.cs:72:13:72:23 | "Alert:1:0" | This is a problem |
|
||||
| InlineTests.cs:76:13:76:23 | "Alert:0:1" | InlineTests.cs:76:13:76:23 | "Alert:0:1" | InlineTests.cs:75:16:75:21 | "Sink" | This is a problem |
|
||||
| InlineTests.cs:80:13:80:23 | "Alert:0:1" | InlineTests.cs:80:13:80:23 | "Alert:0:1" | InlineTests.cs:79:16:79:21 | "Sink" | This is a problem |
|
||||
edges
|
||||
testFailures
|
||||
| InlineTests.cs:6:26:6:35 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:29:28:29:38 | // ... | Missing result: Source |
|
||||
| InlineTests.cs:30:24:30:32 | // ... | Missing result: Sink |
|
||||
| InlineTests.cs:31:33:31:42 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:34:18:34:25 | "Source" | Unexpected result: Source |
|
||||
| InlineTests.cs:35:16:35:21 | "Sink" | Unexpected result: Sink |
|
||||
| InlineTests.cs:36:13:36:23 | InlineTests.cs:34:18:34:25 | Unexpected result: Alert |
|
||||
| InlineTests.cs:58:16:58:21 | "Sink" | Unexpected result: Sink=source2 |
|
||||
| InlineTests.cs:58:24:58:60 | // ... | Missing result: Sink[path-problem-query]=source1 |
|
||||
| InlineTests.cs:64:13:64:23 | InlineTests.cs:62:18:62:25 | Unexpected result: Alert=source3 |
|
||||
| InlineTests.cs:64:26:64:63 | // ... | Missing result: Alert[path-problem-query]=source2 |
|
||||
| InlineTests.cs:72:13:72:23 | "Alert:1:0" | Unexpected result: Alert=source5 |
|
||||
| InlineTests.cs:72:26:72:63 | // ... | Missing result: Alert[path-problem-query]=source4 |
|
||||
| InlineTests.cs:79:16:79:21 | "Sink" | Unexpected result: Sink=sink1 |
|
||||
| InlineTests.cs:79:24:79:58 | // ... | Missing result: Sink[path-problem-query]=sink2 |
|
||||
@@ -0,0 +1,2 @@
|
||||
query: TestUtilities/inline-tests/queries/PathProblemQuery.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1,9 @@
|
||||
#select
|
||||
| InlineTests.cs:6:17:6:23 | "Alert" | This is a problem |
|
||||
| InlineTests.cs:15:13:15:19 | "Alert" | This is a problem |
|
||||
| InlineTests.cs:18:13:18:19 | "Alert" | This is a problem |
|
||||
testFailures
|
||||
| InlineTests.cs:12:34:12:43 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:15:13:15:19 | This is a problem | Unexpected result: Alert |
|
||||
| InlineTests.cs:26:30:26:39 | // ... | Missing result: Alert |
|
||||
| InlineTests.cs:31:33:31:42 | // ... | Missing result: Alert |
|
||||
@@ -0,0 +1,2 @@
|
||||
query: TestUtilities/inline-tests/queries/ProblemQuery.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1,2 @@
|
||||
edges
|
||||
#select
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @kind path-problem
|
||||
* @id path-problem-query
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
query predicate edges(StringLiteral sl1, StringLiteral sl2) { none() }
|
||||
|
||||
from StringLiteral alert, StringLiteral source, StringLiteral sink
|
||||
where
|
||||
exists(string regexp, int sourceOffset, int sinkOffset | regexp = "Alert:([0-9]+):([0-9]+)" |
|
||||
sourceOffset = alert.getValue().regexpCapture(regexp, 1).toInt() and
|
||||
sinkOffset = alert.getValue().regexpCapture(regexp, 2).toInt() and
|
||||
source.getLocation().getStartLine() = alert.getLocation().getStartLine() - sourceOffset and
|
||||
sink.getLocation().getStartLine() = alert.getLocation().getStartLine() - sinkOffset
|
||||
)
|
||||
select alert, source, sink, "This is a problem"
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @kind problem
|
||||
* @id problem-query
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
from StringLiteral sl
|
||||
where sl.getValue() = "Alert"
|
||||
select sl, "This is a problem"
|
||||
@@ -30,7 +30,7 @@ using dotnetweb;
|
||||
#line 3 "Index.cshtml"
|
||||
|
||||
ViewData["Title"] = "ASP.NET Core";
|
||||
var message = Request.Query["m"];
|
||||
var message = Request.Query["m"]; // $ Source=message
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
@@ -38,7 +38,7 @@ using dotnetweb;
|
||||
WriteLiteral("<div class=\"cli\">\n <div class=\"cli-example\"> \n");
|
||||
#nullable restore
|
||||
#line 14 "Index.cshtml"
|
||||
Write(Html.Raw(message)); // BAD
|
||||
Write(Html.Raw(message)); // $ Alert=message
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
| Index.cshtml:14:16:14:22 | call to operator implicit conversion | Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | Index.cshtml:14:16:14:22 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method. | Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteral() method. | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | User-provided value |
|
||||
| XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | $@ flows to here and is written to HTML or JavaScript: System.Web.WebPages.WebPage.WriteLiteralTo() method. | XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | User-provided value |
|
||||
| XSSAspNet.cs:43:28:43:55 | access to indexer | XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:28:43:55 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion | XSSAspNetCore.cs:21:52:21:64 | access to property Query : IQueryCollection | XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:21:52:21:64 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:44:51:44:53 | access to parameter foo | XSSAspNetCore.cs:40:56:40:58 | foo : String | XSSAspNetCore.cs:44:51:44:53 | access to parameter foo | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:40:56:40:58 | foo : String | User-provided value |
|
||||
| XSSAspNetCore.cs:51:43:51:67 | access to property Value | XSSAspNetCore.cs:51:43:51:67 | access to property Value | XSSAspNetCore.cs:51:43:51:67 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:51:43:51:67 | access to property Value | User-provided value |
|
||||
| XSSAspNetCore.cs:58:43:58:73 | call to method ToString | XSSAspNetCore.cs:58:43:58:55 | access to property Query : IQueryCollection | XSSAspNetCore.cs:58:43:58:73 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:58:43:58:55 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:61:44:61:66 | access to indexer | XSSAspNetCore.cs:61:44:61:56 | access to property Query : IQueryCollection | XSSAspNetCore.cs:61:44:61:66 | access to indexer | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:61:44:61:56 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | User-provided value |
|
||||
| XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | User-provided value |
|
||||
| XSSAspNet.cs:44:28:44:33 | access to local variable sayHi2 | XSSAspNet.cs:43:26:43:44 | access to property QueryString : NameValueCollection | XSSAspNet.cs:44:28:44:33 | access to local variable sayHi2 | $@ flows to here and is written to HTML or JavaScript. | XSSAspNet.cs:43:26:43:44 | access to property QueryString : NameValueCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:22:52:22:57 | call to operator implicit conversion | XSSAspNetCore.cs:21:26:21:38 | access to property Query : IQueryCollection | XSSAspNetCore.cs:22:52:22:57 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:21:26:21:38 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:45:51:45:53 | access to parameter foo | XSSAspNetCore.cs:41:56:41:58 | foo : String | XSSAspNetCore.cs:45:51:45:53 | access to parameter foo | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:41:56:41:58 | foo : String | User-provided value |
|
||||
| XSSAspNetCore.cs:53:43:53:46 | access to local variable req2 | XSSAspNetCore.cs:52:24:52:48 | access to property Value : String | XSSAspNetCore.cs:53:43:53:46 | access to local variable req2 | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:52:24:52:48 | access to property Value : String | User-provided value |
|
||||
| XSSAspNetCore.cs:61:43:61:46 | access to local variable req3 | XSSAspNetCore.cs:60:24:60:36 | access to property Query : IQueryCollection | XSSAspNetCore.cs:61:43:61:46 | access to local variable req3 | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:60:24:60:36 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:65:44:65:47 | access to local variable req4 | XSSAspNetCore.cs:64:24:64:36 | access to property Query : IQueryCollection | XSSAspNetCore.cs:65:44:65:47 | access to local variable req4 | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:64:24:64:36 | access to property Query : IQueryCollection | User-provided value |
|
||||
| XSSAspNetCore.cs:74:43:74:44 | access to local variable ct | XSSAspNetCore.cs:73:22:73:40 | access to property ContentType : String | XSSAspNetCore.cs:74:43:74:44 | access to local variable ct | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:73:22:73:40 | access to property ContentType : String | User-provided value |
|
||||
| XSSAspNetCore.cs:78:51:78:56 | call to operator implicit conversion | XSSAspNetCore.cs:77:26:77:40 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:78:51:78:56 | call to operator implicit conversion | $@ flows to here and is written to HTML or JavaScript. | XSSAspNetCore.cs:77:26:77:40 | access to property Headers : IHeaderDictionary | User-provided value |
|
||||
edges
|
||||
| Index.cshtml:5:9:5:15 | access to local variable message : StringValues | Index.cshtml:14:16:14:22 | call to operator implicit conversion | provenance | |
|
||||
| Index.cshtml:5:19:5:31 | access to property Query : IQueryCollection | Index.cshtml:5:9:5:15 | access to local variable message : StringValues | provenance | |
|
||||
@@ -18,17 +18,29 @@ edges
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:19:17:19:21 | access to local variable sayHi : String | provenance | |
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:19:25:19:52 | access to indexer : String | provenance | MaD:3 |
|
||||
| XSSAspNet.cs:19:25:19:52 | access to indexer : String | XSSAspNet.cs:19:17:19:21 | access to local variable sayHi : String | provenance | |
|
||||
| XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:28:43:55 | access to indexer | provenance | |
|
||||
| XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:28:43:55 | access to indexer | provenance | MaD:3 |
|
||||
| XSSAspNetCore.cs:21:52:21:64 | access to property Query : IQueryCollection | XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion | provenance | |
|
||||
| XSSAspNetCore.cs:40:56:40:58 | foo : String | XSSAspNetCore.cs:44:51:44:53 | access to parameter foo | provenance | |
|
||||
| XSSAspNetCore.cs:58:43:58:55 | access to property Query : IQueryCollection | XSSAspNetCore.cs:58:43:58:62 | access to indexer : StringValues | provenance | |
|
||||
| XSSAspNetCore.cs:58:43:58:62 | access to indexer : StringValues | XSSAspNetCore.cs:58:43:58:73 | call to method ToString | provenance | MaD:1 |
|
||||
| XSSAspNetCore.cs:61:44:61:56 | access to property Query : IQueryCollection | XSSAspNetCore.cs:61:44:61:63 | access to indexer : StringValues | provenance | |
|
||||
| XSSAspNetCore.cs:61:44:61:56 | access to property Query : IQueryCollection | XSSAspNetCore.cs:61:44:61:66 | access to indexer | provenance | |
|
||||
| XSSAspNetCore.cs:61:44:61:63 | access to indexer : StringValues | XSSAspNetCore.cs:61:44:61:66 | access to indexer | provenance | |
|
||||
| XSSAspNetCore.cs:61:44:61:63 | access to indexer : StringValues | XSSAspNetCore.cs:61:44:61:66 | access to indexer | provenance | MaD:2 |
|
||||
| XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | provenance | |
|
||||
| XSSAspNet.cs:43:17:43:22 | access to local variable sayHi2 : String | XSSAspNet.cs:44:28:44:33 | access to local variable sayHi2 | provenance | |
|
||||
| XSSAspNet.cs:43:26:43:44 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:17:43:22 | access to local variable sayHi2 : String | provenance | |
|
||||
| XSSAspNet.cs:43:26:43:44 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:26:43:53 | access to indexer : String | provenance | MaD:3 |
|
||||
| XSSAspNet.cs:43:26:43:53 | access to indexer : String | XSSAspNet.cs:43:17:43:22 | access to local variable sayHi2 : String | provenance | |
|
||||
| XSSAspNetCore.cs:21:17:21:22 | access to local variable source : StringValues | XSSAspNetCore.cs:22:52:22:57 | call to operator implicit conversion | provenance | |
|
||||
| XSSAspNetCore.cs:21:26:21:38 | access to property Query : IQueryCollection | XSSAspNetCore.cs:21:17:21:22 | access to local variable source : StringValues | provenance | |
|
||||
| XSSAspNetCore.cs:41:56:41:58 | foo : String | XSSAspNetCore.cs:45:51:45:53 | access to parameter foo | provenance | |
|
||||
| XSSAspNetCore.cs:52:17:52:20 | access to local variable req2 : String | XSSAspNetCore.cs:53:43:53:46 | access to local variable req2 | provenance | |
|
||||
| XSSAspNetCore.cs:52:24:52:48 | access to property Value : String | XSSAspNetCore.cs:52:17:52:20 | access to local variable req2 : String | provenance | |
|
||||
| XSSAspNetCore.cs:60:17:60:20 | access to local variable req3 : String | XSSAspNetCore.cs:61:43:61:46 | access to local variable req3 | provenance | |
|
||||
| XSSAspNetCore.cs:60:24:60:36 | access to property Query : IQueryCollection | XSSAspNetCore.cs:60:24:60:43 | access to indexer : StringValues | provenance | |
|
||||
| XSSAspNetCore.cs:60:24:60:43 | access to indexer : StringValues | XSSAspNetCore.cs:60:24:60:54 | call to method ToString : String | provenance | MaD:1 |
|
||||
| XSSAspNetCore.cs:60:24:60:54 | call to method ToString : String | XSSAspNetCore.cs:60:17:60:20 | access to local variable req3 : String | provenance | |
|
||||
| XSSAspNetCore.cs:64:17:64:20 | access to local variable req4 : String | XSSAspNetCore.cs:65:44:65:47 | access to local variable req4 | provenance | |
|
||||
| XSSAspNetCore.cs:64:24:64:36 | access to property Query : IQueryCollection | XSSAspNetCore.cs:64:17:64:20 | access to local variable req4 : String | provenance | |
|
||||
| XSSAspNetCore.cs:64:24:64:36 | access to property Query : IQueryCollection | XSSAspNetCore.cs:64:24:64:43 | access to indexer : StringValues | provenance | |
|
||||
| XSSAspNetCore.cs:64:24:64:43 | access to indexer : StringValues | XSSAspNetCore.cs:64:17:64:20 | access to local variable req4 : String | provenance | |
|
||||
| XSSAspNetCore.cs:64:24:64:43 | access to indexer : StringValues | XSSAspNetCore.cs:64:24:64:46 | access to indexer : String | provenance | MaD:2 |
|
||||
| XSSAspNetCore.cs:64:24:64:46 | access to indexer : String | XSSAspNetCore.cs:64:17:64:20 | access to local variable req4 : String | provenance | |
|
||||
| XSSAspNetCore.cs:73:17:73:18 | access to local variable ct : String | XSSAspNetCore.cs:74:43:74:44 | access to local variable ct | provenance | |
|
||||
| XSSAspNetCore.cs:73:22:73:40 | access to property ContentType : String | XSSAspNetCore.cs:73:17:73:18 | access to local variable ct : String | provenance | |
|
||||
| XSSAspNetCore.cs:77:17:77:22 | access to local variable header : StringValues | XSSAspNetCore.cs:78:51:78:56 | call to operator implicit conversion | provenance | |
|
||||
| XSSAspNetCore.cs:77:26:77:40 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:77:17:77:22 | access to local variable header : StringValues | provenance | |
|
||||
models
|
||||
| 1 | Summary: Microsoft.Extensions.Primitives; StringValues; false; ToString; (); ; Argument[this]; ReturnValue; taint; manual |
|
||||
| 2 | Summary: Microsoft.Extensions.Primitives; StringValues; false; get_Item; (System.Int32); ; Argument[this]; ReturnValue; taint; manual |
|
||||
@@ -42,20 +54,32 @@ nodes
|
||||
| XSSAspNet.cs:19:25:19:52 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | semmle.label | access to local variable sayHi |
|
||||
| XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | semmle.label | access to local variable sayHi |
|
||||
| XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSSAspNet.cs:43:28:43:55 | access to indexer | semmle.label | access to indexer |
|
||||
| XSSAspNetCore.cs:21:52:21:64 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion | semmle.label | call to operator implicit conversion |
|
||||
| XSSAspNetCore.cs:40:56:40:58 | foo : String | semmle.label | foo : String |
|
||||
| XSSAspNetCore.cs:44:51:44:53 | access to parameter foo | semmle.label | access to parameter foo |
|
||||
| XSSAspNetCore.cs:51:43:51:67 | access to property Value | semmle.label | access to property Value |
|
||||
| XSSAspNetCore.cs:58:43:58:55 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:58:43:58:62 | access to indexer : StringValues | semmle.label | access to indexer : StringValues |
|
||||
| XSSAspNetCore.cs:58:43:58:73 | call to method ToString | semmle.label | call to method ToString |
|
||||
| XSSAspNetCore.cs:61:44:61:56 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:61:44:61:63 | access to indexer : StringValues | semmle.label | access to indexer : StringValues |
|
||||
| XSSAspNetCore.cs:61:44:61:66 | access to indexer | semmle.label | access to indexer |
|
||||
| XSSAspNetCore.cs:69:43:69:61 | access to property ContentType | semmle.label | access to property ContentType |
|
||||
| XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | semmle.label | access to property Headers : IHeaderDictionary |
|
||||
| XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion | semmle.label | call to operator implicit conversion |
|
||||
| XSSAspNet.cs:43:17:43:22 | access to local variable sayHi2 : String | semmle.label | access to local variable sayHi2 : String |
|
||||
| XSSAspNet.cs:43:26:43:44 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSSAspNet.cs:43:26:43:53 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSSAspNet.cs:44:28:44:33 | access to local variable sayHi2 | semmle.label | access to local variable sayHi2 |
|
||||
| XSSAspNetCore.cs:21:17:21:22 | access to local variable source : StringValues | semmle.label | access to local variable source : StringValues |
|
||||
| XSSAspNetCore.cs:21:26:21:38 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:22:52:22:57 | call to operator implicit conversion | semmle.label | call to operator implicit conversion |
|
||||
| XSSAspNetCore.cs:41:56:41:58 | foo : String | semmle.label | foo : String |
|
||||
| XSSAspNetCore.cs:45:51:45:53 | access to parameter foo | semmle.label | access to parameter foo |
|
||||
| XSSAspNetCore.cs:52:17:52:20 | access to local variable req2 : String | semmle.label | access to local variable req2 : String |
|
||||
| XSSAspNetCore.cs:52:24:52:48 | access to property Value : String | semmle.label | access to property Value : String |
|
||||
| XSSAspNetCore.cs:53:43:53:46 | access to local variable req2 | semmle.label | access to local variable req2 |
|
||||
| XSSAspNetCore.cs:60:17:60:20 | access to local variable req3 : String | semmle.label | access to local variable req3 : String |
|
||||
| XSSAspNetCore.cs:60:24:60:36 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:60:24:60:43 | access to indexer : StringValues | semmle.label | access to indexer : StringValues |
|
||||
| XSSAspNetCore.cs:60:24:60:54 | call to method ToString : String | semmle.label | call to method ToString : String |
|
||||
| XSSAspNetCore.cs:61:43:61:46 | access to local variable req3 | semmle.label | access to local variable req3 |
|
||||
| XSSAspNetCore.cs:64:17:64:20 | access to local variable req4 : String | semmle.label | access to local variable req4 : String |
|
||||
| XSSAspNetCore.cs:64:24:64:36 | access to property Query : IQueryCollection | semmle.label | access to property Query : IQueryCollection |
|
||||
| XSSAspNetCore.cs:64:24:64:43 | access to indexer : StringValues | semmle.label | access to indexer : StringValues |
|
||||
| XSSAspNetCore.cs:64:24:64:46 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSSAspNetCore.cs:65:44:65:47 | access to local variable req4 | semmle.label | access to local variable req4 |
|
||||
| XSSAspNetCore.cs:73:17:73:18 | access to local variable ct : String | semmle.label | access to local variable ct : String |
|
||||
| XSSAspNetCore.cs:73:22:73:40 | access to property ContentType : String | semmle.label | access to property ContentType : String |
|
||||
| XSSAspNetCore.cs:74:43:74:44 | access to local variable ct | semmle.label | access to local variable ct |
|
||||
| XSSAspNetCore.cs:77:17:77:22 | access to local variable header : StringValues | semmle.label | access to local variable header : StringValues |
|
||||
| XSSAspNetCore.cs:77:26:77:40 | access to property Headers : IHeaderDictionary | semmle.label | access to property Headers : IHeaderDictionary |
|
||||
| XSSAspNetCore.cs:78:51:78:56 | call to operator implicit conversion | semmle.label | call to operator implicit conversion |
|
||||
subpaths
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security Features/CWE-079/XSS.ql
|
||||
postprocess: TestUtilities/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- TestUtilities/PrettyPrintModels.ql
|
||||
- TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -16,14 +16,14 @@ namespace ASP
|
||||
{
|
||||
Layout = "~/_SiteLayout.cshtml";
|
||||
Page.Title = "Contact";
|
||||
var sayHi = Request.QueryString["sayHi"];
|
||||
var sayHi = Request.QueryString["sayHi"]; // $ Source=sayHi
|
||||
if (sayHi.IsEmpty())
|
||||
{
|
||||
WriteLiteral("<script>alert(\"XSS via WriteLiteral\")</script>"); // GOOD: hard-coded, not user input
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLiteral(sayHi); // BAD: user input flows to HTML unencoded
|
||||
WriteLiteral(sayHi); // $ Alert=sayHi
|
||||
WriteLiteral(HttpUtility.HtmlEncode(sayHi)); // Good: user input is encoded before it flows to HTML
|
||||
}
|
||||
|
||||
@@ -33,15 +33,16 @@ namespace ASP
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLiteralTo(Output, sayHi); // BAD: user input flows to HTML unencoded
|
||||
WriteLiteralTo(Output, sayHi); // $ Alert=sayHi
|
||||
WriteLiteralTo(Output, Html.Encode(sayHi)); // Good: user input is encoded before it flows to HTML
|
||||
}
|
||||
|
||||
BeginContext("~/Views/Home/Contact.cshtml", 288, 32, false);
|
||||
|
||||
Write(Html.Raw("<script>alert(\"XSS via Html.Raw()\")</script>")); // GOOD: hard-coded, not user input
|
||||
Write(Html.Raw(Request.QueryString["sayHi"])); // BAD: user input flows to HTML unencoded
|
||||
Write(Html.Raw(HttpContext.Current.Server.HtmlEncode(Request.QueryString["sayHi"]))); // Good: user input is encoded before it flows to HTML
|
||||
var sayHi2 = Request.QueryString["sayHi"]; // $ Source=sayHi2
|
||||
Write(Html.Raw(sayHi2)); // $ Alert=sayHi2
|
||||
Write(Html.Raw(HttpContext.Current.Server.HtmlEncode(sayHi2))); // Good: user input is encoded before it flows to HTML
|
||||
EndContext("~/Views/Home/Contact.cshtml", 288, 32, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace Testing.Controllers
|
||||
{
|
||||
// BAD: flow of content type to.
|
||||
var v = new ViewResult();
|
||||
v.ViewData["BadData"] = new HtmlString(Request.Query["Bad data"]);
|
||||
var source = Request.Query["Bad data"]; // $ Source=req1
|
||||
v.ViewData["BadData"] = new HtmlString(source); // $ Alert=req1
|
||||
|
||||
StringValues vOut;
|
||||
Request.Query.TryGetValue("Foo", out vOut);
|
||||
@@ -37,28 +38,31 @@ namespace Testing.Controllers
|
||||
|
||||
[HttpPost("Test")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Submit([FromQuery] string foo)
|
||||
public IActionResult Submit([FromQuery] string foo) // $ Source=foo
|
||||
{
|
||||
var view = new ViewResult();
|
||||
//BAD: flow of submitted value to view in HtmlString.
|
||||
view.ViewData["FOO"] = new HtmlString(foo);
|
||||
view.ViewData["FOO"] = new HtmlString(foo); // $ Alert=foo
|
||||
return view;
|
||||
}
|
||||
|
||||
public IActionResult IndexToModel()
|
||||
{
|
||||
//BAD: flow of submitted value to view in HtmlString.
|
||||
HtmlString v = new HtmlString(Request.QueryString.Value);
|
||||
var req2 = Request.QueryString.Value; // $ Source=req2
|
||||
HtmlString v = new HtmlString(req2); // $ Alert=req2
|
||||
return View(new HomeViewModel() { Message = "Message from Index", Description = v });
|
||||
}
|
||||
|
||||
public IActionResult About()
|
||||
{
|
||||
//BAD: flow of submitted value to view in HtmlString.
|
||||
HtmlString v = new HtmlString(Request.Query["Foo"].ToString());
|
||||
var req3 = Request.Query["Foo"].ToString(); // $ Source=req3
|
||||
HtmlString v = new HtmlString(req3); // $ Alert=req3
|
||||
|
||||
//BAD: flow of submitted value to view in HtmlString.
|
||||
HtmlString v1 = new HtmlString(Request.Query["Foo"][0]);
|
||||
var req4 = Request.Query["Foo"][0]; // $ Source=req4
|
||||
HtmlString v1 = new HtmlString(req4); // $ Alert=req4
|
||||
|
||||
return View(new HomeViewModel() { Message = "Message from About", Description = v });
|
||||
}
|
||||
@@ -66,10 +70,12 @@ namespace Testing.Controllers
|
||||
public IActionResult Contact()
|
||||
{
|
||||
//BAD: flow of user content type to view in HtmlString.
|
||||
HtmlString v = new HtmlString(Request.ContentType);
|
||||
var ct = Request.ContentType; // $ Source=ct
|
||||
HtmlString v = new HtmlString(ct); // $ Alert=ct
|
||||
|
||||
//BAD: flow of headers to view in HtmlString.
|
||||
HtmlString v1 = new HtmlString(value: Request.Headers["Foo"]);
|
||||
var header = Request.Headers["Foo"]; // $ Source=header
|
||||
HtmlString v1 = new HtmlString(value: header); // $ Alert=header
|
||||
|
||||
return View(new HomeViewModel() { Message = "Message from Contact", Description = v });
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ class UnusedLabelTest
|
||||
void F1()
|
||||
{
|
||||
goto a;
|
||||
a: // GOOD
|
||||
a: // GOOD
|
||||
;
|
||||
}
|
||||
|
||||
void F2()
|
||||
{
|
||||
a: // BAD
|
||||
a: // $ Alert
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
| UnusedLabel.cs:12:9:12:9 | a: | This label is not used. |
|
||||
| UnusedLabel.cs:12:5:12:5 | a: | This label is not used. |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Useless code/UnusedLabel.ql
|
||||
query: Useless code/UnusedLabel.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
21
go/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
go/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import go
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,3 @@
|
||||
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults<interpretModelForTest/2>
|
||||
|
||||
from string relation, int row, int column, string data
|
||||
where results(relation, row, column, data)
|
||||
select relation, row, column, data
|
||||
|
||||
@@ -21,12 +21,12 @@ type Person struct {
|
||||
func FileSystemAccess() {
|
||||
router := gin.Default()
|
||||
router.POST("/FormUploads", func(c *gin.Context) {
|
||||
filepath := c.Query("filepath")
|
||||
c.File(filepath) // $ FileSystemAccess=filepath
|
||||
http.ServeFile(c.Writer, c.Request, filepath) // $ FileSystemAccess=filepath
|
||||
c.FileAttachment(filepath, "file name in response") // $ FileSystemAccess=filepath
|
||||
filepath := c.Query("filepath") // $ Source=filepath
|
||||
c.File(filepath) // $ Alert=filepath $ FileSystemAccess=filepath
|
||||
http.ServeFile(c.Writer, c.Request, filepath) // $ Alert=filepath $ FileSystemAccess=filepath
|
||||
c.FileAttachment(filepath, "file name in response") // $ Alert=filepath $ FileSystemAccess=filepath
|
||||
file, _ := c.FormFile("afile")
|
||||
_ = c.SaveUploadedFile(file, filepath) // $ FileSystemAccess=filepath
|
||||
_ = c.SaveUploadedFile(file, filepath) // $ Alert=filepath $ FileSystemAccess=filepath
|
||||
})
|
||||
_ = router.Run()
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
query: Security/CWE-022/TaintedPath.ql
|
||||
postprocess: TestUtilities/PrettyPrintModels.ql
|
||||
postprocess:
|
||||
- TestUtilities/PrettyPrintModels.ql
|
||||
- TestUtilities/InlineExpectationsTestQuery.ql
|
||||
|
||||
21
java/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
java/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import java
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,3 @@
|
||||
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults<interpretModelForTest/2>
|
||||
|
||||
from string relation, int row, int column, string data
|
||||
where results(relation, row, column, data)
|
||||
select relation, row, column, data
|
||||
|
||||
@@ -1,2 +1,283 @@
|
||||
failures
|
||||
testFailures
|
||||
#select
|
||||
| AndroidIntentRedirectionTest.java:15:25:15:45 | new Intent[] | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:15:25:15:45 | new Intent[] | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:16:25:16:45 | new Intent[] | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:16:25:16:45 | new Intent[] | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:17:23:17:28 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:17:23:17:28 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:18:23:18:28 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:18:23:18:28 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:19:29:19:34 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:19:29:19:34 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:20:31:20:36 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:20:31:20:36 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:21:32:21:37 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:21:32:21:37 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:22:32:22:37 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:22:32:22:37 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:23:38:23:43 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:23:38:23:43 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:24:38:24:43 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:24:38:24:43 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:25:38:25:43 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:25:38:25:43 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:26:38:26:43 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:26:38:26:43 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:29:22:29:27 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:29:22:29:27 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:30:28:30:33 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:30:28:30:33 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:31:32:31:37 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:31:32:31:37 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:32:23:32:28 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:32:23:32:28 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:33:23:33:28 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:33:23:33:28 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:34:29:34:34 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:34:29:34:34 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:35:29:35:34 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:35:29:35:34 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:36:46:36:51 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:36:46:36:51 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:37:29:37:34 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:37:29:37:34 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:38:35:38:40 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:38:35:38:40 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:39:36:39:41 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:39:36:39:41 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:40:42:40:47 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:40:42:40:47 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:47:27:47:32 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:47:27:47:32 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:49:27:49:32 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:49:27:49:32 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:52:27:52:32 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:52:27:52:32 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:54:27:54:32 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:54:27:54:32 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:61:27:61:32 | intent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:61:27:61:32 | intent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:69:31:69:39 | fwdIntent | AndroidIntentRedirectionTest.java:67:30:67:40 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:69:31:69:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:67:30:67:40 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:74:31:74:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:74:31:74:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:79:31:79:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:79:31:79:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:85:31:85:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:85:31:85:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:96:31:96:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:96:31:96:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:103:31:103:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:103:31:103:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:109:31:109:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:109:31:109:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:116:31:116:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:116:31:116:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:131:31:131:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:131:31:131:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:138:31:138:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:138:31:138:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:145:31:145:39 | fwdIntent | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:145:31:145:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:164:35:164:43 | fwdIntent | AndroidIntentRedirectionTest.java:161:41:161:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:164:35:164:43 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:161:41:161:51 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:173:31:173:44 | originalIntent | AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:173:31:173:44 | originalIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:193:31:193:39 | fwdIntent | AndroidIntentRedirectionTest.java:192:52:192:62 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:193:31:193:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:192:52:192:62 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:197:31:197:39 | fwdIntent | AndroidIntentRedirectionTest.java:196:53:196:63 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:197:31:197:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:196:53:196:63 | getIntent(...) | user-provided value |
|
||||
| AndroidIntentRedirectionTest.java:201:31:201:39 | fwdIntent | AndroidIntentRedirectionTest.java:200:56:200:66 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:201:31:201:39 | fwdIntent | Arbitrary Android activities or services can be started from a $@. | AndroidIntentRedirectionTest.java:200:56:200:66 | getIntent(...) | user-provided value |
|
||||
edges
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:15:39:15:44 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:16:39:16:44 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:17:23:17:28 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:18:23:18:28 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:19:29:19:34 | intent | provenance | Sink:MaD:228 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:20:31:20:36 | intent | provenance | Sink:MaD:3 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:21:32:21:37 | intent | provenance | Sink:MaD:4 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:22:32:22:37 | intent | provenance | Sink:MaD:5 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:23:38:23:43 | intent | provenance | Sink:MaD:6 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:24:38:24:43 | intent | provenance | Sink:MaD:7 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:25:38:25:43 | intent | provenance | Sink:MaD:7 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:26:38:26:43 | intent | provenance | Sink:MaD:7 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:29:22:29:27 | intent | provenance | Sink:MaD:233 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:30:28:30:33 | intent | provenance | Sink:MaD:234 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:31:32:31:37 | intent | provenance | Sink:MaD:232 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:32:23:32:28 | intent | provenance | Sink:MaD:219 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:33:23:33:28 | intent | provenance | Sink:MaD:219 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:34:29:34:34 | intent | provenance | Sink:MaD:220 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:35:29:35:34 | intent | provenance | Sink:MaD:220 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:36:46:36:51 | intent | provenance | Sink:MaD:221 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:37:29:37:34 | intent | provenance | Sink:MaD:222 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:38:35:38:40 | intent | provenance | Sink:MaD:223 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:39:36:39:41 | intent | provenance | Sink:MaD:224 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:40:42:40:47 | intent | provenance | Sink:MaD:225 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:47:27:47:32 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:49:27:49:32 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:52:27:52:32 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:54:27:54:32 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:61:27:61:32 | intent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:73:56:73:61 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:78:40:78:45 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:83:40:83:45 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:84:25:84:30 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:95:38:95:43 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:101:43:101:48 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:107:65:107:70 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:114:59:114:64 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:129:58:129:63 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:136:54:136:59 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | AndroidIntentRedirectionTest.java:143:25:143:30 | intent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:12:34:12:81 | getParcelableExtra(...) : Parcelable | provenance | MaD:326 |
|
||||
| AndroidIntentRedirectionTest.java:12:34:12:81 | getParcelableExtra(...) : Parcelable | AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:15:25:15:45 | {...} : Intent[] [[]] : Intent | AndroidIntentRedirectionTest.java:15:25:15:45 | new Intent[] | provenance | Sink:MaD:226 |
|
||||
| AndroidIntentRedirectionTest.java:15:39:15:44 | intent : Intent | AndroidIntentRedirectionTest.java:15:25:15:45 | {...} : Intent[] [[]] : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:16:25:16:45 | {...} : Intent[] [[]] : Intent | AndroidIntentRedirectionTest.java:16:25:16:45 | new Intent[] | provenance | Sink:MaD:226 |
|
||||
| AndroidIntentRedirectionTest.java:16:39:16:44 | intent : Intent | AndroidIntentRedirectionTest.java:16:25:16:45 | {...} : Intent[] [[]] : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:67:30:67:40 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:67:30:67:77 | getParcelableExtra(...) : Parcelable | provenance | MaD:326 |
|
||||
| AndroidIntentRedirectionTest.java:67:30:67:77 | getParcelableExtra(...) : Parcelable | AndroidIntentRedirectionTest.java:68:36:68:47 | (...)... : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:68:36:68:47 | (...)... : Intent | AndroidIntentRedirectionTest.java:69:31:69:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:73:17:73:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:74:31:74:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:73:56:73:61 | intent : Intent | AndroidIntentRedirectionTest.java:73:56:73:89 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:73:56:73:89 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:73:17:73:25 | fwdIntent [post update] : Intent | provenance | MaD:363 |
|
||||
| AndroidIntentRedirectionTest.java:78:17:78:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:79:31:79:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:78:40:78:45 | intent : Intent | AndroidIntentRedirectionTest.java:78:40:78:75 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:78:40:78:75 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:78:17:78:25 | fwdIntent [post update] : Intent | provenance | MaD:364 |
|
||||
| AndroidIntentRedirectionTest.java:83:17:83:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:85:31:85:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:83:40:83:45 | intent : Intent | AndroidIntentRedirectionTest.java:83:40:83:75 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:83:40:83:75 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:83:17:83:25 | fwdIntent [post update] : Intent | provenance | MaD:364 |
|
||||
| AndroidIntentRedirectionTest.java:84:25:84:30 | intent : Intent | AndroidIntentRedirectionTest.java:84:25:84:58 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:84:25:84:58 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:83:17:83:25 | fwdIntent [post update] : Intent | provenance | MaD:364 |
|
||||
| AndroidIntentRedirectionTest.java:95:17:95:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:96:31:96:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:95:38:95:43 | intent : Intent | AndroidIntentRedirectionTest.java:95:38:95:73 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:95:38:95:73 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:95:17:95:25 | fwdIntent [post update] : Intent | provenance | MaD:378 |
|
||||
| AndroidIntentRedirectionTest.java:101:25:101:85 | new ComponentName(...) : ComponentName | AndroidIntentRedirectionTest.java:102:40:102:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:101:43:101:48 | intent : Intent | AndroidIntentRedirectionTest.java:101:43:101:78 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:101:43:101:78 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:101:25:101:85 | new ComponentName(...) : ComponentName | provenance | MaD:238 |
|
||||
| AndroidIntentRedirectionTest.java:102:17:102:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:103:31:103:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:102:40:102:48 | component : ComponentName | AndroidIntentRedirectionTest.java:102:17:102:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:107:43:107:99 | new ComponentName(...) : ComponentName | AndroidIntentRedirectionTest.java:108:40:108:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:107:65:107:70 | intent : Intent | AndroidIntentRedirectionTest.java:107:65:107:98 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:107:65:107:98 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:107:43:107:99 | new ComponentName(...) : ComponentName | provenance | MaD:238 |
|
||||
| AndroidIntentRedirectionTest.java:108:17:108:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:109:31:109:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:108:40:108:48 | component : ComponentName | AndroidIntentRedirectionTest.java:108:17:108:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:114:25:114:93 | new ComponentName(...) : ComponentName | AndroidIntentRedirectionTest.java:115:40:115:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:114:59:114:64 | intent : Intent | AndroidIntentRedirectionTest.java:114:59:114:92 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:114:59:114:92 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:114:25:114:93 | new ComponentName(...) : ComponentName | provenance | MaD:236 |
|
||||
| AndroidIntentRedirectionTest.java:115:17:115:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:116:31:116:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:115:40:115:48 | component : ComponentName | AndroidIntentRedirectionTest.java:115:17:115:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:129:25:129:92 | createRelative(...) : ComponentName | AndroidIntentRedirectionTest.java:130:40:130:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:129:58:129:63 | intent : Intent | AndroidIntentRedirectionTest.java:129:58:129:91 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:129:58:129:91 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:129:25:129:92 | createRelative(...) : ComponentName | provenance | MaD:240 |
|
||||
| AndroidIntentRedirectionTest.java:130:17:130:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:131:31:131:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:130:40:130:48 | component : ComponentName | AndroidIntentRedirectionTest.java:130:17:130:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:136:25:136:94 | createRelative(...) : ComponentName | AndroidIntentRedirectionTest.java:137:40:137:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:136:54:136:59 | intent : Intent | AndroidIntentRedirectionTest.java:136:54:136:89 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:136:54:136:89 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:136:25:136:94 | createRelative(...) : ComponentName | provenance | MaD:240 |
|
||||
| AndroidIntentRedirectionTest.java:137:17:137:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:138:31:138:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:137:40:137:48 | component : ComponentName | AndroidIntentRedirectionTest.java:137:17:137:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:142:43:143:59 | createRelative(...) : ComponentName | AndroidIntentRedirectionTest.java:144:40:144:48 | component : ComponentName | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:143:25:143:30 | intent : Intent | AndroidIntentRedirectionTest.java:143:25:143:58 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:143:25:143:58 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:142:43:143:59 | createRelative(...) : ComponentName | provenance | MaD:239 |
|
||||
| AndroidIntentRedirectionTest.java:144:17:144:25 | fwdIntent [post update] : Intent | AndroidIntentRedirectionTest.java:145:31:145:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:144:40:144:48 | component : ComponentName | AndroidIntentRedirectionTest.java:144:17:144:25 | fwdIntent [post update] : Intent | provenance | MaD:366 |
|
||||
| AndroidIntentRedirectionTest.java:161:41:161:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:162:45:162:58 | originalIntent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:162:36:162:95 | (...)... : Intent | AndroidIntentRedirectionTest.java:164:35:164:43 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:162:45:162:58 | originalIntent : Intent | AndroidIntentRedirectionTest.java:162:45:162:95 | getParcelableExtra(...) : Parcelable | provenance | MaD:326 |
|
||||
| AndroidIntentRedirectionTest.java:162:45:162:95 | getParcelableExtra(...) : Parcelable | AndroidIntentRedirectionTest.java:162:36:162:95 | (...)... : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:171:45:171:58 | originalIntent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:172:25:172:38 | originalIntent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:173:31:173:44 | originalIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | AndroidIntentRedirectionTest.java:171:45:171:58 | originalIntent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | AndroidIntentRedirectionTest.java:172:25:172:38 | originalIntent : Intent | provenance | |
|
||||
| AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | AndroidIntentRedirectionTest.java:173:31:173:44 | originalIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:171:45:171:58 | originalIntent : Intent | AndroidIntentRedirectionTest.java:171:45:171:89 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:171:45:171:89 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | provenance | MaD:364 |
|
||||
| AndroidIntentRedirectionTest.java:172:25:172:38 | originalIntent : Intent | AndroidIntentRedirectionTest.java:172:25:172:67 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:172:25:172:67 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | provenance | MaD:364 |
|
||||
| AndroidIntentRedirectionTest.java:192:36:192:88 | parseUri(...) : Intent | AndroidIntentRedirectionTest.java:193:31:193:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:192:52:192:62 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:192:52:192:84 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:192:52:192:84 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:192:36:192:88 | parseUri(...) : Intent | provenance | MaD:332 |
|
||||
| AndroidIntentRedirectionTest.java:196:36:196:86 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:197:31:197:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:196:53:196:63 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:196:53:196:85 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:196:53:196:85 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:196:36:196:86 | getIntent(...) : Intent | provenance | MaD:321 |
|
||||
| AndroidIntentRedirectionTest.java:200:36:200:89 | getIntentOld(...) : Intent | AndroidIntentRedirectionTest.java:201:31:201:39 | fwdIntent | provenance | Sink:MaD:227 |
|
||||
| AndroidIntentRedirectionTest.java:200:56:200:66 | getIntent(...) : Intent | AndroidIntentRedirectionTest.java:200:56:200:88 | getStringExtra(...) : String | provenance | MaD:330 |
|
||||
| AndroidIntentRedirectionTest.java:200:56:200:88 | getStringExtra(...) : String | AndroidIntentRedirectionTest.java:200:36:200:89 | getIntentOld(...) : Intent | provenance | MaD:323 |
|
||||
nodes
|
||||
| AndroidIntentRedirectionTest.java:12:25:12:81 | (...)... : Intent | semmle.label | (...)... : Intent |
|
||||
| AndroidIntentRedirectionTest.java:12:34:12:44 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:12:34:12:81 | getParcelableExtra(...) : Parcelable | semmle.label | getParcelableExtra(...) : Parcelable |
|
||||
| AndroidIntentRedirectionTest.java:15:25:15:45 | new Intent[] | semmle.label | new Intent[] |
|
||||
| AndroidIntentRedirectionTest.java:15:25:15:45 | {...} : Intent[] [[]] : Intent | semmle.label | {...} : Intent[] [[]] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:15:39:15:44 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:16:25:16:45 | new Intent[] | semmle.label | new Intent[] |
|
||||
| AndroidIntentRedirectionTest.java:16:25:16:45 | {...} : Intent[] [[]] : Intent | semmle.label | {...} : Intent[] [[]] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:16:39:16:44 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:17:23:17:28 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:18:23:18:28 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:19:29:19:34 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:20:31:20:36 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:21:32:21:37 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:22:32:22:37 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:23:38:23:43 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:24:38:24:43 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:25:38:25:43 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:26:38:26:43 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:29:22:29:27 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:30:28:30:33 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:31:32:31:37 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:32:23:32:28 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:33:23:33:28 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:34:29:34:34 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:35:29:35:34 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:36:46:36:51 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:37:29:37:34 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:38:35:38:40 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:39:36:39:41 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:40:42:40:47 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:47:27:47:32 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:49:27:49:32 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:52:27:52:32 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:54:27:54:32 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:61:27:61:32 | intent | semmle.label | intent |
|
||||
| AndroidIntentRedirectionTest.java:67:30:67:40 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:67:30:67:77 | getParcelableExtra(...) : Parcelable | semmle.label | getParcelableExtra(...) : Parcelable |
|
||||
| AndroidIntentRedirectionTest.java:68:36:68:47 | (...)... : Intent | semmle.label | (...)... : Intent |
|
||||
| AndroidIntentRedirectionTest.java:69:31:69:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:73:17:73:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:73:56:73:61 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:73:56:73:89 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:74:31:74:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:78:17:78:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:78:40:78:45 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:78:40:78:75 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:79:31:79:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:83:17:83:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:83:40:83:45 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:83:40:83:75 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:84:25:84:30 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:84:25:84:58 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:85:31:85:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:95:17:95:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:95:38:95:43 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:95:38:95:73 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:96:31:96:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:101:25:101:85 | new ComponentName(...) : ComponentName | semmle.label | new ComponentName(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:101:43:101:48 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:101:43:101:78 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:102:17:102:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:102:40:102:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:103:31:103:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:107:43:107:99 | new ComponentName(...) : ComponentName | semmle.label | new ComponentName(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:107:65:107:70 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:107:65:107:98 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:108:17:108:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:108:40:108:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:109:31:109:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:114:25:114:93 | new ComponentName(...) : ComponentName | semmle.label | new ComponentName(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:114:59:114:64 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:114:59:114:92 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:115:17:115:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:115:40:115:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:116:31:116:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:129:25:129:92 | createRelative(...) : ComponentName | semmle.label | createRelative(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:129:58:129:63 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:129:58:129:91 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:130:17:130:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:130:40:130:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:131:31:131:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:136:25:136:94 | createRelative(...) : ComponentName | semmle.label | createRelative(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:136:54:136:59 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:136:54:136:89 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:137:17:137:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:137:40:137:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:138:31:138:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:142:43:143:59 | createRelative(...) : ComponentName | semmle.label | createRelative(...) : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:143:25:143:30 | intent : Intent | semmle.label | intent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:143:25:143:58 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:144:17:144:25 | fwdIntent [post update] : Intent | semmle.label | fwdIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:144:40:144:48 | component : ComponentName | semmle.label | component : ComponentName |
|
||||
| AndroidIntentRedirectionTest.java:145:31:145:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:161:41:161:51 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:162:36:162:95 | (...)... : Intent | semmle.label | (...)... : Intent |
|
||||
| AndroidIntentRedirectionTest.java:162:45:162:58 | originalIntent : Intent | semmle.label | originalIntent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:162:45:162:95 | getParcelableExtra(...) : Parcelable | semmle.label | getParcelableExtra(...) : Parcelable |
|
||||
| AndroidIntentRedirectionTest.java:164:35:164:43 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:170:41:170:51 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:171:17:171:30 | originalIntent [post update] : Intent | semmle.label | originalIntent [post update] : Intent |
|
||||
| AndroidIntentRedirectionTest.java:171:45:171:58 | originalIntent : Intent | semmle.label | originalIntent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:171:45:171:89 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:172:25:172:38 | originalIntent : Intent | semmle.label | originalIntent : Intent |
|
||||
| AndroidIntentRedirectionTest.java:172:25:172:67 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:173:31:173:44 | originalIntent | semmle.label | originalIntent |
|
||||
| AndroidIntentRedirectionTest.java:192:36:192:88 | parseUri(...) : Intent | semmle.label | parseUri(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:192:52:192:62 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:192:52:192:84 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:193:31:193:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:196:36:196:86 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:196:53:196:63 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:196:53:196:85 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:197:31:197:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
| AndroidIntentRedirectionTest.java:200:36:200:89 | getIntentOld(...) : Intent | semmle.label | getIntentOld(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:200:56:200:66 | getIntent(...) : Intent | semmle.label | getIntent(...) : Intent |
|
||||
| AndroidIntentRedirectionTest.java:200:56:200:88 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String |
|
||||
| AndroidIntentRedirectionTest.java:201:31:201:39 | fwdIntent | semmle.label | fwdIntent |
|
||||
subpaths
|
||||
|
||||
@@ -9,80 +9,80 @@ import android.os.Bundle;
|
||||
public class AndroidIntentRedirectionTest extends Activity {
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Intent intent = (Intent) getIntent().getParcelableExtra("forward_intent");
|
||||
Intent intent = (Intent) getIntent().getParcelableExtra("forward_intent"); // $ Source=intent
|
||||
|
||||
// @formatter:off
|
||||
startActivities(new Intent[] {intent}); // $ hasAndroidIntentRedirection
|
||||
startActivities(new Intent[] {intent}, null); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent, null); // $ hasAndroidIntentRedirection
|
||||
startActivityAsUser(intent, null); // $ hasAndroidIntentRedirection
|
||||
startActivityAsCaller(intent, null, false, 0); // $ hasAndroidIntentRedirection
|
||||
startActivityForResult(intent, 0); // $ hasAndroidIntentRedirection
|
||||
startActivityForResult(intent, 0, null); // $ hasAndroidIntentRedirection
|
||||
startActivityForResult(null, intent, 0, null); // $ hasAndroidIntentRedirection
|
||||
startActivityForResultAsUser(intent, null, 0, null, null); // $ hasAndroidIntentRedirection
|
||||
startActivityForResultAsUser(intent, 0, null, null); // $ hasAndroidIntentRedirection
|
||||
startActivityForResultAsUser(intent, 0, null); // $ hasAndroidIntentRedirection
|
||||
startActivities(new Intent[] {intent}); // $ Alert=intent
|
||||
startActivities(new Intent[] {intent}, null); // $ Alert=intent
|
||||
startActivity(intent); // $ Alert=intent
|
||||
startActivity(intent, null); // $ Alert=intent
|
||||
startActivityAsUser(intent, null); // $ Alert=intent
|
||||
startActivityAsCaller(intent, null, false, 0); // $ Alert=intent
|
||||
startActivityForResult(intent, 0); // $ Alert=intent
|
||||
startActivityForResult(intent, 0, null); // $ Alert=intent
|
||||
startActivityForResult(null, intent, 0, null); // $ Alert=intent
|
||||
startActivityForResultAsUser(intent, null, 0, null, null); // $ Alert=intent
|
||||
startActivityForResultAsUser(intent, 0, null, null); // $ Alert=intent
|
||||
startActivityForResultAsUser(intent, 0, null); // $ Alert=intent
|
||||
bindService(intent, null, 0);
|
||||
bindServiceAsUser(intent, null, 0, null);
|
||||
startService(intent); // $ hasAndroidIntentRedirection
|
||||
startServiceAsUser(intent, null); // $ hasAndroidIntentRedirection
|
||||
startForegroundService(intent); // $ hasAndroidIntentRedirection
|
||||
sendBroadcast(intent); // $ hasAndroidIntentRedirection
|
||||
sendBroadcast(intent, null); // $ hasAndroidIntentRedirection
|
||||
sendBroadcastAsUser(intent, null); // $ hasAndroidIntentRedirection
|
||||
sendBroadcastAsUser(intent, null, null); // $ hasAndroidIntentRedirection
|
||||
sendBroadcastWithMultiplePermissions(intent, null); // $ hasAndroidIntentRedirection
|
||||
sendStickyBroadcast(intent); // $ hasAndroidIntentRedirection
|
||||
sendStickyBroadcastAsUser(intent, null); // $ hasAndroidIntentRedirection
|
||||
sendStickyOrderedBroadcast(intent, null, null, 0, null, null); // $ hasAndroidIntentRedirection
|
||||
sendStickyOrderedBroadcastAsUser(intent, null, null, null, 0, null, null); // $ hasAndroidIntentRedirection
|
||||
startService(intent); // $ Alert=intent
|
||||
startServiceAsUser(intent, null); // $ Alert=intent
|
||||
startForegroundService(intent); // $ Alert=intent
|
||||
sendBroadcast(intent); // $ Alert=intent
|
||||
sendBroadcast(intent, null); // $ Alert=intent
|
||||
sendBroadcastAsUser(intent, null); // $ Alert=intent
|
||||
sendBroadcastAsUser(intent, null, null); // $ Alert=intent
|
||||
sendBroadcastWithMultiplePermissions(intent, null); // $ Alert=intent
|
||||
sendStickyBroadcast(intent); // $ Alert=intent
|
||||
sendStickyBroadcastAsUser(intent, null); // $ Alert=intent
|
||||
sendStickyOrderedBroadcast(intent, null, null, 0, null, null); // $ Alert=intent
|
||||
sendStickyOrderedBroadcastAsUser(intent, null, null, null, 0, null, null); // $ Alert=intent
|
||||
// @formatter:on
|
||||
|
||||
// Sanitizing only the package or the class still allows redirecting
|
||||
// to non-exported activities in the same package
|
||||
// or activities with the same name in other packages, respectively.
|
||||
if (intent.getComponent().getPackageName().equals("something")) {
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ Alert=intent
|
||||
} else {
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ Alert=intent
|
||||
}
|
||||
if (intent.getComponent().getClassName().equals("something")) {
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ Alert=intent
|
||||
} else {
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ Alert=intent
|
||||
}
|
||||
|
||||
if (intent.getComponent().getPackageName().equals("something")
|
||||
&& intent.getComponent().getClassName().equals("something")) {
|
||||
startActivity(intent); // Safe
|
||||
} else {
|
||||
startActivity(intent); // $ hasAndroidIntentRedirection
|
||||
startActivity(intent); // $ Alert=intent
|
||||
}
|
||||
|
||||
try {
|
||||
{
|
||||
// Delayed cast
|
||||
Object obj = getIntent().getParcelableExtra("forward_intent");
|
||||
Object obj = getIntent().getParcelableExtra("forward_intent"); // $ Source=intent2
|
||||
Intent fwdIntent = (Intent) obj;
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent2
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
fwdIntent.setClassName((Context) null, intent.getStringExtra("className"));
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
fwdIntent.setClassName(intent.getStringExtra("packageName"), null);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
fwdIntent.setClassName(intent.getStringExtra("packageName"),
|
||||
intent.getStringExtra("className"));
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
@@ -93,27 +93,27 @@ public class AndroidIntentRedirectionTest extends Activity {
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
fwdIntent.setPackage(intent.getStringExtra("packageName"));
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
ComponentName component =
|
||||
new ComponentName(intent.getStringExtra("packageName"), null);
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
ComponentName component = new ComponentName("", intent.getStringExtra("className"));
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
ComponentName component =
|
||||
new ComponentName((Context) null, intent.getStringExtra("className"));
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
@@ -128,21 +128,21 @@ public class AndroidIntentRedirectionTest extends Activity {
|
||||
ComponentName component =
|
||||
ComponentName.createRelative("", intent.getStringExtra("className"));
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
ComponentName component =
|
||||
ComponentName.createRelative(intent.getStringExtra("packageName"), "");
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = new Intent();
|
||||
ComponentName component = ComponentName.createRelative((Context) null,
|
||||
intent.getStringExtra("className"));
|
||||
fwdIntent.setComponent(component);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent
|
||||
}
|
||||
{
|
||||
Intent originalIntent = getIntent();
|
||||
@@ -158,19 +158,19 @@ public class AndroidIntentRedirectionTest extends Activity {
|
||||
startActivity(anotherIntent); // Safe - copy constructor from original Intent
|
||||
}
|
||||
{
|
||||
Intent originalIntent = getIntent();
|
||||
Intent originalIntent = getIntent(); // $ Source=intent3
|
||||
Intent fwdIntent = (Intent) originalIntent.getParcelableExtra("forward_intent");
|
||||
if (originalIntent.getBooleanExtra("use_fwd_intent", false)) {
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(fwdIntent); // $ Alert=intent3
|
||||
} else {
|
||||
startActivity(originalIntent); // Safe - not an Intent obtained from the Extras
|
||||
}
|
||||
}
|
||||
{
|
||||
Intent originalIntent = getIntent();
|
||||
Intent originalIntent = getIntent(); // $ Source=intent4
|
||||
originalIntent.setClassName(originalIntent.getStringExtra("package_name"),
|
||||
originalIntent.getStringExtra("class_name"));
|
||||
startActivity(originalIntent); // $ hasAndroidIntentRedirection
|
||||
startActivity(originalIntent); // $ Alert=intent4
|
||||
}
|
||||
{
|
||||
Intent originalIntent = getIntent();
|
||||
@@ -189,16 +189,16 @@ public class AndroidIntentRedirectionTest extends Activity {
|
||||
startActivity(fwdIntent); // $ MISSING: $hasAndroidIntentRedirection
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = Intent.parseUri(getIntent().getStringExtra("uri"), 0);
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
Intent fwdIntent = Intent.parseUri(getIntent().getStringExtra("uri"), 0); // $ Source=intent5
|
||||
startActivity(fwdIntent); // $ Alert=intent5
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = Intent.getIntent(getIntent().getStringExtra("uri"));
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
Intent fwdIntent = Intent.getIntent(getIntent().getStringExtra("uri")); // $ Source=intent6
|
||||
startActivity(fwdIntent); // $ Alert=intent6
|
||||
}
|
||||
{
|
||||
Intent fwdIntent = Intent.getIntentOld(getIntent().getStringExtra("uri"));
|
||||
startActivity(fwdIntent); // $ hasAndroidIntentRedirection
|
||||
Intent fwdIntent = Intent.getIntentOld(getIntent().getStringExtra("uri")); // $ Source=intent7
|
||||
startActivity(fwdIntent); // $ Alert=intent7
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.AndroidIntentRedirectionQuery
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
module HasAndroidIntentRedirectionTest implements TestSig {
|
||||
string getARelevantTag() { result = "hasAndroidIntentRedirection" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasAndroidIntentRedirection" and
|
||||
exists(DataFlow::Node sink | IntentRedirectionFlow::flowTo(sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<HasAndroidIntentRedirectionTest>
|
||||
@@ -0,0 +1,2 @@
|
||||
query: Security/CWE/CWE-940/AndroidIntentRedirection.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -1 +1,2 @@
|
||||
Security/CWE-611/Xxe.ql
|
||||
query: Security/CWE-611/Xxe.ql
|
||||
postprocess: testUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -1,5 +1,5 @@
|
||||
function test() {
|
||||
var src = document.location.search;
|
||||
var src = document.location.search; // $ Source=search
|
||||
|
||||
if (window.DOMParser) {
|
||||
// OK: DOMParser only expands internal general entities
|
||||
@@ -8,10 +8,10 @@ function test() {
|
||||
var parser;
|
||||
try {
|
||||
// NOT OK: XMLDOM expands external entities by default
|
||||
(new ActiveXObject("Microsoft.XMLDOM")).loadXML(src);
|
||||
(new ActiveXObject("Microsoft.XMLDOM")).loadXML(src); // $ Alert=search
|
||||
} catch (e) {
|
||||
// NOT OK: MSXML expands external entities by default
|
||||
(new ActiveXObject("Msxml2.DOMDocument")).loadXML(src);
|
||||
(new ActiveXObject("Msxml2.DOMDocument")).loadXML(src); // $ Alert=search
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
const express = require('express');
|
||||
const libxmljs = require('libxmljs');
|
||||
|
||||
express().get('/some/path', function(req) {
|
||||
express().get('/some/path', function (req) {
|
||||
// NOT OK: unguarded entity expansion
|
||||
libxmljs.parseXml(req.param("some-xml"), { noent: true });
|
||||
libxmljs.parseXml(req.param("some-xml"), { noent: true }); // $ Alert
|
||||
});
|
||||
|
||||
express().post('/some/path', function(req, res) {
|
||||
express().post('/some/path', function (req, res) {
|
||||
// NOT OK: unguarded entity expansion
|
||||
libxmljs.parseXml(req.param("some-xml"), { noent: true });
|
||||
libxmljs.parseXml(req.param("some-xml"), { noent: true }); // $ Alert
|
||||
|
||||
// NOT OK: unguarded entity expansion
|
||||
libxmljs.parseXmlString(req.param("some-xml"), {noent:true})
|
||||
libxmljs.parseXmlString(req.param("some-xml"), { noent: true }) // $ Alert
|
||||
// NOT OK: unguarded entity expansion
|
||||
libxmljs.parseXmlString(req.files.products.data.toString('utf8'), {noent:true})
|
||||
|
||||
libxmljs.parseXmlString(req.files.products.data.toString('utf8'), { noent: true })// $ Source=files $ Alert=files
|
||||
|
||||
// OK - no entity expansion
|
||||
libxmljs.parseXmlString(req.files.products.data.toString('utf8'), {noent:false})
|
||||
libxmljs.parseXmlString(req.files.products.data.toString('utf8'), { noent: false })
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const express = require('express');
|
||||
const libxmljs = require('libxmljs');
|
||||
|
||||
express().get('/some/path', function(req) {
|
||||
express().get('/some/path', function (req) {
|
||||
const parser = new libxmljs.SaxParser();
|
||||
parser.parseString(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
|
||||
parser.parseString(req.param("some-xml")); // $ Alert: the SAX parser expands external entities by default
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const express = require('express');
|
||||
const libxmljs = require('libxmljs');
|
||||
|
||||
express().get('/some/path', function(req) {
|
||||
express().get('/some/path', function (req) {
|
||||
const parser = new libxmljs.SaxPushParser();
|
||||
parser.push(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
|
||||
parser.push(req.param("some-xml")); // $ Alert: the SAX parser expands external entities by default
|
||||
});
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import javascript
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,7 @@ class ModuleImporter(object):
|
||||
def get_import_nodes(self, loaded_module):
|
||||
'Return list of AST nodes representing imports'
|
||||
try:
|
||||
self.logger.debug("Looking for imports in %s", loaded_module.path)
|
||||
return imports_from_ast(loaded_module.py_ast)
|
||||
except Exception as ex:
|
||||
if isinstance(ex, SyntaxError):
|
||||
|
||||
@@ -109,14 +109,25 @@ class PythonSourceModule(object):
|
||||
def old_py_ast(self):
|
||||
# The py_ast is the raw ast from the Python parser.
|
||||
if self._py_ast is None:
|
||||
self._py_ast = semmle.python.parser.parse(self.tokens, self.logger)
|
||||
with timers["old_py_ast"]:
|
||||
self.logger.debug("Trying old parser on %s", self.path)
|
||||
self._py_ast = semmle.python.parser.parse(self.tokens, self.logger)
|
||||
self.logger.debug("Old parser successful on %s", self.path)
|
||||
else:
|
||||
self.logger.debug("Found (during old_py_ast) parse tree for %s in cache", self.path)
|
||||
return self._py_ast
|
||||
|
||||
@property
|
||||
def py_ast(self):
|
||||
try:
|
||||
# First, try to parse the source with the old Python parser.
|
||||
return self.old_py_ast
|
||||
# If the `CODEQL_PYTHON_DISABLE_OLD_PARSER` flag is present, we do not try to use the
|
||||
# old parser, and instead jump straight to the exception handler.
|
||||
if os.environ.get("CODEQL_PYTHON_DISABLE_OLD_PARSER"):
|
||||
self.logger.debug("Old parser disabled, skipping old parse attempt for %s", self.path)
|
||||
raise Exception("Skipping old parser")
|
||||
# Otherwise, we first try to parse the source with the old Python parser.
|
||||
self._py_ast = self.old_py_ast
|
||||
return self._py_ast
|
||||
except Exception as ex:
|
||||
# If that fails, try to parse the source with the new Python parser (unless it has been
|
||||
# explicitly disabled).
|
||||
@@ -131,7 +142,13 @@ class PythonSourceModule(object):
|
||||
raise SyntaxError("Exception %s while parsing %s" % (ex, self.path))
|
||||
else:
|
||||
try:
|
||||
self._py_ast = semmle.python.parser.tsg_parser.parse(self.path, self.logger)
|
||||
with timers["tsg_py_ast"]:
|
||||
if self._py_ast is None:
|
||||
self.logger.debug("Trying tsg-python on %s", self.path)
|
||||
self._py_ast = semmle.python.parser.tsg_parser.parse(self.path, self.logger)
|
||||
self.logger.debug("tsg-python successful on %s", self.path)
|
||||
else:
|
||||
self.logger.debug("Found (during py_ast) parse tree for %s in cache", self.path)
|
||||
return self._py_ast
|
||||
except SyntaxError as ex:
|
||||
raise ex
|
||||
|
||||
@@ -168,7 +168,7 @@ def read_tsg_python_output(path, logger):
|
||||
p.stdout.close()
|
||||
p.terminate()
|
||||
p.wait()
|
||||
logger.info("Read {} nodes and {} edges from TSG output".format(len(node_attr), len(edge_attr)))
|
||||
logger.debug("Read {} nodes and {} edges from TSG output".format(len(node_attr), len(edge_attr)))
|
||||
return node_attr, edge_attr
|
||||
|
||||
def evaluate_string(s):
|
||||
|
||||
@@ -10,7 +10,7 @@ from io import BytesIO
|
||||
|
||||
#Semantic version of extractor.
|
||||
#Update this if any changes are made
|
||||
VERSION = "7.1.0"
|
||||
VERSION = "7.1.1"
|
||||
|
||||
PY_EXTENSIONS = ".py", ".pyw"
|
||||
|
||||
|
||||
8
python/extractor/tests/parser/async-await.py
Normal file
8
python/extractor/tests/parser/async-await.py
Normal file
@@ -0,0 +1,8 @@
|
||||
async def foo():
|
||||
await bar() + await baz()
|
||||
|
||||
async with foo() as bar, baz() as quux:
|
||||
pass
|
||||
|
||||
async for spam in eggs:
|
||||
pass
|
||||
@@ -35,3 +35,5 @@ t, u,
|
||||
x, y,
|
||||
#comment
|
||||
)
|
||||
|
||||
((z,))
|
||||
|
||||
@@ -65,3 +65,10 @@ t = tuple(x for y in z)
|
||||
d for e in f if g # comment
|
||||
# comment
|
||||
] # comment
|
||||
|
||||
# Generator expression with comments
|
||||
(# comment
|
||||
alpha # comment
|
||||
for beta in gamma # comment
|
||||
# comment
|
||||
)
|
||||
|
||||
@@ -77,3 +77,12 @@ if 34:
|
||||
b'\xc5\xe5'
|
||||
if 35:
|
||||
f"{x=}"
|
||||
if 36:
|
||||
r"a\"a"
|
||||
if 37:
|
||||
r'a\'a'
|
||||
if 38:
|
||||
r'a\\'
|
||||
if 39:
|
||||
r'a\
|
||||
'
|
||||
|
||||
@@ -404,7 +404,7 @@
|
||||
|
||||
;;; GeneratorExp
|
||||
|
||||
(generator_expression . "(" . (comment)* . (_) @start (_) @end . (comment)* . ")" .) @generatorexp
|
||||
(generator_expression . "(" . (comment)* . (expression) @start [(for_in_clause) (if_clause)] @end . (comment)* . ")" .) @generatorexp
|
||||
{
|
||||
attr (@generatorexp.node) _location_start = (location-start @start)
|
||||
attr (@generatorexp.node) _location_end = (location-end @end)
|
||||
@@ -416,13 +416,13 @@
|
||||
attr (@if.node) _location_end = (location-end @expr)
|
||||
}
|
||||
|
||||
(generator_expression . "(" . (comment)* . (_) @start (for_in_clause) @child (_) @end . (comment)* . ")" .) @genexpr
|
||||
(generator_expression . "(" . (comment)* . (expression) @start (for_in_clause) @child [(for_in_clause) (if_clause)] @end . (comment)* . ")" .) @genexpr
|
||||
{
|
||||
attr (@child.node) _location_start = (location-start @start)
|
||||
attr (@child.node) _location_end = (location-end @end)
|
||||
}
|
||||
|
||||
(generator_expression . "(" . (comment)* . (_) @start (for_in_clause) @end . (comment)* . ")" .) @genexpr
|
||||
(generator_expression . "(" . (comment)* . (expression) @start (for_in_clause) @end . (comment)* . ")" .) @genexpr
|
||||
{
|
||||
attr (@end.node) _location_start = (location-start @start)
|
||||
attr (@end.node) _location_end = (location-end @end)
|
||||
@@ -863,7 +863,7 @@
|
||||
; information for the entire generator expression (yes, it is a wide parameter!) and so we must recreate the logic for
|
||||
; setting this location information correctly.
|
||||
|
||||
(generator_expression . "(" . (comment)* . (_) @start (_) @end . (comment)* . ")" .) @genexpr
|
||||
(generator_expression . "(" . (comment)* . (expression) @start [(for_in_clause) (if_clause)] @end . (comment)* . ")" .) @genexpr
|
||||
{
|
||||
; Synthesize the `genexpr` function
|
||||
let @genexpr.fun = (ast-node @genexpr "Function")
|
||||
@@ -2661,6 +2661,14 @@
|
||||
let @with.first = @first.node
|
||||
}
|
||||
|
||||
; Async status
|
||||
; NOTE: We only set the `is_async` field on the _first_ clause of the `with` statement,
|
||||
; as this is the behaviour of the old parser.
|
||||
(with_statement "async" "with" @with_keyword (with_clause . (with_item) @with))
|
||||
{
|
||||
attr (@with.node) is_async = #true
|
||||
}
|
||||
|
||||
(with_item
|
||||
value: (_) @value
|
||||
) @with
|
||||
@@ -3264,6 +3272,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
; Async status
|
||||
(function_definition "async" "def" @def_keyword) @funcdef
|
||||
{
|
||||
let start = (location-start @def_keyword)
|
||||
attr (@funcdef.function) is_async = #true
|
||||
attr (@funcdef.node) _location_start = start
|
||||
attr (@funcdef.function) _location_start = start
|
||||
attr (@funcdef.funcexpr) _location_start = start
|
||||
}
|
||||
|
||||
;;; Decorators
|
||||
|
||||
(decorated_definition
|
||||
@@ -3478,5 +3496,9 @@
|
||||
|
||||
[(tuple element: (_)) (tuple_pattern)] @tup
|
||||
{
|
||||
attr (@tup.node) parenthesised = #true
|
||||
; In order to avoid writing to the `parenthesised` attribute twice, we only set it here
|
||||
; if the surrounding expression is not a `parenthesized_expression`.
|
||||
if (not (instance-of (get-parent @tup) "parenthesized_expression")) {
|
||||
attr (@tup.node) parenthesised = #true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,7 +751,6 @@ module.exports = grammar({
|
||||
$.comparison_operator,
|
||||
$.not_operator,
|
||||
$.boolean_operator,
|
||||
$.await,
|
||||
$.lambda,
|
||||
$.primary_expression,
|
||||
$.conditional_expression,
|
||||
@@ -759,6 +758,7 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
primary_expression: $ => choice(
|
||||
$.await,
|
||||
$.binary_operator,
|
||||
$.identifier,
|
||||
$.keyword_identifier,
|
||||
@@ -1202,7 +1202,7 @@ module.exports = grammar({
|
||||
|
||||
await: $ => prec(PREC.unary, seq(
|
||||
'await',
|
||||
$.expression
|
||||
$.primary_expression
|
||||
)),
|
||||
|
||||
comment: $ => token(seq('#', /.*/)),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
|
||||
"name": "python",
|
||||
"word": "identifier",
|
||||
"rules": {
|
||||
@@ -3843,10 +3842,6 @@
|
||||
"type": "SYMBOL",
|
||||
"name": "boolean_operator"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "await"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "lambda"
|
||||
@@ -3868,6 +3863,10 @@
|
||||
"primary_expression": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "await"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "binary_operator"
|
||||
@@ -6586,7 +6585,7 @@
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
"name": "primary_expression"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6696,3 +6695,4 @@
|
||||
"parameter"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -115,10 +115,6 @@
|
||||
"type": "expression",
|
||||
"named": true,
|
||||
"subtypes": [
|
||||
{
|
||||
"type": "await",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "boolean_operator",
|
||||
"named": true
|
||||
@@ -229,6 +225,10 @@
|
||||
"type": "attribute",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "await",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "binary_operator",
|
||||
"named": true
|
||||
@@ -587,7 +587,7 @@
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "expression",
|
||||
"type": "primary_expression",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
@@ -2691,7 +2691,6 @@
|
||||
{
|
||||
"type": "module",
|
||||
"named": true,
|
||||
"root": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
@@ -3816,10 +3815,6 @@
|
||||
"type": ":=",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": ";",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "<",
|
||||
"named": false
|
||||
@@ -3876,10 +3871,6 @@
|
||||
"type": "[",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "\\",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "]",
|
||||
"named": false
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -161,6 +161,22 @@ struct Scanner {
|
||||
} else if (lexer->lookahead == '\\') {
|
||||
if (delimiter.is_raw()) {
|
||||
lexer->advance(lexer, false);
|
||||
// In raw strings, backslashes _can_ escape the same kind of quotes as the outer
|
||||
// string, so we must take care to traverse any such escaped quotes now. If we don't do
|
||||
// this, we will mistakenly consider the string to end at that escaped quote.
|
||||
// Likewise, this also extends to escaped backslashes.
|
||||
if (lexer->lookahead == end_character || lexer->lookahead == '\\') {
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
// Newlines after backslashes also cause issues, so we explicitly step over them here.
|
||||
if (lexer->lookahead == '\r') {
|
||||
lexer->advance(lexer, false);
|
||||
if (lexer->lookahead == '\n') {
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
} else if (lexer->lookahead == '\n') {
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
continue;
|
||||
} else if (delimiter.is_bytes()) {
|
||||
lexer->mark_end(lexer);
|
||||
|
||||
@@ -13,8 +13,9 @@ extern "C" {
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
@@ -47,7 +48,6 @@ struct TSLexer {
|
||||
uint32_t (*get_column)(TSLexer *);
|
||||
bool (*is_at_included_range_start)(const TSLexer *);
|
||||
bool (*eof)(const TSLexer *);
|
||||
void (*log)(const TSLexer *, const char *, ...);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -87,11 +87,6 @@ typedef union {
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
typedef struct {
|
||||
int32_t start;
|
||||
int32_t end;
|
||||
} TSCharacterRange;
|
||||
|
||||
struct TSLanguage {
|
||||
uint32_t version;
|
||||
uint32_t symbol_count;
|
||||
@@ -128,41 +123,15 @@ struct TSLanguage {
|
||||
unsigned (*serialize)(void *, char *);
|
||||
void (*deserialize)(void *, const char *, unsigned);
|
||||
} external_scanner;
|
||||
const TSStateId *primary_state_ids;
|
||||
};
|
||||
|
||||
static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) {
|
||||
uint32_t index = 0;
|
||||
uint32_t size = len - index;
|
||||
while (size > 1) {
|
||||
uint32_t half_size = size / 2;
|
||||
uint32_t mid_index = index + half_size;
|
||||
TSCharacterRange *range = &ranges[mid_index];
|
||||
if (lookahead >= range->start && lookahead <= range->end) {
|
||||
return true;
|
||||
} else if (lookahead > range->end) {
|
||||
index = mid_index;
|
||||
}
|
||||
size -= half_size;
|
||||
}
|
||||
TSCharacterRange *range = &ranges[index];
|
||||
return (lookahead >= range->start && lookahead <= range->end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lexer Macros
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define UNUSED __pragma(warning(suppress : 4101))
|
||||
#else
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
UNUSED \
|
||||
bool eof = false; \
|
||||
int32_t lookahead; \
|
||||
goto start; \
|
||||
@@ -178,17 +147,6 @@ static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define ADVANCE_MAP(...) \
|
||||
{ \
|
||||
static const uint16_t map[] = { __VA_ARGS__ }; \
|
||||
for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \
|
||||
if (map[i] == lookahead) { \
|
||||
state = map[i + 1]; \
|
||||
goto next_state; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SKIP(state_value) \
|
||||
{ \
|
||||
skip = true; \
|
||||
@@ -207,7 +165,7 @@ static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t
|
||||
* Parse Table Macros
|
||||
*/
|
||||
|
||||
#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
|
||||
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
|
||||
|
||||
#define STATE(id) id
|
||||
|
||||
@@ -217,7 +175,7 @@ static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = (state_value) \
|
||||
.state = state_value \
|
||||
} \
|
||||
}}
|
||||
|
||||
@@ -225,7 +183,7 @@ static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = (state_value), \
|
||||
.state = state_value, \
|
||||
.repetition = true \
|
||||
} \
|
||||
}}
|
||||
@@ -238,15 +196,14 @@ static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t
|
||||
} \
|
||||
}}
|
||||
|
||||
#define REDUCE(symbol_name, children, precedence, prod_id) \
|
||||
{{ \
|
||||
.reduce = { \
|
||||
.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_name, \
|
||||
.child_count = children, \
|
||||
.dynamic_precedence = precedence, \
|
||||
.production_id = prod_id \
|
||||
}, \
|
||||
#define REDUCE(symbol_val, child_count_val, ...) \
|
||||
{{ \
|
||||
.reduce = { \
|
||||
.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_val, \
|
||||
.child_count = child_count_val, \
|
||||
__VA_ARGS__ \
|
||||
}, \
|
||||
}}
|
||||
|
||||
#define RECOVER() \
|
||||
|
||||
@@ -103,20 +103,20 @@ module TypeTrackingBasedCallGraph {
|
||||
/** A call that can be resolved by type-tracking. */
|
||||
class ResolvableCall extends RelevantCall {
|
||||
ResolvableCall() {
|
||||
exists(TT::TNormalCall(this, _, _))
|
||||
TT::resolveCall(this, _, _)
|
||||
or
|
||||
TT::resolveClassCall(this, _)
|
||||
}
|
||||
|
||||
/** Gets a resolved target of this call. */
|
||||
Target getTarget() {
|
||||
exists(TT::DataFlowCall call, TT::CallType ct, Function targetFunc |
|
||||
call = TT::TNormalCall(this, targetFunc, ct) and
|
||||
exists(TT::CallType ct, Function targetFunc |
|
||||
TT::resolveCall(this, targetFunc, ct) and
|
||||
not ct instanceof TT::CallTypeClass and
|
||||
targetFunc = result.(TargetFunction).getFunction()
|
||||
)
|
||||
or
|
||||
// a TT::TNormalCall only exists when the call can be resolved to a function.
|
||||
// TT::resolveCall only holds when the call can be resolved to a function.
|
||||
// Since points-to just says the call goes directly to the class itself, and
|
||||
// type-tracking based wants to resolve this to the constructor, which might not
|
||||
// exist. So to do a proper comparison, we don't require the call to be resolve to
|
||||
|
||||
@@ -5,15 +5,5 @@
|
||||
|
||||
private import python as PY
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
private module Impl implements InlineExpectationsTestSig {
|
||||
/**
|
||||
* A class representing line comments in Python. As this is the only form of comment Python
|
||||
* permits, we simply reuse the `Comment` class.
|
||||
*/
|
||||
class ExpectationComment = PY::Comment;
|
||||
|
||||
class Location = PY::Location;
|
||||
}
|
||||
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import Make<Impl>
|
||||
|
||||
21
python/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
python/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
private import python as PY
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
module Impl implements InlineExpectationsTestSig {
|
||||
/**
|
||||
* A class representing line comments in Python. As this is the only form of comment Python
|
||||
* permits, we simply reuse the `Comment` class.
|
||||
*/
|
||||
class ExpectationComment = PY::Comment;
|
||||
|
||||
class Location = PY::Location;
|
||||
}
|
||||
@@ -31,10 +31,7 @@ predicate typeTrackerCallEdge(CallNode call, Function callable) {
|
||||
predicate typeTrackerClassCall(CallNode call, Function callable) {
|
||||
exists(call.getLocation().getFile().getRelativePath()) and
|
||||
exists(callable.getLocation().getFile().getRelativePath()) and
|
||||
exists(TT::NormalCall cc |
|
||||
cc = TT::TNormalCall(call, _, any(TT::TCallType t | t instanceof TT::CallTypeClass)) and
|
||||
TT::TFunction(callable) = TT::viableCallable(cc)
|
||||
)
|
||||
TT::resolveCall(call, callable, any(TT::TCallType t | t instanceof TT::CallTypeClass))
|
||||
}
|
||||
|
||||
module CallGraphTest implements TestSig {
|
||||
|
||||
@@ -21,8 +21,11 @@ module DataFlowCallTest implements TestSig {
|
||||
value = prettyExpr(call.getNode().getNode()) and
|
||||
tag = "call"
|
||||
or
|
||||
value = call.(DataFlowDispatch::NormalCall).getCallType().toString() and
|
||||
tag = "callType"
|
||||
exists(DataFlowDispatch::CallType callType |
|
||||
DataFlowDispatch::resolveCall(call.getNode(), _, callType) and
|
||||
value = callType.toString() and
|
||||
tag = "callType"
|
||||
)
|
||||
or
|
||||
exists(DataFlowDispatch::ArgumentPosition pos, DataFlow::Node arg |
|
||||
arg = call.getArgument(pos)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Numerics/Pythagorean.ql
|
||||
query: Numerics/Pythagorean.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -3,12 +3,12 @@
|
||||
from math import sqrt
|
||||
|
||||
def withPow(a, b):
|
||||
return sqrt(a**2 + b**2)
|
||||
return sqrt(a**2 + b**2) # $ Alert
|
||||
|
||||
def withMul(a, b):
|
||||
return sqrt(a*a + b*b)
|
||||
return sqrt(a*a + b*b) # $ Alert
|
||||
|
||||
def withRef(a, b):
|
||||
a2 = a**2
|
||||
b2 = b*b
|
||||
return sqrt(a2 + b2)
|
||||
return sqrt(a2 + b2) # $ Alert
|
||||
@@ -1 +1,2 @@
|
||||
Security/CWE-094/CodeInjection.ql
|
||||
query: Security/CWE-094/CodeInjection.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from flask import Flask, request
|
||||
from flask import Flask, request # $ Source=flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/code-execution")
|
||||
def code_execution():
|
||||
code = request.args.get("code")
|
||||
exec(code) # NOT OK
|
||||
eval(code) # NOT OK
|
||||
exec(code) # $ Alert=flask
|
||||
eval(code) # $ Alert=flask
|
||||
cmd = compile(code, "<filename>", "exec")
|
||||
exec(cmd) # NOT OK
|
||||
exec(cmd) # $ Alert=flask
|
||||
|
||||
|
||||
@app.route("/safe-code-execution")
|
||||
@@ -18,5 +18,5 @@ def code_execution():
|
||||
obj_name = request.args.get("obj")
|
||||
if obj_name == "foo" or obj_name == "bar":
|
||||
# TODO: Should not alert on this
|
||||
obj = eval(obj_name) # OK
|
||||
obj = eval(obj_name) # $ SPURIOUS: Alert=flask
|
||||
print(obj, obj*10)
|
||||
|
||||
@@ -829,7 +829,28 @@ class ContentSet extends TContentSet {
|
||||
this.isAny() and
|
||||
exists(result)
|
||||
or
|
||||
result = this.getAnElementReadContent()
|
||||
exists(Content elementContent | elementContent = this.getAnElementReadContent() |
|
||||
result = elementContent
|
||||
or
|
||||
// Do not distinguish symbol keys from string keys. This allows us to
|
||||
// give more precise summaries for something like `with_indifferent_access`,
|
||||
// and the amount of false-positive flow arising from this should be very
|
||||
// limited.
|
||||
elementContent =
|
||||
any(Content::KnownElementContent known, ConstantValue cv |
|
||||
cv = known.getIndex() and
|
||||
result.(Content::KnownElementContent).getIndex() =
|
||||
any(ConstantValue cv2 |
|
||||
cv2.(ConstantValue::ConstantSymbolValue).getStringlikeValue() =
|
||||
cv.(ConstantValue::ConstantStringValue).getStringlikeValue()
|
||||
or
|
||||
cv2.(ConstantValue::ConstantStringValue).getStringlikeValue() =
|
||||
cv.(ConstantValue::ConstantSymbolValue).getStringlikeValue()
|
||||
)
|
||||
|
|
||||
known
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,16 +121,6 @@ module ActiveSupport {
|
||||
* Extensions to the `Hash` class.
|
||||
*/
|
||||
module Hash {
|
||||
private class WithIndifferentAccessSummary extends SimpleSummarizedCallable {
|
||||
WithIndifferentAccessSummary() { this = "with_indifferent_access" }
|
||||
|
||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[any]" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow summary for `reverse_merge`, and its alias `with_defaults`.
|
||||
*/
|
||||
@@ -167,8 +157,9 @@ module ActiveSupport {
|
||||
}
|
||||
|
||||
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[?]" and
|
||||
// keys are considered equal modulo string/symbol in our implementation
|
||||
input = "Argument[self].WithElement[any]" and
|
||||
output = "ReturnValue" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
21
ruby/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
ruby/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import ruby
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -458,22 +458,40 @@ edges
|
||||
| semantics.rb:263:14:263:14 | h [element :foo] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semantics.rb:263:10:263:15 | call to s31 | provenance | |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semantics.rb:268:5:268:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semantics.rb:268:5:268:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:267:15:267:25 | call to source | semantics.rb:267:5:267:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:267:15:267:25 | call to source | semantics.rb:267:5:267:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semantics.rb:269:5:269:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semantics.rb:269:5:269:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semantics.rb:269:5:269:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semantics.rb:269:5:269:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semantics.rb:268:5:268:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semantics.rb:268:5:268:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:268:16:268:26 | call to source | semantics.rb:268:5:268:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:268:16:268:26 | call to source | semantics.rb:268:5:268:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semantics.rb:270:5:270:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semantics.rb:270:5:270:5 | h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semantics.rb:270:5:270:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semantics.rb:270:5:270:5 | h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semantics.rb:269:5:269:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semantics.rb:269:5:269:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semantics.rb:269:5:269:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semantics.rb:269:5:269:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semantics.rb:273:14:273:14 | h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semantics.rb:273:14:273:14 | h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semantics.rb:273:14:273:14 | h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semantics.rb:273:14:273:14 | h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semantics.rb:270:5:270:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semantics.rb:270:5:270:5 | [post] h [element :foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semantics.rb:270:5:270:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semantics.rb:270:5:270:5 | [post] h [element foo] | provenance | |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semantics.rb:273:14:273:14 | h [element] | provenance | |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semantics.rb:273:14:273:14 | h [element] | provenance | |
|
||||
| semantics.rb:271:12:271:22 | call to source | semantics.rb:271:5:271:5 | [post] h [element] | provenance | |
|
||||
| semantics.rb:271:12:271:22 | call to source | semantics.rb:271:5:271:5 | [post] h [element] | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
| semantics.rb:273:14:273:14 | h [element] | semantics.rb:273:10:273:15 | call to s32 | provenance | |
|
||||
@@ -538,6 +556,8 @@ edges
|
||||
| semantics.rb:291:10:291:10 | x [element :foo] | semantics.rb:291:10:291:16 | ...[...] | provenance | |
|
||||
| semantics.rb:293:10:293:10 | x [element :foo] | semantics.rb:293:10:293:13 | ...[...] | provenance | |
|
||||
| semantics.rb:293:10:293:10 | x [element :foo] | semantics.rb:293:10:293:13 | ...[...] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:298:10:298:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:298:10:298:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:299:10:299:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:299:10:299:10 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:5:297:5 | x [element foo] | semantics.rb:301:10:301:10 | x [element foo] | provenance | |
|
||||
@@ -546,6 +566,8 @@ edges
|
||||
| semantics.rb:297:9:297:24 | call to s36 [element foo] | semantics.rb:297:5:297:5 | x [element foo] | provenance | |
|
||||
| semantics.rb:297:13:297:23 | call to source | semantics.rb:297:9:297:24 | call to s36 [element foo] | provenance | |
|
||||
| semantics.rb:297:13:297:23 | call to source | semantics.rb:297:9:297:24 | call to s36 [element foo] | provenance | |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semantics.rb:298:10:298:16 | ...[...] | provenance | |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semantics.rb:298:10:298:16 | ...[...] | provenance | |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semantics.rb:299:10:299:17 | ...[...] | provenance | |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semantics.rb:299:10:299:17 | ...[...] | provenance | |
|
||||
| semantics.rb:301:10:301:10 | x [element foo] | semantics.rb:301:10:301:13 | ...[...] | provenance | |
|
||||
@@ -1616,16 +1638,32 @@ nodes
|
||||
| semantics.rb:263:14:263:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semmle.label | h [element] |
|
||||
| semantics.rb:263:14:263:14 | h [element] | semmle.label | h [element] |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:267:5:267:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:267:15:267:25 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:267:15:267:25 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:268:5:268:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:268:5:268:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:268:16:268:26 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:268:16:268:26 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:269:5:269:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element :foo] | semmle.label | [post] h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | [post] h [element foo] | semmle.label | [post] h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:270:5:270:5 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:271:5:271:5 | [post] h [element] | semmle.label | [post] h [element] |
|
||||
@@ -1634,6 +1672,8 @@ nodes
|
||||
| semantics.rb:271:12:271:22 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:273:10:273:15 | call to s32 | semmle.label | call to s32 |
|
||||
| semantics.rb:273:10:273:15 | call to s32 | semmle.label | call to s32 |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element :foo] | semmle.label | h [element :foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element foo] | semmle.label | h [element foo] |
|
||||
| semantics.rb:273:14:273:14 | h [element] | semmle.label | h [element] |
|
||||
@@ -1708,6 +1748,10 @@ nodes
|
||||
| semantics.rb:297:9:297:24 | call to s36 [element foo] | semmle.label | call to s36 [element foo] |
|
||||
| semantics.rb:297:13:297:23 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:297:13:297:23 | call to source | semmle.label | call to source |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:298:10:298:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:298:10:298:16 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:298:10:298:16 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:299:10:299:10 | x [element foo] | semmle.label | x [element foo] |
|
||||
| semantics.rb:299:10:299:17 | ...[...] | semmle.label | ...[...] |
|
||||
|
||||
@@ -270,7 +270,7 @@ def m32(h, i)
|
||||
h[1] = source("d")
|
||||
h[i] = source("e")
|
||||
|
||||
sink s32(h) # $ hasValueFlow=b hasValueFlow=e
|
||||
sink s32(h) # $ hasValueFlow=b $ hasValueFlow=e $ SPURIOUS: hasValueFlow=a
|
||||
end
|
||||
|
||||
def m33(h, i)
|
||||
@@ -295,7 +295,7 @@ end
|
||||
|
||||
def m36(h, i)
|
||||
x = s36(source("a"))
|
||||
sink x[:foo]
|
||||
sink x[:foo] # $ SPURIOUS: hasValueFlow=a
|
||||
sink x["foo"] # $ hasValueFlow=a
|
||||
sink x[:bar]
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
|
||||
@@ -40,12 +40,16 @@ edges
|
||||
| hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:42:5:42:8 | [post] hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element 0] | hash_flow.rb:44:10:44:13 | hash [element 0] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element :a] | hash_flow.rb:46:10:46:13 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element :a] | hash_flow.rb:48:10:48:13 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element a] | hash_flow.rb:46:10:46:13 | hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | [post] hash [element a] | hash_flow.rb:48:10:48:13 | hash [element a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element 0] | hash_flow.rb:43:5:43:8 | [post] hash [element 0] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element :a] | hash_flow.rb:43:5:43:8 | [post] hash [element :a] | provenance | |
|
||||
| hash_flow.rb:43:5:43:8 | hash [element a] | hash_flow.rb:43:5:43:8 | [post] hash [element a] | provenance | |
|
||||
| hash_flow.rb:44:10:44:13 | hash [element 0] | hash_flow.rb:44:10:44:16 | ...[...] | provenance | |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element :a] | hash_flow.rb:46:10:46:17 | ...[...] | provenance | |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element a] | hash_flow.rb:46:10:46:17 | ...[...] | provenance | |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element :a] | hash_flow.rb:48:10:48:18 | ...[...] | provenance | |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element a] | hash_flow.rb:48:10:48:18 | ...[...] | provenance | |
|
||||
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | hash_flow.rb:56:10:56:14 | hash1 [element :a] | provenance | |
|
||||
| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | hash_flow.rb:55:5:55:9 | hash1 [element :a] | provenance | |
|
||||
@@ -583,7 +587,9 @@ edges
|
||||
| hash_flow.rb:626:11:626:11 | a [element] | hash_flow.rb:626:11:626:16 | ...[...] | provenance | |
|
||||
| hash_flow.rb:626:11:626:16 | ...[...] | hash_flow.rb:626:10:626:17 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :a] | hash_flow.rb:639:5:639:8 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :a] | hash_flow.rb:640:11:640:14 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :c] | hash_flow.rb:639:5:639:8 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:632:5:632:8 | hash [element :c] | hash_flow.rb:642:11:642:14 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:632:12:636:5 | call to [] [element :a] | hash_flow.rb:632:5:632:8 | hash [element :a] | provenance | |
|
||||
| hash_flow.rb:632:12:636:5 | call to [] [element :c] | hash_flow.rb:632:5:632:8 | hash [element :c] | provenance | |
|
||||
| hash_flow.rb:633:15:633:25 | call to taint | hash_flow.rb:632:12:636:5 | call to [] [element :a] | provenance | |
|
||||
@@ -599,10 +605,12 @@ edges
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :a] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :c] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element] | hash_flow.rb:639:5:639:8 | [post] hash [element] | provenance | |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element :a] | hash_flow.rb:640:11:640:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element] | hash_flow.rb:640:11:640:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:640:11:640:19 | ...[...] | hash_flow.rb:640:10:640:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:641:11:641:14 | hash [element] | hash_flow.rb:641:11:641:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:641:11:641:19 | ...[...] | hash_flow.rb:641:10:641:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element :c] | hash_flow.rb:642:11:642:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element] | hash_flow.rb:642:11:642:19 | ...[...] | provenance | |
|
||||
| hash_flow.rb:642:11:642:19 | ...[...] | hash_flow.rb:642:10:642:20 | ( ... ) | provenance | |
|
||||
| hash_flow.rb:648:5:648:8 | hash [element :a] | hash_flow.rb:653:9:653:12 | hash [element :a] | provenance | |
|
||||
@@ -1149,7 +1157,9 @@ nodes
|
||||
| hash_flow.rb:44:10:44:13 | hash [element 0] | semmle.label | hash [element 0] |
|
||||
| hash_flow.rb:44:10:44:16 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:46:10:46:13 | hash [element a] | semmle.label | hash [element a] |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:48:10:48:13 | hash [element a] | semmle.label | hash [element a] |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:55:5:55:9 | hash1 [element :a] | semmle.label | hash1 [element :a] |
|
||||
@@ -1740,12 +1750,14 @@ nodes
|
||||
| hash_flow.rb:639:5:639:8 | hash [element :c] | semmle.label | hash [element :c] |
|
||||
| hash_flow.rb:639:5:639:8 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:640:10:640:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
| hash_flow.rb:640:11:640:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:640:11:640:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:641:10:641:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:641:11:641:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:641:11:641:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:642:10:642:20 | ( ... ) | semmle.label | ( ... ) |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element :c] | semmle.label | hash [element :c] |
|
||||
| hash_flow.rb:642:11:642:14 | hash [element] | semmle.label | hash [element] |
|
||||
| hash_flow.rb:642:11:642:19 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_flow.rb:648:5:648:8 | hash [element :a] | semmle.label | hash [element :a] |
|
||||
@@ -2349,6 +2361,8 @@ hashLiteral
|
||||
| hash_flow.rb:30:10:30:16 | ...[...] | hash_flow.rb:19:14:19:23 | call to taint | hash_flow.rb:30:10:30:16 | ...[...] | $@ | hash_flow.rb:19:14:19:23 | call to taint | call to taint |
|
||||
| hash_flow.rb:44:10:44:16 | ...[...] | hash_flow.rb:38:15:38:24 | call to taint | hash_flow.rb:44:10:44:16 | ...[...] | $@ | hash_flow.rb:38:15:38:24 | call to taint | call to taint |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | hash_flow.rb:40:16:40:25 | call to taint | hash_flow.rb:46:10:46:17 | ...[...] | $@ | hash_flow.rb:40:16:40:25 | call to taint | call to taint |
|
||||
| hash_flow.rb:46:10:46:17 | ...[...] | hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:46:10:46:17 | ...[...] | $@ | hash_flow.rb:42:17:42:26 | call to taint | call to taint |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | hash_flow.rb:40:16:40:25 | call to taint | hash_flow.rb:48:10:48:18 | ...[...] | $@ | hash_flow.rb:40:16:40:25 | call to taint | call to taint |
|
||||
| hash_flow.rb:48:10:48:18 | ...[...] | hash_flow.rb:42:17:42:26 | call to taint | hash_flow.rb:48:10:48:18 | ...[...] | $@ | hash_flow.rb:42:17:42:26 | call to taint | call to taint |
|
||||
| hash_flow.rb:56:10:56:18 | ...[...] | hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:56:10:56:18 | ...[...] | $@ | hash_flow.rb:55:21:55:30 | call to taint | call to taint |
|
||||
| hash_flow.rb:61:10:61:18 | ...[...] | hash_flow.rb:59:13:59:22 | call to taint | hash_flow.rb:61:10:61:18 | ...[...] | $@ | hash_flow.rb:59:13:59:22 | call to taint | call to taint |
|
||||
|
||||
@@ -43,9 +43,9 @@ def m2()
|
||||
hash['b'] = 3
|
||||
sink(hash[0]) # $ hasValueFlow=2.1
|
||||
sink(hash[1])
|
||||
sink(hash[:a]) # $ hasValueFlow=2.2
|
||||
sink(hash[:a]) # $ hasValueFlow=2.2 $ SPURIOUS hasValueFlow=2.3
|
||||
sink(hash[:b])
|
||||
sink(hash['a']) # $ hasValueFlow=2.3
|
||||
sink(hash['a']) # $ hasValueFlow=2.3 $ SPURIOUS hasValueFlow=2.2
|
||||
sink(hash['b'])
|
||||
end
|
||||
|
||||
|
||||
@@ -60,45 +60,45 @@ edges
|
||||
| hash_extensions.rb:2:5:2:5 | h [element :a] | hash_extensions.rb:3:9:3:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:2:9:2:26 | call to [] [element :a] | hash_extensions.rb:2:5:2:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:2:9:2:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element] | hash_extensions.rb:4:10:4:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | hash_extensions.rb:3:5:3:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element] | hash_extensions.rb:4:10:4:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element :a] | hash_extensions.rb:11:9:11:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:10:9:10:26 | call to [] [element :a] | hash_extensions.rb:10:5:10:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:10:14:10:24 | call to source | hash_extensions.rb:10:9:10:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element] | hash_extensions.rb:12:10:12:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element :a] | hash_extensions.rb:11:9:11:20 | call to to_options [element] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element] | hash_extensions.rb:11:5:11:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element] | hash_extensions.rb:12:10:12:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element :a] | hash_extensions.rb:19:9:19:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:18:9:18:26 | call to [] [element :a] | hash_extensions.rb:18:5:18:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:18:14:18:24 | call to source | hash_extensions.rb:18:9:18:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element] | hash_extensions.rb:20:10:20:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element :a] | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | hash_extensions.rb:19:5:19:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element] | hash_extensions.rb:20:10:20:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element :a] | hash_extensions.rb:4:10:4:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | provenance | |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | hash_extensions.rb:3:5:3:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element :a] | hash_extensions.rb:4:10:4:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element a] | hash_extensions.rb:11:9:11:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:10:9:10:30 | call to [] [element a] | hash_extensions.rb:10:5:10:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:10:18:10:28 | call to source | hash_extensions.rb:10:9:10:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element a] | hash_extensions.rb:12:10:12:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element a] | hash_extensions.rb:11:9:11:20 | call to to_options [element a] | provenance | |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element a] | hash_extensions.rb:11:5:11:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element a] | hash_extensions.rb:12:10:12:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element a] | hash_extensions.rb:19:9:19:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:18:9:18:30 | call to [] [element a] | hash_extensions.rb:18:5:18:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:18:18:18:28 | call to source | hash_extensions.rb:18:9:18:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element a] | hash_extensions.rb:20:10:20:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element a] | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | provenance | |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | hash_extensions.rb:19:5:19:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element a] | hash_extensions.rb:20:10:20:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:26:5:26:5 | h [element :a] | hash_extensions.rb:27:9:27:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:26:9:26:26 | call to [] [element :a] | hash_extensions.rb:26:5:26:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:26:9:26:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element] | hash_extensions.rb:28:10:28:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | hash_extensions.rb:27:5:27:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element] | hash_extensions.rb:28:10:28:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element :a] | hash_extensions.rb:35:9:35:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:34:9:34:26 | call to [] [element :a] | hash_extensions.rb:34:5:34:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:34:14:34:24 | call to source | hash_extensions.rb:34:9:34:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element] | hash_extensions.rb:36:10:36:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element :a] | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | hash_extensions.rb:35:5:35:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element] | hash_extensions.rb:36:10:36:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element :a] | hash_extensions.rb:28:10:28:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | provenance | |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | hash_extensions.rb:27:5:27:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element :a] | hash_extensions.rb:28:10:28:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element a] | hash_extensions.rb:35:9:35:9 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:34:9:34:30 | call to [] [element a] | hash_extensions.rb:34:5:34:5 | h [element a] | provenance | |
|
||||
| hash_extensions.rb:34:18:34:28 | call to source | hash_extensions.rb:34:9:34:30 | call to [] [element a] | provenance | |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element a] | hash_extensions.rb:36:10:36:10 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element a] | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | provenance | |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | hash_extensions.rb:35:5:35:5 | x [element a] | provenance | |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element a] | hash_extensions.rb:36:10:36:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:42:5:42:5 | h [element :a] | hash_extensions.rb:43:9:43:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:42:9:42:26 | call to [] [element :a] | hash_extensions.rb:42:5:42:5 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:42:9:42:26 | call to [] [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element] | hash_extensions.rb:44:10:44:10 | x [element] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | hash_extensions.rb:43:5:43:5 | x [element] | provenance | |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element] | hash_extensions.rb:44:10:44:14 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element :a] | hash_extensions.rb:44:10:44:10 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | provenance | |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | hash_extensions.rb:43:5:43:5 | x [element :a] | provenance | |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element :a] | hash_extensions.rb:44:10:44:15 | ...[...] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :a] | hash_extensions.rb:51:9:51:9 | h [element :a] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :b] | hash_extensions.rb:51:9:51:9 | h [element :b] | provenance | |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :d] | hash_extensions.rb:51:9:51:9 | h [element :d] | provenance | |
|
||||
@@ -305,51 +305,51 @@ nodes
|
||||
| hash_extensions.rb:2:5:2:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:2:9:2:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:2:14:2:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:3:5:3:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:3:9:3:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] | semmle.label | call to stringify_keys [element] |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:4:10:4:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:10:9:10:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:10:14:10:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element] | semmle.label | call to to_options [element] |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element :a] | semmle.label | call to stringify_keys [element :a] |
|
||||
| hash_extensions.rb:4:10:4:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:4:10:4:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:10:5:10:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:10:9:10:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:10:18:10:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:11:5:11:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:11:9:11:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:11:9:11:20 | call to to_options [element a] | semmle.label | call to to_options [element a] |
|
||||
| hash_extensions.rb:12:10:12:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:18:9:18:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:18:14:18:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] | semmle.label | call to symbolize_keys [element] |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:18:5:18:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:18:9:18:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:18:18:18:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:19:5:19:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:19:9:19:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element a] | semmle.label | call to symbolize_keys [element a] |
|
||||
| hash_extensions.rb:20:10:20:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:26:5:26:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:26:9:26:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:26:14:26:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:27:5:27:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:27:9:27:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] | semmle.label | call to deep_stringify_keys [element] |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:28:10:28:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:34:9:34:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:34:14:34:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] | semmle.label | call to deep_symbolize_keys [element] |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element :a] | semmle.label | call to deep_stringify_keys [element :a] |
|
||||
| hash_extensions.rb:28:10:28:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:28:10:28:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:34:5:34:5 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:34:9:34:30 | call to [] [element a] | semmle.label | call to [] [element a] |
|
||||
| hash_extensions.rb:34:18:34:28 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:35:5:35:5 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:35:9:35:9 | h [element a] | semmle.label | h [element a] |
|
||||
| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element a] | semmle.label | call to deep_symbolize_keys [element a] |
|
||||
| hash_extensions.rb:36:10:36:10 | x [element a] | semmle.label | x [element a] |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:42:5:42:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:42:9:42:26 | call to [] [element :a] | semmle.label | call to [] [element :a] |
|
||||
| hash_extensions.rb:42:14:42:24 | call to source | semmle.label | call to source |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:43:5:43:5 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:43:9:43:9 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] | semmle.label | call to with_indifferent_access [element] |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element] | semmle.label | x [element] |
|
||||
| hash_extensions.rb:44:10:44:14 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element :a] | semmle.label | call to with_indifferent_access [element :a] |
|
||||
| hash_extensions.rb:44:10:44:10 | x [element :a] | semmle.label | x [element :a] |
|
||||
| hash_extensions.rb:44:10:44:15 | ...[...] | semmle.label | ...[...] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :a] | semmle.label | h [element :a] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :b] | semmle.label | h [element :b] |
|
||||
| hash_extensions.rb:50:5:50:5 | h [element :d] | semmle.label | h [element :d] |
|
||||
@@ -516,12 +516,12 @@ testFailures
|
||||
| active_support.rb:283:8:283:17 | call to presence | active_support.rb:282:7:282:16 | call to source | active_support.rb:283:8:283:17 | call to presence | $@ | active_support.rb:282:7:282:16 | call to source | call to source |
|
||||
| active_support.rb:286:8:286:17 | call to presence | active_support.rb:285:7:285:16 | call to source | active_support.rb:286:8:286:17 | call to presence | $@ | active_support.rb:285:7:285:16 | call to source | call to source |
|
||||
| active_support.rb:291:8:291:17 | call to deep_dup | active_support.rb:290:7:290:16 | call to source | active_support.rb:291:8:291:17 | call to deep_dup | $@ | active_support.rb:290:7:290:16 | call to source | call to source |
|
||||
| hash_extensions.rb:4:10:4:14 | ...[...] | hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:4:10:4:14 | ...[...] | $@ | hash_extensions.rb:2:14:2:24 | call to source | call to source |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | hash_extensions.rb:10:14:10:24 | call to source | hash_extensions.rb:12:10:12:14 | ...[...] | $@ | hash_extensions.rb:10:14:10:24 | call to source | call to source |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | hash_extensions.rb:18:14:18:24 | call to source | hash_extensions.rb:20:10:20:14 | ...[...] | $@ | hash_extensions.rb:18:14:18:24 | call to source | call to source |
|
||||
| hash_extensions.rb:28:10:28:14 | ...[...] | hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:28:10:28:14 | ...[...] | $@ | hash_extensions.rb:26:14:26:24 | call to source | call to source |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | hash_extensions.rb:34:14:34:24 | call to source | hash_extensions.rb:36:10:36:14 | ...[...] | $@ | hash_extensions.rb:34:14:34:24 | call to source | call to source |
|
||||
| hash_extensions.rb:44:10:44:14 | ...[...] | hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:44:10:44:14 | ...[...] | $@ | hash_extensions.rb:42:14:42:24 | call to source | call to source |
|
||||
| hash_extensions.rb:4:10:4:15 | ...[...] | hash_extensions.rb:2:14:2:24 | call to source | hash_extensions.rb:4:10:4:15 | ...[...] | $@ | hash_extensions.rb:2:14:2:24 | call to source | call to source |
|
||||
| hash_extensions.rb:12:10:12:14 | ...[...] | hash_extensions.rb:10:18:10:28 | call to source | hash_extensions.rb:12:10:12:14 | ...[...] | $@ | hash_extensions.rb:10:18:10:28 | call to source | call to source |
|
||||
| hash_extensions.rb:20:10:20:14 | ...[...] | hash_extensions.rb:18:18:18:28 | call to source | hash_extensions.rb:20:10:20:14 | ...[...] | $@ | hash_extensions.rb:18:18:18:28 | call to source | call to source |
|
||||
| hash_extensions.rb:28:10:28:15 | ...[...] | hash_extensions.rb:26:14:26:24 | call to source | hash_extensions.rb:28:10:28:15 | ...[...] | $@ | hash_extensions.rb:26:14:26:24 | call to source | call to source |
|
||||
| hash_extensions.rb:36:10:36:14 | ...[...] | hash_extensions.rb:34:18:34:28 | call to source | hash_extensions.rb:36:10:36:14 | ...[...] | $@ | hash_extensions.rb:34:18:34:28 | call to source | call to source |
|
||||
| hash_extensions.rb:44:10:44:15 | ...[...] | hash_extensions.rb:42:14:42:24 | call to source | hash_extensions.rb:44:10:44:15 | ...[...] | $@ | hash_extensions.rb:42:14:42:24 | call to source | call to source |
|
||||
| hash_extensions.rb:56:10:56:14 | ...[...] | hash_extensions.rb:50:52:50:61 | call to taint | hash_extensions.rb:56:10:56:14 | ...[...] | $@ | hash_extensions.rb:50:52:50:61 | call to taint | call to taint |
|
||||
| hash_extensions.rb:58:10:58:14 | ...[...] | hash_extensions.rb:50:14:50:23 | call to taint | hash_extensions.rb:58:10:58:14 | ...[...] | $@ | hash_extensions.rb:50:14:50:23 | call to taint | call to taint |
|
||||
| hash_extensions.rb:59:10:59:14 | ...[...] | hash_extensions.rb:50:29:50:38 | call to taint | hash_extensions.rb:59:10:59:14 | ...[...] | $@ | hash_extensions.rb:50:29:50:38 | call to taint | call to taint |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
def m_stringify_keys
|
||||
h = { a: source("a") }
|
||||
x = h.stringify_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_stringify_keys()
|
||||
|
||||
def m_to_options
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.to_options
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -15,7 +15,7 @@ end
|
||||
m_to_options()
|
||||
|
||||
def m_symbolize_keys
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.symbolize_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -25,13 +25,13 @@ m_symbolize_keys()
|
||||
def m_deep_stringify_keys
|
||||
h = { a: source("a") }
|
||||
x = h.deep_stringify_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_deep_stringify_keys()
|
||||
|
||||
def m_deep_symbolize_keys
|
||||
h = { a: source("a") }
|
||||
h = { "a" => source("a") }
|
||||
x = h.deep_symbolize_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
@@ -41,7 +41,7 @@ m_deep_symbolize_keys()
|
||||
def m_with_indifferent_access
|
||||
h = { a: source("a") }
|
||||
x = h.with_indifferent_access
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
sink x["a"] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
m_with_indifferent_access()
|
||||
|
||||
@@ -2,17 +2,17 @@ class TestContoller < ActionController::Base
|
||||
|
||||
# this is vulnerable
|
||||
def upload
|
||||
untar params[:file], params[:filename]
|
||||
untar params[:file], params[:filename] # $ Source=upload
|
||||
end
|
||||
|
||||
# this is vulnerable
|
||||
def unpload_zip
|
||||
unzip params[:file]
|
||||
unzip params[:file] # $ Source=upload_zip
|
||||
end
|
||||
|
||||
# this is vulnerable
|
||||
def create_new_zip
|
||||
zip params[:filename], files
|
||||
zip params[:filename], files # $ Source=create_new_zip
|
||||
end
|
||||
|
||||
# these are not vulnerable because of the string compare sanitizer
|
||||
@@ -56,7 +56,7 @@ class TestContoller < ActionController::Base
|
||||
else
|
||||
destination_directory = File.dirname(destination_file)
|
||||
FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory)
|
||||
File.open destination_file, "wb" do |f|
|
||||
File.open destination_file, "wb" do |f| # $ Alert=upload
|
||||
f.print tarfile.read
|
||||
end
|
||||
end
|
||||
@@ -65,7 +65,7 @@ class TestContoller < ActionController::Base
|
||||
end
|
||||
|
||||
def unzip(file)
|
||||
Zip::File.open(file) do |zip_file|
|
||||
Zip::File.open(file) do |zip_file| # $ Alert=upload_zip
|
||||
zip_file.each do |entry|
|
||||
entry.extract
|
||||
end
|
||||
@@ -73,7 +73,7 @@ class TestContoller < ActionController::Base
|
||||
end
|
||||
|
||||
def zip(filename, files = [])
|
||||
Zip::File.new(filename) do |zf|
|
||||
Zip::File.new(filename) do |zf| # $ Alert=create_new_zip
|
||||
files.each do |f|
|
||||
zf.add f
|
||||
end
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#select
|
||||
| ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value |
|
||||
| ArchiveApiPathTraversal.rb:68:20:68:23 | file | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | ArchiveApiPathTraversal.rb:68:20:68:23 | file | This path depends on a $@. | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | user-provided value |
|
||||
| ArchiveApiPathTraversal.rb:76:19:76:26 | filename | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | This path depends on a $@. | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | user-provided value |
|
||||
| tainted_path.rb:5:26:5:29 | path | tainted_path.rb:4:12:4:17 | call to params | tainted_path.rb:5:26:5:29 | path | This path depends on a $@. | tainted_path.rb:4:12:4:17 | call to params | user-provided value |
|
||||
| tainted_path.rb:11:26:11:29 | path | tainted_path.rb:10:31:10:36 | call to params | tainted_path.rb:11:26:11:29 | path | This path depends on a $@. | tainted_path.rb:10:31:10:36 | call to params | user-provided value |
|
||||
| tainted_path.rb:17:26:17:29 | path | tainted_path.rb:16:28:16:33 | call to params | tainted_path.rb:17:26:17:29 | path | This path depends on a $@. | tainted_path.rb:16:28:16:33 | call to params | user-provided value |
|
||||
| tainted_path.rb:23:26:23:29 | path | tainted_path.rb:22:29:22:34 | call to params | tainted_path.rb:23:26:23:29 | path | This path depends on a $@. | tainted_path.rb:22:29:22:34 | call to params | user-provided value |
|
||||
| tainted_path.rb:29:26:29:29 | path | tainted_path.rb:28:22:28:27 | call to params | tainted_path.rb:29:26:29:29 | path | This path depends on a $@. | tainted_path.rb:28:22:28:27 | call to params | user-provided value |
|
||||
| tainted_path.rb:35:26:35:29 | path | tainted_path.rb:34:29:34:34 | call to params | tainted_path.rb:35:26:35:29 | path | This path depends on a $@. | tainted_path.rb:34:29:34:34 | call to params | user-provided value |
|
||||
| tainted_path.rb:41:26:41:29 | path | tainted_path.rb:40:26:40:31 | call to params | tainted_path.rb:41:26:41:29 | path | This path depends on a $@. | tainted_path.rb:40:26:40:31 | call to params | user-provided value |
|
||||
| tainted_path.rb:48:26:48:29 | path | tainted_path.rb:47:43:47:48 | call to params | tainted_path.rb:48:26:48:29 | path | This path depends on a $@. | tainted_path.rb:47:43:47:48 | call to params | user-provided value |
|
||||
| tainted_path.rb:60:26:60:29 | path | tainted_path.rb:59:40:59:45 | call to params | tainted_path.rb:60:26:60:29 | path | This path depends on a $@. | tainted_path.rb:59:40:59:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:78:19:78:22 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:78:19:78:22 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:92:11:92:14 | path | tainted_path.rb:90:40:90:45 | call to params | tainted_path.rb:92:11:92:14 | path | This path depends on a $@. | tainted_path.rb:90:40:90:45 | call to params | user-provided value |
|
||||
edges
|
||||
| ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] | provenance | |
|
||||
| ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] | ArchiveApiPathTraversal.rb:49:17:49:27 | destination | provenance | |
|
||||
@@ -152,22 +171,3 @@ nodes
|
||||
| tainted_path.rb:90:40:90:52 | ...[...] | semmle.label | ...[...] |
|
||||
| tainted_path.rb:92:11:92:14 | path | semmle.label | path |
|
||||
subpaths
|
||||
#select
|
||||
| ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value |
|
||||
| ArchiveApiPathTraversal.rb:68:20:68:23 | file | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | ArchiveApiPathTraversal.rb:68:20:68:23 | file | This path depends on a $@. | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | user-provided value |
|
||||
| ArchiveApiPathTraversal.rb:76:19:76:26 | filename | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | This path depends on a $@. | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | user-provided value |
|
||||
| tainted_path.rb:5:26:5:29 | path | tainted_path.rb:4:12:4:17 | call to params | tainted_path.rb:5:26:5:29 | path | This path depends on a $@. | tainted_path.rb:4:12:4:17 | call to params | user-provided value |
|
||||
| tainted_path.rb:11:26:11:29 | path | tainted_path.rb:10:31:10:36 | call to params | tainted_path.rb:11:26:11:29 | path | This path depends on a $@. | tainted_path.rb:10:31:10:36 | call to params | user-provided value |
|
||||
| tainted_path.rb:17:26:17:29 | path | tainted_path.rb:16:28:16:33 | call to params | tainted_path.rb:17:26:17:29 | path | This path depends on a $@. | tainted_path.rb:16:28:16:33 | call to params | user-provided value |
|
||||
| tainted_path.rb:23:26:23:29 | path | tainted_path.rb:22:29:22:34 | call to params | tainted_path.rb:23:26:23:29 | path | This path depends on a $@. | tainted_path.rb:22:29:22:34 | call to params | user-provided value |
|
||||
| tainted_path.rb:29:26:29:29 | path | tainted_path.rb:28:22:28:27 | call to params | tainted_path.rb:29:26:29:29 | path | This path depends on a $@. | tainted_path.rb:28:22:28:27 | call to params | user-provided value |
|
||||
| tainted_path.rb:35:26:35:29 | path | tainted_path.rb:34:29:34:34 | call to params | tainted_path.rb:35:26:35:29 | path | This path depends on a $@. | tainted_path.rb:34:29:34:34 | call to params | user-provided value |
|
||||
| tainted_path.rb:41:26:41:29 | path | tainted_path.rb:40:26:40:31 | call to params | tainted_path.rb:41:26:41:29 | path | This path depends on a $@. | tainted_path.rb:40:26:40:31 | call to params | user-provided value |
|
||||
| tainted_path.rb:48:26:48:29 | path | tainted_path.rb:47:43:47:48 | call to params | tainted_path.rb:48:26:48:29 | path | This path depends on a $@. | tainted_path.rb:47:43:47:48 | call to params | user-provided value |
|
||||
| tainted_path.rb:60:26:60:29 | path | tainted_path.rb:59:40:59:45 | call to params | tainted_path.rb:60:26:60:29 | path | This path depends on a $@. | tainted_path.rb:59:40:59:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:78:19:78:22 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:78:19:78:22 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
|
||||
| tainted_path.rb:92:11:92:14 | path | tainted_path.rb:90:40:90:45 | call to params | tainted_path.rb:92:11:92:14 | path | This path depends on a $@. | tainted_path.rb:90:40:90:45 | call to params | user-provided value |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/security/cwe-022/PathInjection.ql
|
||||
query: queries/security/cwe-022/PathInjection.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
class FooController < ActionController::Base
|
||||
# BAD
|
||||
def route0
|
||||
path = params[:path]
|
||||
@content = File.read path
|
||||
path = params[:path] # $ Source=path1
|
||||
@content = File.read path # $ Alert=path1
|
||||
end
|
||||
|
||||
# BAD - File.absolute_path preserves taint
|
||||
def route1
|
||||
path = File.absolute_path params[:path]
|
||||
@content = File.read path
|
||||
path = File.absolute_path params[:path] # $ Source=path2
|
||||
@content = File.read path # $ Alert=path2
|
||||
end
|
||||
|
||||
# BAD - File.dirname preserves taint
|
||||
def route2
|
||||
path = "#{File.dirname(params[:path])}/foo"
|
||||
@content = File.read path
|
||||
path = "#{File.dirname(params[:path])}/foo" # $ Source=path3
|
||||
@content = File.read path # $ Alert=path3
|
||||
end
|
||||
|
||||
# BAD - File.expand_path preserves taint
|
||||
def route3
|
||||
path = File.expand_path params[:path]
|
||||
@content = File.read path
|
||||
path = File.expand_path params[:path] # $ Source=path4
|
||||
@content = File.read path # $ Alert=path4
|
||||
end
|
||||
|
||||
# BAD - File.path preserves taint
|
||||
def route4
|
||||
path = File.path params[:path]
|
||||
@content = File.read path
|
||||
path = File.path params[:path] # $ Source=path5
|
||||
@content = File.read path # $ Alert=path5
|
||||
end
|
||||
|
||||
# BAD - File.realdirpath preserves taint
|
||||
def route5
|
||||
path = File.realdirpath params[:path]
|
||||
@content = File.read path
|
||||
path = File.realdirpath params[:path] # $ Source=path6
|
||||
@content = File.read path # $ Alert=path6
|
||||
end
|
||||
|
||||
# BAD - File.realpath preserves taint
|
||||
def route6
|
||||
path = File.realpath params[:path]
|
||||
@content = File.read path
|
||||
path = File.realpath params[:path] # $ Source=path7
|
||||
@content = File.read path # $ Alert=path7
|
||||
end
|
||||
|
||||
# BAD - tainted arguments in any position propagate to the return value of
|
||||
# File.join
|
||||
def route7
|
||||
path = File.join("foo", "bar", "baz", params[:path], "qux")
|
||||
@content = File.read path
|
||||
path = File.join("foo", "bar", "baz", params[:path], "qux") # $ Source=path8
|
||||
@content = File.read path # $ Alert=path8
|
||||
end
|
||||
|
||||
# GOOD - File.basename does not preserve taint
|
||||
@@ -56,8 +56,8 @@ class FooController < ActionController::Base
|
||||
|
||||
# BAD
|
||||
def route9
|
||||
path = ActiveStorage::Filename.new(params[:path])
|
||||
@content = File.read path
|
||||
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path9
|
||||
@content = File.read path # $ Alert=path9
|
||||
end
|
||||
|
||||
# GOOD - explicitly sanitized
|
||||
@@ -68,27 +68,27 @@ class FooController < ActionController::Base
|
||||
|
||||
# BAD
|
||||
def route11
|
||||
path = ActiveStorage::Filename.new(params[:path])
|
||||
send_file path
|
||||
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path10
|
||||
send_file path # $ Alert=path10
|
||||
end
|
||||
|
||||
# BAD
|
||||
def route12
|
||||
path = ActiveStorage::Filename.new(params[:path])
|
||||
bla (Dir.glob path)
|
||||
bla (Dir[path])
|
||||
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path11
|
||||
bla (Dir.glob path) # $ Alert=path11
|
||||
bla (Dir[path]) # $ Alert=path11
|
||||
end
|
||||
|
||||
# BAD
|
||||
def route13
|
||||
path = ActiveStorage::Filename.new(params[:path])
|
||||
load(path)
|
||||
autoload(:MyModule, path)
|
||||
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path12
|
||||
load(path) # $ Alert=path12
|
||||
autoload(:MyModule, path) # $ Alert=path12
|
||||
end
|
||||
|
||||
def require_relative()
|
||||
path = ActiveStorage::Filename.new(params[:path])
|
||||
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path13
|
||||
puts "Debug: require_relative(#{path})"
|
||||
super(path)
|
||||
super(path) # $ Alert=path13
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use anyhow::Context;
|
||||
use archive::Archiver;
|
||||
use log::info;
|
||||
use ra_ap_hir::Semantics;
|
||||
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
|
||||
use ra_ap_project_model::ProjectManifest;
|
||||
use rust_analyzer::{ParseResult, RustAnalyzer};
|
||||
@@ -17,7 +18,7 @@ mod translate;
|
||||
pub mod trap;
|
||||
|
||||
fn extract(
|
||||
rust_analyzer: &mut rust_analyzer::RustAnalyzer,
|
||||
rust_analyzer: &rust_analyzer::RustAnalyzer,
|
||||
archiver: &Archiver,
|
||||
traps: &trap::TrapFileProvider,
|
||||
file: &std::path::Path,
|
||||
@@ -29,15 +30,10 @@ fn extract(
|
||||
text,
|
||||
errors,
|
||||
file_id,
|
||||
semantics,
|
||||
} = rust_analyzer.parse(file);
|
||||
let line_index = LineIndex::new(text.as_ref());
|
||||
let display_path = file.to_string_lossy();
|
||||
let mut trap = traps.create("source", file);
|
||||
trap.writer.comment(format!(
|
||||
"semantics: {}",
|
||||
if semantics.is_some() { "yes" } else { "no" }
|
||||
));
|
||||
let label = trap.emit_file(file);
|
||||
let mut translator = translate::Translator::new(
|
||||
trap,
|
||||
@@ -45,7 +41,7 @@ fn extract(
|
||||
label,
|
||||
line_index,
|
||||
file_id,
|
||||
semantics,
|
||||
file_id.and(rust_analyzer.semantics()),
|
||||
);
|
||||
|
||||
for err in errors {
|
||||
@@ -116,14 +112,20 @@ fn main() -> anyhow::Result<()> {
|
||||
if files.is_empty() {
|
||||
break;
|
||||
}
|
||||
let mut rust_analyzer = RustAnalyzer::new(manifest, &cfg.scratch_dir);
|
||||
for file in files {
|
||||
extract(&mut rust_analyzer, &archiver, &traps, file);
|
||||
if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cfg.scratch_dir) {
|
||||
let semantics = Semantics::new(db);
|
||||
let rust_analyzer = RustAnalyzer::new(vfs, semantics);
|
||||
for file in files {
|
||||
extract(&rust_analyzer, &archiver, &traps, file);
|
||||
}
|
||||
} else {
|
||||
for file in files {
|
||||
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut rust_analyzer = RustAnalyzer::WithoutDatabase();
|
||||
for file in other_files {
|
||||
extract(&mut rust_analyzer, &archiver, &traps, file);
|
||||
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use itertools::Itertools;
|
||||
use log::{debug, info};
|
||||
use ra_ap_base_db::SourceDatabase;
|
||||
use ra_ap_base_db::SourceDatabaseFileInputExt;
|
||||
use ra_ap_hir::Semantics;
|
||||
use ra_ap_ide_db::RootDatabase;
|
||||
use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
|
||||
@@ -21,19 +20,24 @@ use ra_ap_vfs::VfsPath;
|
||||
use std::borrow::Cow;
|
||||
use std::path::{Path, PathBuf};
|
||||
use triomphe::Arc;
|
||||
pub enum RustAnalyzer {
|
||||
WithDatabase { db: RootDatabase, vfs: Vfs },
|
||||
WithoutDatabase(),
|
||||
pub enum RustAnalyzer<'a> {
|
||||
WithSemantics {
|
||||
vfs: &'a Vfs,
|
||||
semantics: Semantics<'a, RootDatabase>,
|
||||
},
|
||||
WithoutSemantics,
|
||||
}
|
||||
pub struct ParseResult<'a> {
|
||||
pub struct ParseResult {
|
||||
pub ast: SourceFile,
|
||||
pub text: Arc<str>,
|
||||
pub errors: Vec<SyntaxError>,
|
||||
pub file_id: Option<EditionedFileId>,
|
||||
pub semantics: Option<Semantics<'a, RootDatabase>>,
|
||||
}
|
||||
impl RustAnalyzer {
|
||||
pub fn new(project: &ProjectManifest, scratch_dir: &Path) -> Self {
|
||||
impl<'a> RustAnalyzer<'a> {
|
||||
pub fn load_workspace(
|
||||
project: &ProjectManifest,
|
||||
scratch_dir: &Path,
|
||||
) -> Option<(RootDatabase, Vfs)> {
|
||||
let config = CargoConfig {
|
||||
sysroot: Some(RustLibSource::Discover),
|
||||
target_dir: ra_ap_paths::Utf8PathBuf::from_path_buf(scratch_dir.to_path_buf())
|
||||
@@ -50,14 +54,55 @@ impl RustAnalyzer {
|
||||
let manifest = project.manifest_path();
|
||||
|
||||
match load_workspace_at(manifest.as_ref(), &config, &load_config, &progress) {
|
||||
Ok((db, vfs, _macro_server)) => RustAnalyzer::WithDatabase { db, vfs },
|
||||
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
|
||||
Err(err) => {
|
||||
log::error!("failed to load workspace for {}: {}", manifest, err);
|
||||
RustAnalyzer::WithoutDatabase()
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn parse(&mut self, path: &Path) -> ParseResult<'_> {
|
||||
pub fn new(vfs: &'a Vfs, semantics: Semantics<'a, RootDatabase>) -> Self {
|
||||
RustAnalyzer::WithSemantics { vfs, semantics }
|
||||
}
|
||||
pub fn semantics(&'a self) -> Option<&'a Semantics<'a, RootDatabase>> {
|
||||
match self {
|
||||
RustAnalyzer::WithSemantics { vfs: _, semantics } => Some(semantics),
|
||||
RustAnalyzer::WithoutSemantics => None,
|
||||
}
|
||||
}
|
||||
pub fn parse(&self, path: &Path) -> ParseResult {
|
||||
if let RustAnalyzer::WithSemantics { vfs, semantics } = self {
|
||||
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
|
||||
.ok()
|
||||
.and_then(|x| AbsPathBuf::try_from(x).ok())
|
||||
.map(VfsPath::from)
|
||||
.and_then(|x| vfs.file_id(&x))
|
||||
{
|
||||
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id)) {
|
||||
let file_id = EditionedFileId::current_edition(file_id);
|
||||
let source_file = semantics.parse(file_id);
|
||||
let errors = semantics
|
||||
.db
|
||||
.parse_errors(file_id)
|
||||
.into_iter()
|
||||
.flat_map(|x| x.to_vec())
|
||||
.collect();
|
||||
|
||||
return ParseResult {
|
||||
ast: source_file,
|
||||
text: input,
|
||||
errors,
|
||||
file_id: Some(file_id),
|
||||
};
|
||||
} else {
|
||||
log::debug!(
|
||||
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
|
||||
file_id,
|
||||
path.to_string_lossy()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut errors = Vec::new();
|
||||
let input = match std::fs::read(path) {
|
||||
Ok(data) => data,
|
||||
@@ -71,32 +116,6 @@ impl RustAnalyzer {
|
||||
};
|
||||
let (input, err) = from_utf8_lossy(&input);
|
||||
|
||||
if let RustAnalyzer::WithDatabase { vfs, db } = self {
|
||||
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
|
||||
.ok()
|
||||
.and_then(|x| AbsPathBuf::try_from(x).ok())
|
||||
.map(VfsPath::from)
|
||||
.and_then(|x| vfs.file_id(&x))
|
||||
{
|
||||
db.set_file_text(file_id, &input);
|
||||
let semantics = Semantics::new(db);
|
||||
|
||||
let file_id = EditionedFileId::current_edition(file_id);
|
||||
let source_file = semantics.parse(file_id);
|
||||
errors.extend(
|
||||
db.parse_errors(file_id)
|
||||
.into_iter()
|
||||
.flat_map(|x| x.to_vec()),
|
||||
);
|
||||
return ParseResult {
|
||||
ast: source_file,
|
||||
text: input.as_ref().into(),
|
||||
errors,
|
||||
file_id: Some(file_id),
|
||||
semantics: Some(semantics),
|
||||
};
|
||||
}
|
||||
}
|
||||
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
|
||||
errors.extend(parse.errors());
|
||||
errors.extend(err);
|
||||
@@ -105,7 +124,6 @@ impl RustAnalyzer {
|
||||
text: input.as_ref().into(),
|
||||
errors,
|
||||
file_id: None,
|
||||
semantics: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ pub struct Translator<'a> {
|
||||
label: trap::Label,
|
||||
line_index: LineIndex,
|
||||
file_id: Option<EditionedFileId>,
|
||||
pub semantics: Option<Semantics<'a, RootDatabase>>,
|
||||
pub semantics: Option<&'a Semantics<'a, RootDatabase>>,
|
||||
}
|
||||
|
||||
impl<'a> Translator<'a> {
|
||||
@@ -65,7 +65,7 @@ impl<'a> Translator<'a> {
|
||||
label: trap::Label,
|
||||
line_index: LineIndex,
|
||||
file_id: Option<EditionedFileId>,
|
||||
semantics: Option<Semantics<'a, RootDatabase>>,
|
||||
semantics: Option<&'a Semantics<'a, RootDatabase>>,
|
||||
) -> Translator<'a> {
|
||||
Translator {
|
||||
trap,
|
||||
|
||||
9
rust/ql/consistency-queries/DataFlowConsistency.ql
Normal file
9
rust/ql/consistency-queries/DataFlowConsistency.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
|
||||
private import rust
|
||||
private import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
private import codeql.rust.dataflow.internal.TaintTrackingImpl
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
|
||||
private module Input implements InputSig<Location, RustDataFlow> { }
|
||||
|
||||
import MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>
|
||||
@@ -26,21 +26,29 @@ module Impl {
|
||||
result = getImmediateParent(e)
|
||||
}
|
||||
|
||||
/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
|
||||
private AstNode getParentOfAst(AstNode ast) {
|
||||
result = getParentOfAstStep*(getImmediateParent(ast))
|
||||
}
|
||||
|
||||
class AstNode extends Generated::AstNode {
|
||||
/**
|
||||
* Gets the nearest enclosing parent of this node, which is also an `AstNode`,
|
||||
* if any.
|
||||
*/
|
||||
AstNode getParentNode() { result = getParentOfAstStep*(getImmediateParent(this)) }
|
||||
|
||||
/** Gets the immediately enclosing callable of this node, if any. */
|
||||
cached
|
||||
Callable getEnclosingCallable() {
|
||||
exists(AstNode p | p = getParentOfAst(this) |
|
||||
exists(AstNode p | p = this.getParentNode() |
|
||||
result = p
|
||||
or
|
||||
not p instanceof Callable and
|
||||
result = p.getEnclosingCallable()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this node is inside a macro expansion. */
|
||||
predicate isInMacroExpansion() {
|
||||
this = any(MacroCall mc).getExpanded()
|
||||
or
|
||||
this.getParentNode().isInMacroExpansion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ predicate hiddenNode(AstNode n) {
|
||||
not succ(n, _) and
|
||||
not succ(_, n)
|
||||
or
|
||||
n instanceof ControlFlowGraphImpl::PostOrderTree // location is counter-intuitive
|
||||
n instanceof ControlFlowGraphImpl::PostOrderTree and // location is counter-intuitive
|
||||
not n instanceof MacroExpr
|
||||
or
|
||||
n.isInMacroExpansion()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,5 +20,6 @@ where
|
||||
not write = any(Ssa::WriteDefinition def).getWriteAccess().getAstNode() and
|
||||
// avoid overlap with the unused variable query
|
||||
not isUnused(v) and
|
||||
not v instanceof DiscardVariable
|
||||
select write, "Variable is assigned a value that is never used."
|
||||
not v instanceof DiscardVariable and
|
||||
not write.isInMacroExpansion()
|
||||
select write, "Variable $@ is assigned a value that is never used.", v, v.getName()
|
||||
|
||||
@@ -13,4 +13,4 @@ import UnusedVariable
|
||||
|
||||
from Variable v
|
||||
where isUnused(v)
|
||||
select v, "Variable is not used."
|
||||
select v, "Variable '" + v + "' is not used."
|
||||
|
||||
@@ -10,5 +10,6 @@ predicate isUnused(Variable v) {
|
||||
not exists(v.getAnAccess()) and
|
||||
not exists(v.getInitializer()) and
|
||||
not v instanceof DiscardVariable and
|
||||
not v.getPat().isInMacroExpansion() and
|
||||
exists(File f | f.getBaseName() = "main.rs" | v.getLocation().getFile() = f) // temporarily severely limit results
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_abi.rs:5:5:5:11 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -0,0 +1,2 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_arg_list.rs:5:5:5:11 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -0,0 +1,2 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_array_type.rs:5:5:5:11 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user