Merge branch 'main' into js/hana_db_client

This commit is contained in:
Napalys Klicius
2025-03-28 13:21:15 +01:00
committed by GitHub
251 changed files with 17272 additions and 4546 deletions

View File

@@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-13, windows-2019]
os: [ubuntu-22.04, macos-13, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

22
.github/workflows/go-tests-rtjo.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: "Go: Run RTJO Tests"
on:
pull_request:
types:
- labeled
permissions:
contents: read
jobs:
test-linux:
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
name: RTJO Test Linux (Ubuntu)
runs-on: ubuntu-latest-xl
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test
with:
run-code-checks: true
dynamic-join-order-mode: all

40
.github/workflows/ruby-qltest-rtjo.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: "Ruby: Run RTJO Language Tests"
on:
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: ruby
permissions:
contents: read
jobs:
qltest-rtjo:
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
runs-on: ubuntu-latest-xl
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -0,0 +1,5 @@
---
category: fix
---
* The query `actions/code-injection/medium` now produces alerts for injection
vulnerabilities on `pull_request` events.

View File

@@ -30,6 +30,9 @@ extensions:
- ["pull_request_review_comment", "github.event.review"]
- ["pull_request_review_comment", "github.head_ref"]
- ["pull_request_review_comment", "github.event.changes"]
- ["pull_request", "github.event.pull_request"]
- ["pull_request", "github.head_ref"]
- ["pull_request", "github.event.changes"]
- ["pull_request_target", "github.event.pull_request"]
- ["pull_request_target", "github.head_ref"]
- ["pull_request_target", "github.event.changes"]

View File

@@ -12,6 +12,7 @@ extensions:
- ["pull_request_comment"]
- ["pull_request_review"]
- ["pull_request_review_comment"]
- ["pull_request"]
- ["pull_request_target"]
- ["workflow_run"] # depending on branch filter
- ["workflow_call"] # depending on caller

View File

@@ -400,6 +400,7 @@ nodes
| .github/workflows/level0.yml:44:20:44:49 | github.event.issue.body | semmle.label | github.event.issue.body |
| .github/workflows/level0.yml:69:35:69:66 | github.event.comment.body | semmle.label | github.event.comment.body |
| .github/workflows/level1.yml:37:38:37:81 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | semmle.label | github.event.pull_request.body |
| .github/workflows/pull_request_review.yml:7:19:7:56 | github.event.pull_request.title | semmle.label | github.event.pull_request.title |
| .github/workflows/pull_request_review.yml:8:19:8:55 | github.event.pull_request.body | semmle.label | github.event.pull_request.body |
| .github/workflows/pull_request_review.yml:9:19:9:61 | github.event.pull_request.head.label | semmle.label | github.event.pull_request.head.label |
@@ -629,6 +630,7 @@ nodes
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title |
| .github/workflows/test20.yml:15:54:15:94 | github.event.pull_request.head.ref | semmle.label | github.event.pull_request.head.ref |
| .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |

View File

@@ -400,6 +400,7 @@ nodes
| .github/workflows/level0.yml:44:20:44:49 | github.event.issue.body | semmle.label | github.event.issue.body |
| .github/workflows/level0.yml:69:35:69:66 | github.event.comment.body | semmle.label | github.event.comment.body |
| .github/workflows/level1.yml:37:38:37:81 | github.event.workflow_run.head_branch | semmle.label | github.event.workflow_run.head_branch |
| .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | semmle.label | github.event.pull_request.body |
| .github/workflows/pull_request_review.yml:7:19:7:56 | github.event.pull_request.title | semmle.label | github.event.pull_request.title |
| .github/workflows/pull_request_review.yml:8:19:8:55 | github.event.pull_request.body | semmle.label | github.event.pull_request.body |
| .github/workflows/pull_request_review.yml:9:19:9:61 | github.event.pull_request.head.label | semmle.label | github.event.pull_request.head.label |
@@ -629,6 +630,7 @@ nodes
| .github/workflows/test19.yml:124:9:129:6 | Run Step: title3 [title] | semmle.label | Run Step: title3 [title] |
| .github/workflows/test19.yml:125:14:128:50 | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n | semmle.label | TITLE=$(gh issue view "$ISSUE_NUMBER" --json title,author)\nTITLE=$(echo $TITLE \| jq -r '.title')\necho "title=$TITLE" >> "$GITHUB_OUTPUT"\n |
| .github/workflows/test19.yml:129:21:129:52 | steps.title3.outputs.title | semmle.label | steps.title3.outputs.title |
| .github/workflows/test20.yml:15:54:15:94 | github.event.pull_request.head.ref | semmle.label | github.event.pull_request.head.ref |
| .github/workflows/test21.yml:22:35:22:73 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:23:36:23:74 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
| .github/workflows/test21.yml:24:50:24:88 | github.event.head_commit.message | semmle.label | github.event.head_commit.message |
@@ -706,6 +708,7 @@ subpaths
| .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | .github/workflows/inter-job2.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job2.yml:45:20:45:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} |
| .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | .github/workflows/inter-job4.yml:22:9:26:6 | Uses Step: source | .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job4.yml:44:20:44:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} |
| .github/workflows/inter-job5.yml:45:20:45:53 | needs.job1.outputs.job_output | .github/workflows/inter-job5.yml:45:20:45:53 | needs.job1.outputs.job_output | .github/workflows/inter-job5.yml:45:20:45:53 | needs.job1.outputs.job_output | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/inter-job5.yml:45:20:45:53 | needs.job1.outputs.job_output | ${{needs.job1.outputs.job_output}} |
| .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/priv_pull_request.yml:14:21:14:57 | github.event.pull_request.body | ${{ github.event.pull_request.body }} |
| .github/workflows/push.yml:7:19:7:57 | github.event.commits[11].message | .github/workflows/push.yml:7:19:7:57 | github.event.commits[11].message | .github/workflows/push.yml:7:19:7:57 | github.event.commits[11].message | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:7:19:7:57 | github.event.commits[11].message | ${{ github.event.commits[11].message }} |
| .github/workflows/push.yml:8:19:8:62 | github.event.commits[11].author.email | .github/workflows/push.yml:8:19:8:62 | github.event.commits[11].author.email | .github/workflows/push.yml:8:19:8:62 | github.event.commits[11].author.email | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:8:19:8:62 | github.event.commits[11].author.email | ${{ github.event.commits[11].author.email }} |
| .github/workflows/push.yml:9:19:9:61 | github.event.commits[11].author.name | .github/workflows/push.yml:9:19:9:61 | github.event.commits[11].author.name | .github/workflows/push.yml:9:19:9:61 | github.event.commits[11].author.name | Potential code injection in $@, which may be controlled by an external user. | .github/workflows/push.yml:9:19:9:61 | github.event.commits[11].author.name | ${{ github.event.commits[11].author.name }} |

View File

@@ -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>;

View File

@@ -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()

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 | | | |

View File

@@ -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";
}

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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";
}
}

View File

@@ -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)
{

View File

@@ -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))}");

View File

@@ -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();

View File

@@ -4,7 +4,7 @@ source https://api.nuget.org/v3/index.json
# behave like nuget in choosing transitive dependency versions
strategy: max
nuget Basic.CompilerLog.Util
nuget Basic.CompilerLog.Util 0.9.8
nuget Mono.Posix.NETStandard
nuget Newtonsoft.Json
nuget xunit

12
csharp/paket.lock generated
View File

@@ -3,12 +3,12 @@ STRATEGY: MAX
RESTRICTION: == net9.0
NUGET
remote: https://api.nuget.org/v3/index.json
Basic.CompilerLog.Util (0.9.4)
Basic.CompilerLog.Util (0.9.8)
MessagePack (>= 2.5.187)
Microsoft.CodeAnalysis (>= 4.11)
Microsoft.CodeAnalysis.CSharp (>= 4.11)
Microsoft.CodeAnalysis.VisualBasic (>= 4.11)
Microsoft.Extensions.ObjectPool (>= 9.0)
Microsoft.CodeAnalysis (>= 4.12)
Microsoft.CodeAnalysis.CSharp (>= 4.12)
Microsoft.CodeAnalysis.VisualBasic (>= 4.12)
Microsoft.Extensions.ObjectPool (>= 9.0.2)
MSBuild.StructuredLogger (>= 2.2.243)
System.Buffers (>= 4.6)
Humanizer.Core (2.14.1)
@@ -96,7 +96,7 @@ NUGET
System.Reflection.Metadata (>= 8.0)
System.Threading.Channels (>= 7.0)
Microsoft.CodeCoverage (17.12)
Microsoft.Extensions.ObjectPool (9.0)
Microsoft.Extensions.ObjectPool (9.0.3)
Microsoft.NET.StringTools (17.12.6)
Microsoft.NET.Test.Sdk (17.12)
Microsoft.CodeCoverage (>= 17.12)

4
csharp/paket.main.bzl generated

File diff suppressed because one or more lines are too long

View File

@@ -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() }

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 }
}

View File

@@ -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

View File

@@ -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(_)
}

View File

@@ -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) |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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;
}
}

View File

@@ -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]**.

View File

@@ -30,6 +30,8 @@ The following properties are supported by all query files:
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@id`` | ``<text>`` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard CodeQL queries have the following format: ``<language>/<brief-description>``. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@previous-id`` | ``<text>`` | Indicates that query results were previously reported on a different query. The previous id should be a sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the previous query. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``) or a path (``@kind path-problem``). For more information on these query types, see ":doc:`About CodeQL queries <about-codeql-queries>`." |
| | | ``path-problem`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

View File

@@ -93,6 +93,10 @@ Note, `@id` properties should be consistent for queries that highlight the same
* `@id java/tainted-format-string`
* `@id cpp/tainted-format-string`
#### Query previous ID `@previous-id`
Queries with alerts that used to be reported on a different query should also have an `@previous-id` property to refer back to the query where the alerts were originally reported. For example, if alerts from `java/query-one` are now reported on `java/query-two`, then the metadata for `java/query-two` should contain: `@previous-id java/query-one`.
### Query type `@kind`
@@ -113,7 +117,7 @@ Alert queries (`@kind problem` or `path-problem`) support two further properties
* `medium`
* `high`
* `very-high`
* `@problem.severity`defines the likelihood that an alert, either security-related or not, causes an actual problem such as incorrect program behavior:
* `@problem.severity`defines the likelihood that an alert, either security-related or not, causes an actual problem such as incorrect program behavior:
* `error`an issue that is likely to cause incorrect program behavior, for example a crash or vulnerability.
* `warning`an issue that indicates a potential problem in the code, or makes the code fragile if another (unrelated) part of code is changed.
* `recommendation`an issue where the code behaves correctly, but it could be improved.

View File

@@ -52,9 +52,9 @@ ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor
codeql dataset measure -o $@ build/stats/database/db-go
test: all build/testdb/check-upgrade-path
codeql test run -j0 ql/test --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache)
codeql test run -j0 ql/test --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache) --dynamic-join-order-mode=$(rtjo)
# use GOOS=linux because GOOS=darwin GOARCH=386 is no longer supported
env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache)
env GOOS=linux GOARCH=386 codeql$(EXE) test run -j0 ql/test/query-tests/Security/CWE-681 --search-path .. --consistency-queries ql/test/consistency --compilation-cache=$(cache) --dynamic-join-order-mode=$(rtjo)
cd extractor; $(BAZEL) test ...
bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1)

View File

@@ -9,6 +9,10 @@ inputs:
description: Whether to run formatting, code and qhelp generation checks
required: false
default: false
dynamic-join-order-mode:
description: Value of the --dynamic-join-order-mode flag to pass to the codeql test command
required: false
default: "none"
runs:
using: composite
steps:
@@ -74,4 +78,4 @@ runs:
shell: bash
run: |
cd go
make test cache="${{ steps.query-cache.outputs.cache-dir }}"
make test cache="${{ steps.query-cache.outputs.cache-dir }}" rtjo=${{ inputs.dynamic-join-order-mode }}

View File

@@ -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,,,,,,,,
@@ -33,8 +33,8 @@ github.com/beego/beego,142,68,42,,,,68,,10,,,,,,60,4,,,,,26,,,42,,42,
github.com/caarlos0/env,,5,2,,,,,,,,,,,,,,,,,,,5,,,,1,1
github.com/clevergo/clevergo,1,,,,,,,,,,,,,,,,,1,,,,,,,,,
github.com/codeskyblue/go-sh,4,,,4,,,,,,,,,,,,,,,,,,,,,,,
github.com/couchbase/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,,,18,
github.com/couchbaselabs/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,,,18,
github.com/couchbase/gocb,8,22,48,,,,,8,,,,,,,,,,,,,22,,,,,48,
github.com/couchbaselabs/gocb,8,22,48,,,,,8,,,,,,,,,,,,,22,,,,,48,
github.com/crankycoder/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
github.com/cristalhq/jwt,1,,,,1,,,,,,,,,,,,,,,,,,,,,,
github.com/davecgh/go-spew/spew,9,,,,,,9,,,,,,,,,,,,,,,,,,,,
@@ -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,8 +106,8 @@ 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/couchbase/gocb,8,,18,,,,,8,,,,,,,,,,,,,,,,,,18,
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,
gopkg.in/go-xmlpath/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
21 expvar 6 6
22 fmt 3 16 3 16
23 github.com/ChrisTrenkamp/goxpath 3 3
24 github.com/Masterminds/squirrel 32 27 32 27
25 github.com/Sirupsen/logrus 145 145
26 github.com/antchfx/htmlquery 4 4
27 github.com/antchfx/jsonquery 4 4
33 github.com/caarlos0/env 5 2 5 1 1
34 github.com/clevergo/clevergo 1 1
35 github.com/codeskyblue/go-sh 4 4
36 github.com/couchbase/gocb 8 22 18 48 8 22 18 48
37 github.com/couchbaselabs/gocb 8 22 18 48 8 22 18 48
38 github.com/crankycoder/xmlpath 2 2
39 github.com/cristalhq/jwt 1 1
40 github.com/davecgh/go-spew/spew 9 9
77 github.com/kataras/jwt 5 5
78 github.com/kelseyhightower/envconfig 6 6
79 github.com/labstack/echo 3 12 2 2 1 12 2
80 github.com/lann/squirrel 32 27 32 27
81 github.com/lestrrat-go/jwx 2 2
82 github.com/lestrrat-go/libxml2/parser 3 3
83 github.com/lestrrat/go-jwx/jwk 1 1
106 google.golang.org/protobuf/internal/impl 2 2
107 google.golang.org/protobuf/proto 8 8
108 google.golang.org/protobuf/reflect/protoreflect 1 1
109 gopkg.in/Masterminds/squirrel 32 27 32 27
110 gopkg.in/couchbase/gocb 8 22 18 48 8 22 18 48
111 gopkg.in/glog 90 90
112 gopkg.in/go-jose/go-jose 3 4 2 1 4
113 gopkg.in/go-xmlpath/xmlpath 2 2

View File

@@ -10,8 +10,8 @@ Go framework & library support
`Afero <https://github.com/spf13/afero>`_,``github.com/spf13/afero*``,,,34
`Bun <https://bun.uptrace.dev/>`_,``github.com/uptrace/bun*``,,,63
`CleverGo <https://github.com/clevergo/clevergo>`_,"``clevergo.tech/clevergo*``, ``github.com/clevergo/clevergo*``",,,2
`Couchbase official client(gocb) <https://github.com/couchbase/gocb>`_,"``github.com/couchbase/gocb*``, ``gopkg.in/couchbase/gocb*``",,36,16
`Couchbase unofficial client <http://www.github.com/couchbase/go-couchbase>`_,``github.com/couchbaselabs/gocb*``,,18,8
`Couchbase official client(gocb) <https://github.com/couchbase/gocb>`_,"``github.com/couchbase/gocb*``, ``gopkg.in/couchbase/gocb*``",44,96,16
`Couchbase unofficial client <http://www.github.com/couchbase/go-couchbase>`_,``github.com/couchbaselabs/gocb*``,22,48,8
`Echo <https://echo.labstack.com/>`_,``github.com/labstack/echo*``,12,2,3
`Fiber <https://github.com/gofiber/fiber>`_,``github.com/gofiber/fiber*``,,,5
`Fosite <https://github.com/ory/fosite>`_,``github.com/ory/fosite*``,,,2
@@ -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,,494,958,1556
Totals,,641,1048,1556

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* `database` source models have been added for v1 and v2 of the `github.com/couchbase/gocb` package.

View File

@@ -9,6 +9,32 @@ extensions:
- ["gocb2", "github.com/couchbase/gocb/v2"]
- ["gocb2", "gopkg.in/couchbase/gocb.v2"]
- ["gocb2", "github.com/couchbaselabs/gocb/v2"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:gocb1", "Cluster", True, "ExecuteAnalyticsQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb1", "Cluster", True, "ExecuteN1qlQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb1", "Cluster", True, "ExecuteSearchQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Cluster", True, "AnalyticsQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Cluster", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "Get", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "GetAndLock", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "GetAndTouch", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "GetAnyReplica", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "LookupIn", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "LookupInAllReplicas", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "LookupInAnyReplica", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Collection", True, "Scan", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Scope", True, "AnalyticsQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "Scope", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "TransactionAttemptContext", True, "Get", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "TransactionAttemptContext", True, "GetReplicaFromPreferredServerGroup", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "TransactionAttemptContext", True, "Insert", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "TransactionAttemptContext", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "TransactionAttemptContext", True, "Replace", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "ViewIndexManager", True, "GetAllDesignDocuments", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gocb2", "ViewIndexManager", True, "GetDesignDocument", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -27,6 +53,9 @@ extensions:
data:
- ["group:gocb1", "", False, "NewAnalyticsQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "", False, "NewN1qlQuery", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "AnalyticsResults", True, "One", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb1", "AnalyticsResults", True, "Next", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb1", "AnalyticsResults", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "AnalyticsQuery", True, "ContextId", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "AnalyticsQuery", True, "Deferred", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "AnalyticsQuery", True, "Pretty", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
@@ -43,3 +72,30 @@ extensions:
- ["group:gocb1", "N1qlQuery", True, "ReadOnly", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "N1qlQuery", True, "ScanCap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "N1qlQuery", True, "Timeout", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "QueryResults", True, "One", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb1", "QueryResults", True, "Next", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb1", "QueryResults", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb1", "SearchResults", True, "Hits", "", "", "Argument[receiver]", "ReturnValue.ArrayElement", "taint", "manual"]
- ["group:gocb2", "AnalyticsResult", True, "One", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "AnalyticsResult", True, "Raw", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "AnalyticsResult", True, "Row", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "AnalyticsResultRaw", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "GetResult", True, "Content", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "LookupInAllReplicasResult", True, "Next", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "LookupInResult", True, "ContentAt", "", "", "Argument[receiver]", "Argument[1]", "taint", "manual"]
- ["group:gocb2", "MutateInResult", True, "ContentAt", "", "", "Argument[receiver]", "Argument[1]", "taint", "manual"]
- ["group:gocb2", "QueryResult", True, "One", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "QueryResult", True, "Raw", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "QueryResult", True, "Row", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "QueryResultRaw", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "ScanResult", True, "Next", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "ScanResultItem", True, "Content", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "SearchResult", True, "Raw", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "SearchResult", True, "Row", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "SearchResultRaw", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "TransactionGetResult", True, "Content", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "TransactionQueryResult", True, "One", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "TransactionQueryResult", True, "Row", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["group:gocb2", "ViewResult", True, "Raw", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "ViewResult", True, "Row", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["group:gocb2", "ViewResultRaw", True, "NextBytes", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]

View File

@@ -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

View File

@@ -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

View File

@@ -357,6 +357,23 @@ module RegexpReplaceFunction {
class LoggerCall extends DataFlow::Node instanceof LoggerCall::Range {
/** Gets a node that is a part of the logged message. */
DataFlow::Node getAMessageComponent() { result = super.getAMessageComponent() }
/**
* Gets a node whose value is a part of the logged message.
*
* Components corresponding to the format specifier "%T" are excluded as
* their type is logged rather than their value.
*/
DataFlow::Node getAValueFormattedMessageComponent() {
result = this.getAMessageComponent() and
not exists(string formatSpecifier |
result = this.(StringOps::Formatting::StringFormatCall).getOperand(_, formatSpecifier) and
// We already know that `formatSpecifier` starts with `%`, so we check
// that it ends with `T` to confirm that it is `%T` or possibly some
// variation on it.
formatSpecifier.matches("%T")
)
}
}
/** Provides a class for modeling new logging APIs. */

View 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
}
}
}

View File

@@ -40,7 +40,7 @@ module CleartextLogging {
* An argument to a logging mechanism.
*/
class LoggerSink extends Sink {
LoggerSink() { this = any(LoggerCall log).getAMessageComponent() }
LoggerSink() { this = any(LoggerCall log).getAValueFormattedMessageComponent() }
}
/**

View File

@@ -35,7 +35,7 @@ module LogInjection {
/** An argument to a logging mechanism. */
class LoggerSink extends Sink {
LoggerSink() { this = any(LoggerCall log).getAMessageComponent() }
LoggerSink() { this = any(LoggerCall log).getAValueFormattedMessageComponent() }
}
/**

View File

@@ -138,7 +138,9 @@ predicate privateUrlFlowsToAuthCodeUrlCall(DataFlow::CallNode call) {
module FlowToPrintConfig implements DataFlow::ConfigSig {
additional predicate isSinkCall(DataFlow::Node sink, DataFlow::CallNode call) {
exists(LoggerCall logCall | call = logCall | sink = logCall.getAMessageComponent())
exists(LoggerCall logCall | call = logCall |
sink = logCall.getAValueFormattedMessageComponent()
)
}
predicate isSource(DataFlow::Node source) { source = any(AuthCodeUrl m).getACall().getResult() }

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* False positives in "Log entries created from user input" (`go/log-injection`) and "Clear-text logging of sensitive information" (`go/clear-text-logging`) which involved the verb `%T` in a format specifier have been fixed. As a result, some users may also see more alerts from the "Use of constant `state` value in OAuth 2.0 URL" (`go/constant-oauth2-state`) query.

View File

@@ -4,14 +4,20 @@ import ModelValidation
import utils.test.InlineExpectationsTest
module LoggerTest implements TestSig {
string getARelevantTag() { result = "logger" }
string getARelevantTag() { result = ["type-logger", "logger"] }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(LoggerCall log |
log.getLocation() = location and
element = log.toString() and
value = log.getAMessageComponent().toString() and
tag = "logger"
(
value = log.getAValueFormattedMessageComponent().toString() and
tag = "logger"
or
value = log.getAMessageComponent().toString() and
not value = log.getAValueFormattedMessageComponent().toString() and
tag = "type-logger"
)
)
}
}

View File

@@ -30,6 +30,13 @@ func glogTest() {
glog.Warningf(fmt, text) // $ logger=fmt logger=text
glog.Warningln(text) // $ logger=text
// components corresponding to the format specifier "%T" are not considered vulnerable
glog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
glog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
glog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
glog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
glog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
klog.Error(text) // $ logger=text
klog.ErrorDepth(0, text) // $ logger=text
klog.Errorf(fmt, text) // $ logger=fmt logger=text
@@ -50,4 +57,11 @@ func glogTest() {
klog.WarningDepth(0, text) // $ logger=text
klog.Warningf(fmt, text) // $ logger=fmt logger=text
klog.Warningln(text) // $ logger=text
// components corresponding to the format specifier "%T" are not considered vulnerable
klog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
klog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
klog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
klog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
klog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}

View File

@@ -32,4 +32,8 @@ func logrusCalls() {
logrus.Panicln(text) // $ logger=text
logrus.Infof(fmt, text) // $ logger=fmt logger=text
logrus.FatalFn(fn) // $ logger=fn
// components corresponding to the format specifier "%T" are not considered vulnerable
logrus.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logrus.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}

View File

@@ -3,6 +3,8 @@ package main
const fmt = "formatted %s string"
const text = "test"
func main() {
var v []byte
func main() {
stdlib()
}

View File

@@ -17,6 +17,11 @@ func stdlib() {
logger.Printf(fmt, text) // $ logger=fmt logger=text
logger.Println(text) // $ logger=text
// components corresponding to the format specifier "%T" are not considered vulnerable
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.SetPrefix("prefix: ")
log.Fatal(text) // $ logger=text
log.Fatalf(fmt, text) // $ logger=fmt logger=text
@@ -27,4 +32,9 @@ func stdlib() {
log.Print(text) // $ logger=text
log.Printf(fmt, text) // $ logger=fmt logger=text
log.Println(text) // $ logger=text
// components corresponding to the format specifier "%T" are not considered vulnerable
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}

View File

@@ -1,9 +1,59 @@
module test
go 1.22.5
go 1.24
require (
gorm.io/gorm v1.23.0
github.com/astaxie/beego v1.12.3
github.com/beego/beego/v2 v2.3.5
github.com/couchbase/gocb v1.6.7
github.com/couchbase/gocb/v2 v2.9.4
github.com/jmoiron/sqlx v1.4.0
go.mongodb.org/mongo-driver/mongo v1.17.2
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 (
github.com/couchbase/gocbcore/v10 v10.5.4 // indirect
github.com/couchbase/gocbcoreps v0.1.3 // indirect
github.com/couchbase/goprotostellar v1.0.2 // indirect
github.com/couchbaselabs/gocbconnstr/v2 v2.0.0-20240607131231-fb385523de28 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/couchbase/gocbcore.v7 v7.1.18 // indirect
gopkg.in/couchbaselabs/gocbconnstr.v1 v1.0.4 // indirect
gopkg.in/couchbaselabs/gojcbmock.v1 v1.0.4 // indirect
gopkg.in/couchbaselabs/jsonx.v1 v1.0.1 // indirect
)

View File

@@ -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"]

View File

@@ -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"]

View File

@@ -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"
}

View File

@@ -1,5 +1,8 @@
package test
//go:generate depstubber -vendor github.com/astaxie/beego/orm Ormer NewOrm
//go:generate depstubber -vendor github.com/beego/beego/v2/client/orm DB,DQL,Ormer NewOrm
import (
oldOrm "github.com/astaxie/beego/orm"
"github.com/beego/beego/v2/client/orm"

View File

@@ -0,0 +1,57 @@
package test
//go:generate depstubber -vendor github.com/couchbase/gocb Cluster,AnalyticsResults,QueryResults,SearchResults
import "github.com/couchbase/gocb"
func test_couchbase_gocb_v1_Cluster(cluster *gocb.Cluster, aq *gocb.AnalyticsQuery, n1ql *gocb.N1qlQuery, sq *gocb.SearchQuery) {
// Analytics
r1, err := cluster.ExecuteAnalyticsQuery(aq, nil) // $ source
if err != nil {
return
}
var user1, user2 User
r1.One(&user1)
sink(user1) // $ hasTaintFlow="user1"
for r1.Next(user2) {
sink(user2) // $ hasTaintFlow="user2"
}
var b1 []byte
b1 = r1.NextBytes()
sink(b1) // $ hasTaintFlow="b1"
// N1QL
r2, err := cluster.ExecuteN1qlQuery(n1ql, nil) // $ source
if err != nil {
return
}
var user3, user4 User
r2.One(&user3)
sink(user3) // $ hasTaintFlow="user3"
for r2.Next(user4) {
sink(user4) // $ hasTaintFlow="user4"
}
var b2 []byte
b2 = r2.NextBytes()
sink(b2) // $ hasTaintFlow="b2"
// Search
r3, err := cluster.ExecuteSearchQuery(sq) // $ source
if err != nil {
return
}
hit := r3.Hits()[0]
sink(hit) // $ hasTaintFlow="hit"
}

View File

@@ -0,0 +1,247 @@
package test
//go:generate depstubber -vendor github.com/couchbase/gocb/v2 AnalyticsResult,AnalyticsResultRaw,Cluster,Collection,ExistsResult,GetResult,LookupInReplicaResult,LookupInResult,MutateInResult,MutationResult,QueryResult,QueryResultRaw,Result,ScanResult,ScanResultItem,Scope,SearchResult,SearchResultRaw,TransactionAttemptContext,TransactionGetResult,TransactionQueryResult,ViewIndexManager,ViewResult,ViewResultRaw
import "github.com/couchbase/gocb/v2"
func test_couchbase_gocb_v2_Cluster(cluster *gocb.Cluster) {
r1, err := cluster.AnalyticsQuery("SELECT * FROM `travel-sample`", nil) // $ source
if err != nil {
return
}
for r1.Next() {
var name1, name2 string
r1.One(&name1)
sink(name1) // $ hasTaintFlow="name1"
r1.Row(&name2)
sink(name2) // $ hasTaintFlow="name2"
b := r1.Raw().NextBytes()
sink(b) // $ hasTaintFlow="b"
}
r2, err := cluster.Query("SELECT * FROM `travel-sample`", nil) // $ source
if err != nil {
return
}
for r2.Next() {
var name1, name2 string
r2.One(&name1)
sink(name1) // $ hasTaintFlow="name1"
r2.Row(&name2)
sink(name2) // $ hasTaintFlow="name2"
b := r2.Raw().NextBytes()
sink(b) // $ hasTaintFlow="b"
}
}
func test_couchbase_gocb_v2_Scope(scope *gocb.Scope) {
r1, err := scope.AnalyticsQuery("SELECT * FROM `travel-sample`", nil) // $ source
if err != nil {
return
}
for r1.Next() {
var name1, name2 string
r1.One(&name1)
sink(name1) // $ hasTaintFlow="name1"
r1.Row(&name2)
sink(name2) // $ hasTaintFlow="name2"
b := r1.Raw().NextBytes()
sink(b) // $ hasTaintFlow="b"
}
r2, err := scope.Query("SELECT * FROM `travel-sample`", nil) // $ source
if err != nil {
return
}
for r2.Next() {
var name1, name2 string
r2.One(&name1)
sink(name1) // $ hasTaintFlow="name1"
r2.Row(&name2)
sink(name2) // $ hasTaintFlow="name2"
b := r2.Raw().NextBytes()
sink(b) // $ hasTaintFlow="b"
}
}
func test_couchbase_gocb_v2_Collection(coll *gocb.Collection) {
type User struct {
Name string
}
var user User
r1, err := coll.Get("documentID", nil) // $ source
if err != nil {
return
}
r1.Content(&user)
sink(user) // $ hasTaintFlow="user"
r2, err := coll.GetAndLock("documentID", 30, nil) // $ source
if err != nil {
return
}
sink(r2) // $ hasTaintFlow="r2"
r3, err := coll.GetAndTouch("documentID", 30, nil) // $ source
if err != nil {
return
}
var user3 User
r3.Content(&user3)
sink(user3) // $ hasTaintFlow="user3"
r4, err := coll.GetAnyReplica("documentID", nil) // $ source
if err != nil {
return
}
sink(r4) // $ hasTaintFlow="r4"
r5, err := coll.LookupIn("documentID", []gocb.LookupInSpec{}, nil) // $ source
if err != nil {
return
}
var user5 User
r5.ContentAt(0, &user5)
sink(user5) // $ hasTaintFlow="user5"
r6, err := coll.LookupInAllReplicas("documentID", []gocb.LookupInSpec{}, nil) // $ source
if err != nil {
return
}
var user6 User
r6.Next().ContentAt(0, &user6)
sink(user6) // $ hasTaintFlow="user6"
r7, err := coll.LookupInAnyReplica("documentID", []gocb.LookupInSpec{}, nil) // $ source
if err != nil {
return
}
var user7 User
r7.ContentAt(0, &user7)
sink(user7) // $ hasTaintFlow="user7"
r8, err := coll.Scan(nil, nil) // $ source
if err != nil {
return
}
var user8 User
r8.Next().Content(&user8)
sink(user8) // $ hasTaintFlow="user8"
}
func test_couchbase_gocb_v2_TransactionAttemptContext(tam *gocb.TransactionAttemptContext, coll *gocb.Collection) {
r1, err := tam.Get(coll, "documentID") // $ source
if err != nil {
return
}
var user User
r1.Content(&user)
sink(user) // $ hasTaintFlow="user"
r2, err := tam.GetReplicaFromPreferredServerGroup(coll, "documentID") // $ source
if err != nil {
return
}
var user2 User
r2.Content(&user2)
sink(user2) // $ hasTaintFlow="user2"
var user3 User
r3, err := tam.Insert(coll, "documentID", &user3) // $ source
if err != nil {
return
}
var user4 User
r3.Content(&user4)
sink(user4) // $ hasTaintFlow="user4"
r4, err := tam.Query("SELECT * FROM `travel-sample`", nil) // $ source
if err != nil {
return
}
for r4.Next() {
var user5 User
r4.One(&user5)
sink(user5) // $ hasTaintFlow="user5"
var user6 User
r4.Row(&user6)
sink(user6) // $ hasTaintFlow="user6"
}
r5, err := tam.Replace(r3, user4) // $ source
if err != nil {
return
}
sink(r5) // $ hasTaintFlow="r5"
}
func test_couchbase_gocb_v2_ViewIndexManager(v *gocb.ViewIndexManager) {
doc, err := v.GetDesignDocument("name", 0, nil) // $ source
if err != nil {
return
}
sink(doc) // $ hasTaintFlow="doc"
docs, err := v.GetAllDesignDocuments(0, nil) // $ source
if err != nil {
return
}
sink(docs) // $ hasTaintFlow="docs"
}

View File

@@ -1,5 +1,7 @@
package test
//go:generate depstubber -vendor gorm.io/gorm Association,ConnPool,DB
import "gorm.io/gorm"
// test querying an Association

View File

@@ -1,5 +1,7 @@
package test
//go:generate depstubber -vendor github.com/jmoiron/sqlx Conn,DB,NamedStmt,Stmt,Tx Get,GetContext,NamedQuery,NamedQueryContext,Select,SelectContext
import (
"context"

View 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{}
}

View File

@@ -2,7 +2,7 @@
// This is a simple stub for github.com/beego/beego/v2/client/orm, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/beego/beego/v2/client/orm (exports: DQL,DB,Ormer; functions: NewOrm)
// Source: github.com/beego/beego/v2/client/orm (exports: DB,DQL,Ormer; functions: NewOrm)
// Package orm is a stub of github.com/beego/beego/v2/client/orm, generated by depstubber.
package orm
@@ -56,30 +56,10 @@ func (_ *Condition) OrNotCond(_ *Condition) *Condition {
}
type DB struct {
RWMutex *sync.RWMutex
DB *sql.DB
*sync.RWMutex
DB *sql.DB
}
func (_ DB) Lock() {}
func (_ DB) RLock() {}
func (_ DB) RLocker() sync.Locker {
return nil
}
func (_ DB) RUnlock() {}
func (_ DB) TryLock() bool {
return false
}
func (_ DB) TryRLock() bool {
return false
}
func (_ DB) Unlock() {}
func (_ *DB) Begin() (*sql.Tx, error) {
return nil, nil
}

View File

@@ -1,26 +0,0 @@
package sqlx
import (
"context"
"database/sql"
)
type Conn struct {
*sql.Conn
}
func (c *Conn) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
return nil
}
func (c *Conn) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
return nil
}
func (c *Conn) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
return nil
}
func (c *Conn) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
return nil, nil
}

View File

@@ -1,52 +0,0 @@
package sqlx
import (
"context"
"database/sql"
)
type DB struct {
*sql.DB
// Mapper *reflectx.Mapper
}
func (db *DB) Get(dest interface{}, query string, args ...interface{}) error {
return nil
}
func (db *DB) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
return nil
}
func (db *DB) QueryRowx(query string, args ...interface{}) *Row {
return nil
}
func (db *DB) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
return nil
}
func (db *DB) Queryx(query string, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (db *DB) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (db *DB) Select(dest interface{}, query string, args ...interface{}) error {
return nil
}
func (db *DB) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
return nil
}
func (db *DB) NamedQuery(query string, arg interface{}) (*Rows, error) {
return nil, nil
}
func (db *DB) NamedQueryContext(ctx context.Context, query string, arg interface{}) (*Rows, error) {
return nil, nil
}

View File

@@ -1,60 +0,0 @@
package sqlx
import (
"context"
"database/sql"
)
type NamedStmt struct {
Params []string
QueryString string
Stmt *sql.Stmt
}
func (s *NamedStmt) Get(dest interface{}, args ...interface{}) error {
return nil
}
func (s *NamedStmt) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}
func (s *NamedStmt) QueryRow(args ...interface{}) *Row {
return nil
}
func (s *NamedStmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row {
return nil
}
func (s *NamedStmt) Query(args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *NamedStmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *NamedStmt) QueryRowx(args ...interface{}) *Row {
return nil
}
func (s *NamedStmt) QueryRowxContext(ctx context.Context, args ...interface{}) *Row {
return nil
}
func (s *NamedStmt) Queryx(args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *NamedStmt) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *NamedStmt) Select(dest interface{}, args ...interface{}) error {
return nil
}
func (s *NamedStmt) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}

View File

@@ -1,21 +0,0 @@
package sqlx
type Row struct {
// Mapper *reflectx.Mapper
}
func (r *Row) MapScan(dest map[string]interface{}) error {
return nil
}
func (r *Row) StructScan(dest interface{}) error {
return nil
}
func (r *Row) SliceScan(dest []interface{}) error {
return nil
}
func (r *Row) Scan(dest ...interface{}) error {
return nil
}

View File

@@ -1,22 +0,0 @@
package sqlx
import "database/sql"
type Rows struct {
*sql.Rows
// Mapper *reflectx.Mapper
// contains filtered or unexported fields
}
func (r *Rows) MapScan(dest map[string]interface{}) error {
return nil
}
func (r *Rows) StructScan(dest interface{}) error {
return nil
}
func (r *Rows) SliceScan(dest []interface{}) error {
return nil
}

View File

@@ -1,42 +0,0 @@
package sqlx
import (
"context"
"database/sql"
)
type Stmt struct {
*sql.Stmt
}
func (s *Stmt) Get(dest interface{}, args ...interface{}) error {
return nil
}
func (s *Stmt) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}
func (s *Stmt) QueryRowx(args ...interface{}) *Row {
return nil
}
func (s *Stmt) QueryRowxContext(ctx context.Context, args ...interface{}) *Row {
return nil
}
func (s *Stmt) Queryx(args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *Stmt) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (s *Stmt) Select(dest interface{}, args ...interface{}) error {
return nil
}
func (s *Stmt) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}

View File

@@ -1,67 +1,530 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/jmoiron/sqlx, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/jmoiron/sqlx (exports: Conn,DB,NamedStmt,Stmt,Tx; functions: Get,GetContext,NamedQuery,NamedQueryContext,Select,SelectContext)
// Package sqlx is a stub of github.com/jmoiron/sqlx, generated by depstubber.
package sqlx
import (
"context"
"database/sql"
context "context"
sql "database/sql"
)
type ColScanner interface {
Columns() ([]string, error)
Scan(dest ...interface{}) error
Err() error
type Conn struct {
*sql.Conn
Mapper interface{}
}
type Execer interface {
Exec(query string, args ...interface{}) (sql.Result, error)
func (_ Conn) BeginTx(_ context.Context, _ *sql.TxOptions) (*sql.Tx, error) {
return nil, nil
}
type ExecerContext interface {
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
func (_ Conn) Close() error {
return nil
}
func (_ Conn) ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
}
func (_ Conn) PingContext(_ context.Context) error {
return nil
}
func (_ Conn) PrepareContext(_ context.Context, _ string) (*sql.Stmt, error) {
return nil, nil
}
func (_ Conn) QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error) {
return nil, nil
}
func (_ Conn) QueryRowContext(_ context.Context, _ string, _ ...interface{}) *sql.Row {
return nil
}
func (_ Conn) Raw(_ func(interface{}) error) error {
return nil
}
func (_ *Conn) BeginTxx(_ context.Context, _ *sql.TxOptions) (*Tx, error) {
return nil, nil
}
func (_ *Conn) GetContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *Conn) PreparexContext(_ context.Context, _ string) (*Stmt, error) {
return nil, nil
}
func (_ *Conn) QueryRowxContext(_ context.Context, _ string, _ ...interface{}) *Row {
return nil
}
func (_ *Conn) QueryxContext(_ context.Context, _ string, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Conn) Rebind(_ string) string {
return ""
}
func (_ *Conn) SelectContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
type DB struct {
*sql.DB
Mapper interface{}
}
func (_ *DB) BeginTxx(_ context.Context, _ *sql.TxOptions) (*Tx, error) {
return nil, nil
}
func (_ *DB) Beginx() (*Tx, error) {
return nil, nil
}
func (_ *DB) BindNamed(_ string, _ interface{}) (string, []interface{}, error) {
return "", nil, nil
}
func (_ *DB) Connx(_ context.Context) (*Conn, error) {
return nil, nil
}
func (_ *DB) DriverName() string {
return ""
}
func (_ *DB) Get(_ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *DB) GetContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *DB) MapperFunc(_ func(string) string) {}
func (_ *DB) MustBegin() *Tx {
return nil
}
func (_ *DB) MustBeginTx(_ context.Context, _ *sql.TxOptions) *Tx {
return nil
}
func (_ *DB) MustExec(_ string, _ ...interface{}) sql.Result {
return nil
}
func (_ *DB) MustExecContext(_ context.Context, _ string, _ ...interface{}) sql.Result {
return nil
}
func (_ *DB) NamedExec(_ string, _ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *DB) NamedExecContext(_ context.Context, _ string, _ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *DB) NamedQuery(_ string, _ interface{}) (*Rows, error) {
return nil, nil
}
func (_ *DB) NamedQueryContext(_ context.Context, _ string, _ interface{}) (*Rows, error) {
return nil, nil
}
func (_ *DB) PrepareNamed(_ string) (*NamedStmt, error) {
return nil, nil
}
func (_ *DB) PrepareNamedContext(_ context.Context, _ string) (*NamedStmt, error) {
return nil, nil
}
func (_ *DB) Preparex(_ string) (*Stmt, error) {
return nil, nil
}
func (_ *DB) PreparexContext(_ context.Context, _ string) (*Stmt, error) {
return nil, nil
}
func (_ *DB) QueryRowx(_ string, _ ...interface{}) *Row {
return nil
}
func (_ *DB) QueryRowxContext(_ context.Context, _ string, _ ...interface{}) *Row {
return nil
}
func (_ *DB) Queryx(_ string, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *DB) QueryxContext(_ context.Context, _ string, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *DB) Rebind(_ string) string {
return ""
}
func (_ *DB) Select(_ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *DB) SelectContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *DB) Unsafe() *DB {
return nil
}
type Ext interface {
Queryer
Execer
BindNamed(_ string, _ interface{}) (string, []interface{}, error)
DriverName() string
Exec(_ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryRowx(_ string, _ ...interface{}) *Row
Queryx(_ string, _ ...interface{}) (*Rows, error)
Rebind(_ string) string
}
type ExtContext interface {
QueryerContext
ExecerContext
// contains filtered or unexported methods
BindNamed(_ string, _ interface{}) (string, []interface{}, error)
DriverName() string
ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error)
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
QueryRowxContext(_ context.Context, _ string, _ ...interface{}) *Row
QueryxContext(_ context.Context, _ string, _ ...interface{}) (*Rows, error)
Rebind(_ string) string
}
func Get(_ Queryer, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func GetContext(_ context.Context, _ QueryerContext, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func NamedQuery(_ Ext, _ string, _ interface{}) (*Rows, error) {
return nil, nil
}
func NamedQueryContext(_ context.Context, _ ExtContext, _ string, _ interface{}) (*Rows, error) {
return nil, nil
}
type NamedStmt struct {
Params []string
QueryString string
Stmt *Stmt
}
func (_ *NamedStmt) Close() error {
return nil
}
func (_ *NamedStmt) Exec(_ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *NamedStmt) ExecContext(_ context.Context, _ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *NamedStmt) Get(_ interface{}, _ interface{}) error {
return nil
}
func (_ *NamedStmt) GetContext(_ context.Context, _ interface{}, _ interface{}) error {
return nil
}
func (_ *NamedStmt) MustExec(_ interface{}) sql.Result {
return nil
}
func (_ *NamedStmt) MustExecContext(_ context.Context, _ interface{}) sql.Result {
return nil
}
func (_ *NamedStmt) Query(_ interface{}) (*sql.Rows, error) {
return nil, nil
}
func (_ *NamedStmt) QueryContext(_ context.Context, _ interface{}) (*sql.Rows, error) {
return nil, nil
}
func (_ *NamedStmt) QueryRow(_ interface{}) *Row {
return nil
}
func (_ *NamedStmt) QueryRowContext(_ context.Context, _ interface{}) *Row {
return nil
}
func (_ *NamedStmt) QueryRowx(_ interface{}) *Row {
return nil
}
func (_ *NamedStmt) QueryRowxContext(_ context.Context, _ interface{}) *Row {
return nil
}
func (_ *NamedStmt) Queryx(_ interface{}) (*Rows, error) {
return nil, nil
}
func (_ *NamedStmt) QueryxContext(_ context.Context, _ interface{}) (*Rows, error) {
return nil, nil
}
func (_ *NamedStmt) Select(_ interface{}, _ interface{}) error {
return nil
}
func (_ *NamedStmt) SelectContext(_ context.Context, _ interface{}, _ interface{}) error {
return nil
}
func (_ *NamedStmt) Unsafe() *NamedStmt {
return nil
}
type Queryer interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
Queryx(query string, args ...interface{}) (*Rows, error)
QueryRowx(query string, args ...interface{}) *Row
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryRowx(_ string, _ ...interface{}) *Row
Queryx(_ string, _ ...interface{}) (*Rows, error)
}
type QueryerContext interface {
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error)
QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
QueryRowxContext(_ context.Context, _ string, _ ...interface{}) *Row
QueryxContext(_ context.Context, _ string, _ ...interface{}) (*Rows, error)
}
func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
return e.Queryx(query, arg)
type Row struct {
Mapper interface{}
}
func NamedQueryContext(ctx context.Context, e ExtContext, query string, arg interface{}) (*Rows, error) {
return e.QueryxContext(ctx, query, arg)
func (_ *Row) ColumnTypes() ([]*sql.ColumnType, error) {
return nil, nil
}
func Get(q Queryer, dest interface{}, query string, args ...interface{}) error {
func (_ *Row) Columns() ([]string, error) {
return nil, nil
}
func (_ *Row) Err() error {
return nil
}
func GetContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {
func (_ *Row) MapScan(_ map[string]interface{}) error {
return nil
}
func Select(q Queryer, dest interface{}, query string, args ...interface{}) error {
func (_ *Row) Scan(_ ...interface{}) error {
return nil
}
func SelectContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {
func (_ *Row) SliceScan() ([]interface{}, error) {
return nil, nil
}
func (_ *Row) StructScan(_ interface{}) error {
return nil
}
type Rows struct {
*sql.Rows
Mapper interface{}
}
func (_ *Rows) MapScan(_ map[string]interface{}) error {
return nil
}
func (_ *Rows) SliceScan() ([]interface{}, error) {
return nil, nil
}
func (_ *Rows) StructScan(_ interface{}) error {
return nil
}
func Select(_ Queryer, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func SelectContext(_ context.Context, _ QueryerContext, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
type Stmt struct {
*sql.Stmt
Mapper interface{}
}
func (_ *Stmt) Get(_ interface{}, _ ...interface{}) error {
return nil
}
func (_ *Stmt) GetContext(_ context.Context, _ interface{}, _ ...interface{}) error {
return nil
}
func (_ *Stmt) MustExec(_ ...interface{}) sql.Result {
return nil
}
func (_ *Stmt) MustExecContext(_ context.Context, _ ...interface{}) sql.Result {
return nil
}
func (_ *Stmt) QueryRowx(_ ...interface{}) *Row {
return nil
}
func (_ *Stmt) QueryRowxContext(_ context.Context, _ ...interface{}) *Row {
return nil
}
func (_ *Stmt) Queryx(_ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Stmt) QueryxContext(_ context.Context, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Stmt) Select(_ interface{}, _ ...interface{}) error {
return nil
}
func (_ *Stmt) SelectContext(_ context.Context, _ interface{}, _ ...interface{}) error {
return nil
}
func (_ *Stmt) Unsafe() *Stmt {
return nil
}
type Tx struct {
*sql.Tx
Mapper interface{}
}
func (_ *Tx) BindNamed(_ string, _ interface{}) (string, []interface{}, error) {
return "", nil, nil
}
func (_ *Tx) DriverName() string {
return ""
}
func (_ *Tx) Get(_ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *Tx) GetContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *Tx) MustExec(_ string, _ ...interface{}) sql.Result {
return nil
}
func (_ *Tx) MustExecContext(_ context.Context, _ string, _ ...interface{}) sql.Result {
return nil
}
func (_ *Tx) NamedExec(_ string, _ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *Tx) NamedExecContext(_ context.Context, _ string, _ interface{}) (sql.Result, error) {
return nil, nil
}
func (_ *Tx) NamedQuery(_ string, _ interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Tx) NamedStmt(_ *NamedStmt) *NamedStmt {
return nil
}
func (_ *Tx) NamedStmtContext(_ context.Context, _ *NamedStmt) *NamedStmt {
return nil
}
func (_ *Tx) PrepareNamed(_ string) (*NamedStmt, error) {
return nil, nil
}
func (_ *Tx) PrepareNamedContext(_ context.Context, _ string) (*NamedStmt, error) {
return nil, nil
}
func (_ *Tx) Preparex(_ string) (*Stmt, error) {
return nil, nil
}
func (_ *Tx) PreparexContext(_ context.Context, _ string) (*Stmt, error) {
return nil, nil
}
func (_ *Tx) QueryRowx(_ string, _ ...interface{}) *Row {
return nil
}
func (_ *Tx) QueryRowxContext(_ context.Context, _ string, _ ...interface{}) *Row {
return nil
}
func (_ *Tx) Queryx(_ string, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Tx) QueryxContext(_ context.Context, _ string, _ ...interface{}) (*Rows, error) {
return nil, nil
}
func (_ *Tx) Rebind(_ string) string {
return ""
}
func (_ *Tx) Select(_ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *Tx) SelectContext(_ context.Context, _ interface{}, _ string, _ ...interface{}) error {
return nil
}
func (_ *Tx) Stmtx(_ interface{}) *Stmt {
return nil
}
func (_ *Tx) StmtxContext(_ context.Context, _ interface{}) *Stmt {
return nil
}
func (_ *Tx) Unsafe() *Tx {
return nil
}

View File

@@ -1,47 +0,0 @@
package sqlx
import (
"context"
"database/sql"
)
type Tx struct {
*sql.Tx
}
func (tx *Tx) Get(dest interface{}, args ...interface{}) error {
return nil
}
func (tx *Tx) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}
func (tx *Tx) QueryRowx(args ...interface{}) *Row {
return nil
}
func (tx *Tx) QueryRowxContext(ctx context.Context, args ...interface{}) *Row {
return nil
}
func (tx *Tx) Queryx(args ...interface{}) (*Rows, error) {
return nil, nil
}
func (tx *Tx) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) {
return nil, nil
}
func (tx *Tx) Select(dest interface{}, args ...interface{}) error {
return nil
}
func (tx *Tx) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error {
return nil
}
func (tx *Tx) NamedQuery(query string, arg interface{}) (*Rows, error) {
return nil, nil
}

View File

@@ -0,0 +1,5 @@
package sources
func Source[T any]() T {
return *new(T)
}

View File

@@ -1,77 +1,878 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for gorm.io/gorm, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: gorm.io/gorm (exports: Association,ConnPool,DB; functions: )
// Package gorm is a stub of gorm.io/gorm, generated by depstubber.
package gorm
import (
"context"
"database/sql"
context "context"
sql "database/sql"
reflect "reflect"
strings "strings"
sync "sync"
time "time"
)
type DB struct{}
func (db *DB) Find(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) FindInBatches(dest interface{}, batchSize int, fc func(tx *DB, batch int) error) *DB {
return db
}
func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) FirstOrInit(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) First(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Model(value interface{}) *DB {
return db
}
func (db *DB) Last(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Pluck(column string, dest interface{}) *DB {
return db
}
func (db *DB) Take(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Scan(dest interface{}) *DB {
return db
}
func (db *DB) ScanRows(rows *sql.Rows, result interface{}) error {
return nil
}
func (db *DB) Row() *sql.Row {
return nil
}
func (db *DB) Rows() (*sql.Rows, error) {
return nil, nil
}
type Association struct {
DB *DB
DB *DB
Relationship interface{}
Unscope bool
Error error
}
func (a *Association) Find(dest interface{}) *Association {
return a
func (_ *Association) Append(_ ...interface{}) error {
return nil
}
func (_ *Association) Clear() error {
return nil
}
func (_ *Association) Count() int64 {
return 0
}
func (_ *Association) Delete(_ ...interface{}) error {
return nil
}
func (_ *Association) Find(_ interface{}, _ ...interface{}) error {
return nil
}
func (_ *Association) Replace(_ ...interface{}) error {
return nil
}
func (_ *Association) Unscoped() *Association {
return nil
}
type ColumnType interface {
AutoIncrement() (bool, bool)
ColumnType() (string, bool)
Comment() (string, bool)
DatabaseTypeName() string
DecimalSize() (int64, int64, bool)
DefaultValue() (string, bool)
Length() (int64, bool)
Name() string
Nullable() (bool, bool)
PrimaryKey() (bool, bool)
ScanType() reflect.Type
Unique() (bool, bool)
}
type Config struct {
SkipDefaultTransaction bool
NamingStrategy interface{}
FullSaveAssociations bool
Logger interface{}
NowFunc func() time.Time
DryRun bool
PrepareStmt bool
DisableAutomaticPing bool
DisableForeignKeyConstraintWhenMigrating bool
IgnoreRelationshipsWhenMigrating bool
DisableNestedTransaction bool
AllowGlobalUpdate bool
QueryFields bool
CreateBatchSize int
TranslateError bool
PropagateUnscoped bool
ClauseBuilders map[string]interface{}
ConnPool ConnPool
Dialector
Plugins map[string]Plugin
}
func (_ Config) BindVarTo(_ interface{}, _ *Statement, _ interface{}) {}
func (_ Config) DataTypeOf(_ interface{}) string {
return ""
}
func (_ Config) DefaultValueOf(_ interface{}) interface{} {
return nil
}
func (_ Config) Explain(_ string, _ ...interface{}) string {
return ""
}
func (_ Config) Initialize(_ *DB) error {
return nil
}
func (_ Config) Migrator(_ *DB) Migrator {
return nil
}
func (_ Config) Name() string {
return ""
}
func (_ Config) QuoteTo(_ interface{}, _ string) {}
func (_ *Config) AfterInitialize(_ *DB) error {
return nil
}
func (_ *Config) Apply(_ *Config) error {
return nil
}
type ConnPool interface {
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error)
PrepareContext(_ context.Context, _ string) (*sql.Stmt, error)
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
QueryRowContext(_ context.Context, _ string, _ ...interface{}) *sql.Row
}
type Model interface{}
type DB struct {
*Config
Error error
RowsAffected int64
Statement *Statement
}
func (_ DB) AfterInitialize(_ *DB) error {
return nil
}
func (_ DB) Apply(_ *Config) error {
return nil
}
func (_ DB) BindVarTo(_ interface{}, _ *Statement, _ interface{}) {}
func (_ DB) DataTypeOf(_ interface{}) string {
return ""
}
func (_ DB) DefaultValueOf(_ interface{}) interface{} {
return nil
}
func (_ DB) Explain(_ string, _ ...interface{}) string {
return ""
}
func (_ DB) Initialize(_ *DB) error {
return nil
}
func (_ DB) Name() string {
return ""
}
func (_ DB) QuoteTo(_ interface{}, _ string) {}
func (_ *DB) AddError(_ error) error {
return nil
}
func (_ *DB) Assign(_ ...interface{}) *DB {
return nil
}
func (_ *DB) Association(_ string) *Association {
return nil
}
func (_ *DB) Attrs(_ ...interface{}) *DB {
return nil
}
func (_ *DB) AutoMigrate(_ ...interface{}) error {
return nil
}
func (_ *DB) Begin(_ ...*sql.TxOptions) *DB {
return nil
}
func (_ *DB) Callback() interface{} {
return nil
}
func (_ *DB) Clauses(_ ...interface{}) *DB {
return nil
}
func (_ *DB) Commit() *DB {
return nil
}
func (_ *DB) Connection(_ func(*DB) error) error {
return nil
}
func (_ *DB) Count(_ *int64) *DB {
return nil
}
func (_ *DB) Create(_ interface{}) *DB {
return nil
}
func (_ *DB) CreateInBatches(_ interface{}, _ int) *DB {
return nil
}
func (_ *DB) DB() (*sql.DB, error) {
return nil, nil
}
func (_ *DB) Debug() *DB {
return nil
}
func (_ *DB) Delete(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Distinct(_ ...interface{}) *DB {
return nil
}
func (_ *DB) Exec(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Find(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) FindInBatches(_ interface{}, _ int, _ func(*DB, int) error) *DB {
return nil
}
func (_ *DB) First(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) FirstOrCreate(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) FirstOrInit(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Get(_ string) (interface{}, bool) {
return nil, false
}
func (_ *DB) Group(_ string) *DB {
return nil
}
func (_ *DB) Having(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) InnerJoins(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) InstanceGet(_ string) (interface{}, bool) {
return nil, false
}
func (_ *DB) InstanceSet(_ string, _ interface{}) *DB {
return nil
}
func (_ *DB) Joins(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Last(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Limit(_ int) *DB {
return nil
}
func (_ *DB) MapColumns(_ map[string]string) *DB {
return nil
}
func (_ *DB) Migrator() Migrator {
return nil
}
func (_ *DB) Model(_ interface{}) *DB {
return nil
}
func (_ *DB) Not(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Offset(_ int) *DB {
return nil
}
func (_ *DB) Omit(_ ...string) *DB {
return nil
}
func (_ *DB) Or(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Order(_ interface{}) *DB {
return nil
}
func (_ *DB) Pluck(_ string, _ interface{}) *DB {
return nil
}
func (_ *DB) Preload(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Raw(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Rollback() *DB {
return nil
}
func (_ *DB) RollbackTo(_ string) *DB {
return nil
}
func (_ *DB) Row() *sql.Row {
return nil
}
func (_ *DB) Rows() (*sql.Rows, error) {
return nil, nil
}
func (_ *DB) Save(_ interface{}) *DB {
return nil
}
func (_ *DB) SavePoint(_ string) *DB {
return nil
}
func (_ *DB) Scan(_ interface{}) *DB {
return nil
}
func (_ *DB) ScanRows(_ *sql.Rows, _ interface{}) error {
return nil
}
func (_ *DB) Scopes(_ ...func(*DB) *DB) *DB {
return nil
}
func (_ *DB) Select(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Session(_ *Session) *DB {
return nil
}
func (_ *DB) Set(_ string, _ interface{}) *DB {
return nil
}
func (_ *DB) SetupJoinTable(_ interface{}, _ string, _ interface{}) error {
return nil
}
func (_ *DB) Table(_ string, _ ...interface{}) *DB {
return nil
}
func (_ *DB) Take(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) ToSQL(_ func(*DB) *DB) string {
return ""
}
func (_ *DB) Transaction(_ func(*DB) error, _ ...*sql.TxOptions) error {
return nil
}
func (_ *DB) Unscoped() *DB {
return nil
}
func (_ *DB) Update(_ string, _ interface{}) *DB {
return nil
}
func (_ *DB) UpdateColumn(_ string, _ interface{}) *DB {
return nil
}
func (_ *DB) UpdateColumns(_ interface{}) *DB {
return nil
}
func (_ *DB) Updates(_ interface{}) *DB {
return nil
}
func (_ *DB) Use(_ Plugin) error {
return nil
}
func (_ *DB) Where(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ *DB) WithContext(_ context.Context) *DB {
return nil
}
type Dialector interface {
BindVarTo(_ interface{}, _ *Statement, _ interface{})
DataTypeOf(_ interface{}) string
DefaultValueOf(_ interface{}) interface{}
Explain(_ string, _ ...interface{}) string
Initialize(_ *DB) error
Migrator(_ *DB) Migrator
Name() string
QuoteTo(_ interface{}, _ string)
}
type Index interface {
Columns() []string
Name() string
Option() string
PrimaryKey() (bool, bool)
Table() string
Unique() (bool, bool)
}
type Migrator interface {
AddColumn(_ interface{}, _ string) error
AlterColumn(_ interface{}, _ string) error
AutoMigrate(_ ...interface{}) error
ColumnTypes(_ interface{}) ([]ColumnType, error)
CreateConstraint(_ interface{}, _ string) error
CreateIndex(_ interface{}, _ string) error
CreateTable(_ ...interface{}) error
CreateView(_ string, _ ViewOption) error
CurrentDatabase() string
DropColumn(_ interface{}, _ string) error
DropConstraint(_ interface{}, _ string) error
DropIndex(_ interface{}, _ string) error
DropTable(_ ...interface{}) error
DropView(_ string) error
FullDataTypeOf(_ interface{}) interface{}
GetIndexes(_ interface{}) ([]Index, error)
GetTables() ([]string, error)
GetTypeAliases(_ string) []string
HasColumn(_ interface{}, _ string) bool
HasConstraint(_ interface{}, _ string) bool
HasIndex(_ interface{}, _ string) bool
HasTable(_ interface{}) bool
MigrateColumn(_ interface{}, _ interface{}, _ ColumnType) error
MigrateColumnUnique(_ interface{}, _ interface{}, _ ColumnType) error
RenameColumn(_ interface{}, _ string, _ string) error
RenameIndex(_ interface{}, _ string, _ string) error
RenameTable(_ interface{}, _ interface{}) error
TableType(_ interface{}) (TableType, error)
}
type Plugin interface {
Initialize(_ *DB) error
Name() string
}
type Session struct {
DryRun bool
PrepareStmt bool
NewDB bool
Initialized bool
SkipHooks bool
SkipDefaultTransaction bool
DisableNestedTransaction bool
AllowGlobalUpdate bool
FullSaveAssociations bool
PropagateUnscoped bool
QueryFields bool
Context context.Context
Logger interface{}
NowFunc func() time.Time
CreateBatchSize int
}
type Statement struct {
*DB
TableExpr interface{}
Table string
Model interface{}
Unscoped bool
Dest interface{}
ReflectValue reflect.Value
Clauses map[string]interface{}
BuildClauses []string
Distinct bool
Selects []string
Omits []string
ColumnMapping map[string]string
Joins []interface{}
Preloads map[string][]interface{}
Settings sync.Map
ConnPool ConnPool
Schema interface{}
Context context.Context
RaiseErrorOnNotFound bool
SkipHooks bool
SQL strings.Builder
Vars []interface{}
CurDestIndex int
}
func (_ Statement) AddError(_ error) error {
return nil
}
func (_ Statement) AfterInitialize(_ *DB) error {
return nil
}
func (_ Statement) Apply(_ *Config) error {
return nil
}
func (_ Statement) Assign(_ ...interface{}) *DB {
return nil
}
func (_ Statement) Association(_ string) *Association {
return nil
}
func (_ Statement) Attrs(_ ...interface{}) *DB {
return nil
}
func (_ Statement) AutoMigrate(_ ...interface{}) error {
return nil
}
func (_ Statement) Begin(_ ...*sql.TxOptions) *DB {
return nil
}
func (_ Statement) BindVarTo(_ interface{}, _ *Statement, _ interface{}) {}
func (_ Statement) Callback() interface{} {
return nil
}
func (_ Statement) Commit() *DB {
return nil
}
func (_ Statement) Connection(_ func(*DB) error) error {
return nil
}
func (_ Statement) Count(_ *int64) *DB {
return nil
}
func (_ Statement) Create(_ interface{}) *DB {
return nil
}
func (_ Statement) CreateInBatches(_ interface{}, _ int) *DB {
return nil
}
func (_ Statement) DataTypeOf(_ interface{}) string {
return ""
}
func (_ Statement) Debug() *DB {
return nil
}
func (_ Statement) DefaultValueOf(_ interface{}) interface{} {
return nil
}
func (_ Statement) Delete(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Exec(_ string, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Explain(_ string, _ ...interface{}) string {
return ""
}
func (_ Statement) Find(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) FindInBatches(_ interface{}, _ int, _ func(*DB, int) error) *DB {
return nil
}
func (_ Statement) First(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) FirstOrCreate(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) FirstOrInit(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Get(_ string) (interface{}, bool) {
return nil, false
}
func (_ Statement) Group(_ string) *DB {
return nil
}
func (_ Statement) Having(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Initialize(_ *DB) error {
return nil
}
func (_ Statement) InnerJoins(_ string, _ ...interface{}) *DB {
return nil
}
func (_ Statement) InstanceGet(_ string) (interface{}, bool) {
return nil, false
}
func (_ Statement) InstanceSet(_ string, _ interface{}) *DB {
return nil
}
func (_ Statement) Last(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Limit(_ int) *DB {
return nil
}
func (_ Statement) MapColumns(_ map[string]string) *DB {
return nil
}
func (_ Statement) Migrator() Migrator {
return nil
}
func (_ Statement) Name() string {
return ""
}
func (_ Statement) Not(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Offset(_ int) *DB {
return nil
}
func (_ Statement) Omit(_ ...string) *DB {
return nil
}
func (_ Statement) Or(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Order(_ interface{}) *DB {
return nil
}
func (_ Statement) Pluck(_ string, _ interface{}) *DB {
return nil
}
func (_ Statement) Preload(_ string, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Raw(_ string, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Rollback() *DB {
return nil
}
func (_ Statement) RollbackTo(_ string) *DB {
return nil
}
func (_ Statement) Row() *sql.Row {
return nil
}
func (_ Statement) Rows() (*sql.Rows, error) {
return nil, nil
}
func (_ Statement) Save(_ interface{}) *DB {
return nil
}
func (_ Statement) SavePoint(_ string) *DB {
return nil
}
func (_ Statement) Scan(_ interface{}) *DB {
return nil
}
func (_ Statement) ScanRows(_ *sql.Rows, _ interface{}) error {
return nil
}
func (_ Statement) Scopes(_ ...func(*DB) *DB) *DB {
return nil
}
func (_ Statement) Select(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) Session(_ *Session) *DB {
return nil
}
func (_ Statement) Set(_ string, _ interface{}) *DB {
return nil
}
func (_ Statement) SetupJoinTable(_ interface{}, _ string, _ interface{}) error {
return nil
}
func (_ Statement) Take(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) ToSQL(_ func(*DB) *DB) string {
return ""
}
func (_ Statement) Transaction(_ func(*DB) error, _ ...*sql.TxOptions) error {
return nil
}
func (_ Statement) Update(_ string, _ interface{}) *DB {
return nil
}
func (_ Statement) UpdateColumn(_ string, _ interface{}) *DB {
return nil
}
func (_ Statement) UpdateColumns(_ interface{}) *DB {
return nil
}
func (_ Statement) Updates(_ interface{}) *DB {
return nil
}
func (_ Statement) Use(_ Plugin) error {
return nil
}
func (_ Statement) Where(_ interface{}, _ ...interface{}) *DB {
return nil
}
func (_ Statement) WithContext(_ context.Context) *DB {
return nil
}
func (_ *Statement) AddClause(_ interface{}) {}
func (_ *Statement) AddClauseIfNotExists(_ interface{}) {}
func (_ *Statement) AddVar(_ interface{}, _ ...interface{}) {}
func (_ *Statement) Build(_ ...string) {}
func (_ *Statement) BuildCondition(_ interface{}, _ ...interface{}) []interface{} {
return nil
}
func (_ *Statement) Changed(_ ...string) bool {
return false
}
func (_ *Statement) Parse(_ interface{}) error {
return nil
}
func (_ *Statement) ParseWithSpecialTableName(_ interface{}, _ string) error {
return nil
}
func (_ *Statement) Quote(_ interface{}) string {
return ""
}
func (_ *Statement) QuoteTo(_ interface{}, _ interface{}) {}
func (_ *Statement) SelectAndOmitColumns(_ bool, _ bool) (map[string]bool, bool) {
return nil, false
}
func (_ *Statement) SetColumn(_ string, _ interface{}, _ ...bool) {}
func (_ *Statement) WriteByte(_ byte) error {
return nil
}
func (_ *Statement) WriteQuoted(_ interface{}) {}
func (_ *Statement) WriteString(_ string) (int, error) {
return 0, nil
}
type TableType interface {
Comment() (string, bool)
Name() string
Schema() string
Type() string
}
type ViewOption struct {
Replace bool
CheckOption string
Query *DB
}

View File

@@ -1,9 +1,150 @@
# gorm.io/gorm v1.23.0
# github.com/astaxie/beego v1.12.3
## explicit
gorm.io/gorm
github.com/astaxie/beego/orm
# github.com/beego/beego/v2 v2.3.5
## explicit
github.com/beego/beego/v2/client/orm
# github.com/couchbase/gocb v1.6.7
## explicit
github.com/couchbase/gocb
# github.com/couchbase/gocb/v2 v2.9.4
## explicit
github.com/couchbase/gocb/v2
# github.com/jmoiron/sqlx v1.4.0
## explicit
github.com/jmoiron/sqlx
# go.mongodb.org/mongo-driver/mongo v1.17.2
# 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
# go.mongodb.org/mongo-driver v1.17.3
## explicit
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
# github.com/couchbase/gocbcoreps v0.1.3
## explicit
github.com/couchbase/gocbcoreps
# github.com/couchbase/goprotostellar v1.0.2
## explicit
github.com/couchbase/goprotostellar
# github.com/couchbaselabs/gocbconnstr/v2 v2.0.0-20240607131231-fb385523de28
## explicit
github.com/couchbaselabs/gocbconnstr/v2
# github.com/go-logr/logr v1.4.1
## explicit
github.com/go-logr/logr
# github.com/go-logr/stdr v1.2.2
## explicit
github.com/go-logr/stdr
# github.com/golang/snappy v0.0.4
## explicit
github.com/golang/snappy
# github.com/google/uuid v1.6.0
## explicit
github.com/google/uuid
# github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
## explicit
github.com/grpc-ecosystem/go-grpc-middleware
# github.com/hashicorp/golang-lru v0.5.4
## explicit
github.com/hashicorp/golang-lru
# github.com/jinzhu/inflection v1.0.0
## explicit
github.com/jinzhu/inflection
# github.com/jinzhu/now v1.1.5
## explicit
github.com/jinzhu/now
# github.com/klauspost/compress v1.16.7
## explicit
github.com/klauspost/compress
# github.com/montanaflynn/stats v0.7.1
## explicit
github.com/montanaflynn/stats
# github.com/opentracing/opentracing-go v1.2.0
## explicit
github.com/opentracing/opentracing-go
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
# github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18
## explicit
github.com/shiena/ansicolor
# github.com/valyala/bytebufferpool v1.0.0
## explicit
github.com/valyala/bytebufferpool
# github.com/xdg-go/pbkdf2 v1.0.0
## explicit
github.com/xdg-go/pbkdf2
# github.com/xdg-go/scram v1.1.2
## explicit
github.com/xdg-go/scram
# github.com/xdg-go/stringprep v1.0.4
## explicit
github.com/xdg-go/stringprep
# github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78
## explicit
github.com/youmark/pkcs8
# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0
## explicit
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
# go.opentelemetry.io/otel v1.24.0
## explicit
go.opentelemetry.io/otel
# go.opentelemetry.io/otel/metric v1.24.0
## explicit
go.opentelemetry.io/otel/metric
# go.opentelemetry.io/otel/trace v1.24.0
## explicit
go.opentelemetry.io/otel/trace
# go.uber.org/multierr v1.11.0
## explicit
go.uber.org/multierr
# go.uber.org/zap v1.27.0
## explicit
go.uber.org/zap
# golang.org/x/crypto v0.26.0
## explicit
golang.org/x/crypto
# golang.org/x/net v0.24.0
## explicit
golang.org/x/net
# golang.org/x/sync v0.8.0
## explicit
golang.org/x/sync
# golang.org/x/sys v0.23.0
## explicit
golang.org/x/sys
# golang.org/x/text v0.17.0
## explicit
golang.org/x/text
# google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda
## explicit
google.golang.org/genproto/googleapis/rpc
# google.golang.org/grpc v1.63.2
## explicit
google.golang.org/grpc
# google.golang.org/protobuf v1.34.2
## explicit
google.golang.org/protobuf
# gopkg.in/couchbase/gocbcore.v7 v7.1.18
## explicit
gopkg.in/couchbase/gocbcore.v7
# gopkg.in/couchbaselabs/gocbconnstr.v1 v1.0.4
## explicit
gopkg.in/couchbaselabs/gocbconnstr.v1
# gopkg.in/couchbaselabs/gojcbmock.v1 v1.0.4
## explicit
gopkg.in/couchbaselabs/gojcbmock.v1
# gopkg.in/couchbaselabs/jsonx.v1 v1.0.1
## explicit
gopkg.in/couchbaselabs/jsonx.v1

View File

@@ -30,52 +30,54 @@ import (
func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
username := req.URL.Query()["username"][0]
slice := []any{"username", username}
password := req.URL.Query()["password"][0]
formatString := req.URL.Query()["formatString"][0]
testFlag := req.URL.Query()["testFlag"][0]
slice := []any{"username", username}
{
fmt.Print(username) // $ hasTaintFlow="username"
fmt.Printf(username) // $ hasTaintFlow="username"
fmt.Println(username) // $ hasTaintFlow="username"
fmt.Fprint(nil, username) // Fprint functions are only loggers if they target stdout/stderr
fmt.Fprintf(nil, username)
fmt.Fprintln(nil, username)
fmt.Print(username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
fmt.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
fmt.Println(username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
fmt.Fprint(nil, username, password) // Fprint functions are only loggers if they target stdout/stderr
fmt.Fprintf(nil, formatString, username, password)
fmt.Fprintln(nil, username, password)
}
// log
{
log.Print("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Printf("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Println("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Print("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
log.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
log.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
if testFlag == "true" {
log.Fatal("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
}
if testFlag == "true" {
log.Fatalf("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
}
if testFlag == "true" {
log.Fatalln("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
}
if testFlag == "true" {
log.Panic("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
}
if testFlag == "true" {
log.Panicf("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
}
if testFlag == "true" {
log.Panicln("user %s logged in.\n", username) // $ hasTaintFlow="username"
log.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
}
logger := log.Default()
logger.Print("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Printf("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Println("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Fatal("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Fatalf("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Fatalln("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Panic("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Panicf("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Panicln("user %s logged in.\n", username) // $ hasTaintFlow="username"
logger.Print("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
logger.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
logger.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
logger.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
logger.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
logger.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
logger.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
logger.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
logger.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
}
// k8s.io/klog
{
@@ -421,7 +423,6 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
simpleLogger.Tracew("%s", username) // $ hasTaintFlow="username"
simpleLogger.Debugw("%s %s", slice...) // $ hasTaintFlow="slice"
}
}
type Logger interface {
@@ -514,8 +515,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
verbose.Infof("user %q logged in.\n", username)
klog.Infof("user %q logged in.\n", username)
klog.Errorf("user %q logged in.\n", username)
klog.Fatalf("user %q logged in.\n", username)
klog.Exitf("user %q logged in.\n", username)
if testFlag == " true" {
klog.Fatalf("user %q logged in.\n", username)
}
if testFlag == " true" {
klog.Exitf("user %q logged in.\n", username)
}
}
// elazarl/goproxy
{
@@ -529,16 +534,24 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
glog.Infof("user %q logged in.\n", username)
glog.Errorf("user %q logged in.\n", username)
glog.Fatalf("user %q logged in.\n", username)
glog.Exitf("user %q logged in.\n", username)
if testFlag == " true" {
glog.Fatalf("user %q logged in.\n", username)
}
if testFlag == " true" {
glog.Exitf("user %q logged in.\n", username)
}
}
// sirupsen/logrus
{
logrus.Debugf("user %q logged in.\n", username)
logrus.Errorf("user %q logged in.\n", username)
logrus.Fatalf("user %q logged in.\n", username)
if testFlag == " true" {
logrus.Fatalf("user %q logged in.\n", username)
}
logrus.Infof("user %q logged in.\n", username)
logrus.Panicf("user %q logged in.\n", username)
if testFlag == " true" {
logrus.Panicf("user %q logged in.\n", username)
}
logrus.Printf("user %q logged in.\n", username)
logrus.Tracef("user %q logged in.\n", username)
logrus.Warnf("user %q logged in.\n", username)
@@ -548,10 +561,14 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
entry := logrus.WithFields(fields)
entry.Debugf("user %q logged in.\n", username)
entry.Errorf("user %q logged in.\n", username)
entry.Fatalf("user %q logged in.\n", username)
if testFlag == " true" {
entry.Fatalf("user %q logged in.\n", username)
}
entry.Infof("user %q logged in.\n", username)
entry.Logf(0, "user %q logged in.\n", username)
entry.Panicf("user %q logged in.\n", username)
if testFlag == " true" {
entry.Panicf("user %q logged in.\n", username)
}
entry.Printf("user %q logged in.\n", username)
entry.Tracef("user %q logged in.\n", username)
entry.Warnf("user %q logged in.\n", username)
@@ -560,10 +577,14 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
logger := entry.Logger
logger.Debugf("user %q logged in.\n", username)
logger.Errorf("user %q logged in.\n", username)
logger.Fatalf("user %q logged in.\n", username)
if testFlag == " true" {
logger.Fatalf("user %q logged in.\n", username)
}
logger.Infof("user %q logged in.\n", username)
logger.Logf(0, "user %q logged in.\n", username)
logger.Panicf("user %q logged in.\n", username)
if testFlag == " true" {
logger.Panicf("user %q logged in.\n", username)
}
logger.Printf("user %q logged in.\n", username)
logger.Tracef("user %q logged in.\n", username)
logger.Warnf("user %q logged in.\n", username)
@@ -599,8 +620,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
verbose.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
klog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
klog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
klog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
klog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
klog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
if testFlag == " true" {
klog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
}
// elazarl/goproxy
{
@@ -614,16 +639,24 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
glog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
glog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
glog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
glog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
glog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
if testFlag == " true" {
glog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
}
// sirupsen/logrus
{
logrus.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
logrus.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
logrus.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
logrus.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
logrus.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Tracef("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logrus.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
@@ -631,24 +664,32 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
fields := make(logrus.Fields)
entry := logrus.WithFields(fields)
entry.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
entry.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
entry.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
entry.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
entry.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Tracef("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
entry.Warningf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger := entry.Logger
logger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
logger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
logger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
if testFlag == " true" {
logger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
logger.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Tracef("user %#q logged in.\n", username) // $ hasTaintFlow="username"
logger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
@@ -677,3 +718,9 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
sLogger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
}
}
// GOOD: User-provided values formatted using a %T directive, which prints the type of the argument
func handlerGood5(req *http.Request) {
object := req.URL.Query()["username"][0]
log.Printf("found object of type %T.\n", object)
}

View File

@@ -1,35 +1,35 @@
#select
| klog.go:22:15:22:20 | header | klog.go:20:30:20:37 | selection of Header | klog.go:22:15:22:20 | header | $@ flows to a logging call. | klog.go:20:30:20:37 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:28:13:28:41 | call to Get | klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | $@ flows to a logging call. | klog.go:28:13:28:20 | selection of Header | Sensitive data returned by HTTP request headers |
| main.go:15:12:15:19 | password | main.go:15:12:15:19 | password | main.go:15:12:15:19 | password | $@ flows to a logging call. | main.go:15:12:15:19 | password | Sensitive data returned by an access to password |
| main.go:16:17:16:24 | password | main.go:16:17:16:24 | password | main.go:16:17:16:24 | password | $@ flows to a logging call. | main.go:16:17:16:24 | password | Sensitive data returned by an access to password |
| main.go:17:13:17:20 | password | main.go:17:13:17:20 | password | main.go:17:13:17:20 | password | $@ flows to a logging call. | main.go:17:13:17:20 | password | Sensitive data returned by an access to password |
| main.go:18:14:18:21 | password | main.go:18:14:18:21 | password | main.go:18:14:18:21 | password | $@ flows to a logging call. | main.go:18:14:18:21 | password | Sensitive data returned by an access to password |
| main.go:19:12:19:19 | password | main.go:19:12:19:19 | password | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:19:12:19:19 | password | Sensitive data returned by an access to password |
| main.go:20:17:20:24 | password | main.go:20:17:20:24 | password | main.go:20:17:20:24 | password | $@ flows to a logging call. | main.go:20:17:20:24 | password | Sensitive data returned by an access to password |
| main.go:21:13:21:20 | password | main.go:21:13:21:20 | password | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:21:13:21:20 | password | Sensitive data returned by an access to password |
| main.go:22:14:22:21 | password | main.go:22:14:22:21 | password | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:22:14:22:21 | password | Sensitive data returned by an access to password |
| main.go:23:12:23:19 | password | main.go:23:12:23:19 | password | main.go:23:12:23:19 | password | $@ flows to a logging call. | main.go:23:12:23:19 | password | Sensitive data returned by an access to password |
| main.go:24:17:24:24 | password | main.go:24:17:24:24 | password | main.go:24:17:24:24 | password | $@ flows to a logging call. | main.go:24:17:24:24 | password | Sensitive data returned by an access to password |
| main.go:25:13:25:20 | password | main.go:25:13:25:20 | password | main.go:25:13:25:20 | password | $@ flows to a logging call. | main.go:25:13:25:20 | password | Sensitive data returned by an access to password |
| main.go:26:14:26:21 | password | main.go:26:14:26:21 | password | main.go:26:14:26:21 | password | $@ flows to a logging call. | main.go:26:14:26:21 | password | Sensitive data returned by an access to password |
| main.go:27:16:27:23 | password | main.go:27:16:27:23 | password | main.go:27:16:27:23 | password | $@ flows to a logging call. | main.go:27:16:27:23 | password | Sensitive data returned by an access to password |
| main.go:30:10:30:17 | password | main.go:30:10:30:17 | password | main.go:30:10:30:17 | password | $@ flows to a logging call. | main.go:30:10:30:17 | password | Sensitive data returned by an access to password |
| main.go:31:15:31:22 | password | main.go:31:15:31:22 | password | main.go:31:15:31:22 | password | $@ flows to a logging call. | main.go:31:15:31:22 | password | Sensitive data returned by an access to password |
| main.go:32:11:32:18 | password | main.go:32:11:32:18 | password | main.go:32:11:32:18 | password | $@ flows to a logging call. | main.go:32:11:32:18 | password | Sensitive data returned by an access to password |
| main.go:33:12:33:19 | password | main.go:33:12:33:19 | password | main.go:33:12:33:19 | password | $@ flows to a logging call. | main.go:33:12:33:19 | password | Sensitive data returned by an access to password |
| main.go:34:10:34:17 | password | main.go:34:10:34:17 | password | main.go:34:10:34:17 | password | $@ flows to a logging call. | main.go:34:10:34:17 | password | Sensitive data returned by an access to password |
| main.go:35:15:35:22 | password | main.go:35:15:35:22 | password | main.go:35:15:35:22 | password | $@ flows to a logging call. | main.go:35:15:35:22 | password | Sensitive data returned by an access to password |
| main.go:36:11:36:18 | password | main.go:36:11:36:18 | password | main.go:36:11:36:18 | password | $@ flows to a logging call. | main.go:36:11:36:18 | password | Sensitive data returned by an access to password |
| main.go:37:12:37:19 | password | main.go:37:12:37:19 | password | main.go:37:12:37:19 | password | $@ flows to a logging call. | main.go:37:12:37:19 | password | Sensitive data returned by an access to password |
| main.go:38:10:38:17 | password | main.go:38:10:38:17 | password | main.go:38:10:38:17 | password | $@ flows to a logging call. | main.go:38:10:38:17 | password | Sensitive data returned by an access to password |
| main.go:39:15:39:22 | password | main.go:39:15:39:22 | password | main.go:39:15:39:22 | password | $@ flows to a logging call. | main.go:39:15:39:22 | password | Sensitive data returned by an access to password |
| main.go:40:11:40:18 | password | main.go:40:11:40:18 | password | main.go:40:11:40:18 | password | $@ flows to a logging call. | main.go:40:11:40:18 | password | Sensitive data returned by an access to password |
| main.go:41:12:41:19 | password | main.go:41:12:41:19 | password | main.go:41:12:41:19 | password | $@ flows to a logging call. | main.go:41:12:41:19 | password | Sensitive data returned by an access to password |
| main.go:42:14:42:21 | password | main.go:42:14:42:21 | password | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:42:14:42:21 | password | Sensitive data returned by an access to password |
| main.go:44:12:44:19 | password | main.go:44:12:44:19 | password | main.go:44:12:44:19 | password | $@ flows to a logging call. | main.go:44:12:44:19 | password | Sensitive data returned by an access to password |
| main.go:45:17:45:24 | password | main.go:45:17:45:24 | password | main.go:45:17:45:24 | password | $@ flows to a logging call. | main.go:45:17:45:24 | password | Sensitive data returned by an access to password |
| main.go:52:35:52:42 | password | main.go:52:35:52:42 | password | main.go:52:35:52:42 | password | $@ flows to a logging call. | main.go:52:35:52:42 | password | Sensitive data returned by an access to password |
| klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers |
| main.go:16:12:16:19 | password | main.go:16:12:16:19 | password | main.go:16:12:16:19 | password | $@ flows to a logging call. | main.go:16:12:16:19 | password | Sensitive data returned by an access to password |
| main.go:17:19:17:26 | password | main.go:17:19:17:26 | password | main.go:17:19:17:26 | password | $@ flows to a logging call. | main.go:17:19:17:26 | password | Sensitive data returned by an access to password |
| main.go:18:13:18:20 | password | main.go:18:13:18:20 | password | main.go:18:13:18:20 | password | $@ flows to a logging call. | main.go:18:13:18:20 | password | Sensitive data returned by an access to password |
| main.go:19:14:19:21 | password | main.go:19:14:19:21 | password | main.go:19:14:19:21 | password | $@ flows to a logging call. | main.go:19:14:19:21 | password | Sensitive data returned by an access to password |
| main.go:20:12:20:19 | password | main.go:20:12:20:19 | password | main.go:20:12:20:19 | password | $@ flows to a logging call. | main.go:20:12:20:19 | password | Sensitive data returned by an access to password |
| main.go:21:19:21:26 | password | main.go:21:19:21:26 | password | main.go:21:19:21:26 | password | $@ flows to a logging call. | main.go:21:19:21:26 | password | Sensitive data returned by an access to password |
| main.go:22:13:22:20 | password | main.go:22:13:22:20 | password | main.go:22:13:22:20 | password | $@ flows to a logging call. | main.go:22:13:22:20 | password | Sensitive data returned by an access to password |
| main.go:23:14:23:21 | password | main.go:23:14:23:21 | password | main.go:23:14:23:21 | password | $@ flows to a logging call. | main.go:23:14:23:21 | password | Sensitive data returned by an access to password |
| main.go:24:12:24:19 | password | main.go:24:12:24:19 | password | main.go:24:12:24:19 | password | $@ flows to a logging call. | main.go:24:12:24:19 | password | Sensitive data returned by an access to password |
| main.go:25:19:25:26 | password | main.go:25:19:25:26 | password | main.go:25:19:25:26 | password | $@ flows to a logging call. | main.go:25:19:25:26 | password | Sensitive data returned by an access to password |
| main.go:26:13:26:20 | password | main.go:26:13:26:20 | password | main.go:26:13:26:20 | password | $@ flows to a logging call. | main.go:26:13:26:20 | password | Sensitive data returned by an access to password |
| main.go:27:14:27:21 | password | main.go:27:14:27:21 | password | main.go:27:14:27:21 | password | $@ flows to a logging call. | main.go:27:14:27:21 | password | Sensitive data returned by an access to password |
| main.go:28:16:28:23 | password | main.go:28:16:28:23 | password | main.go:28:16:28:23 | password | $@ flows to a logging call. | main.go:28:16:28:23 | password | Sensitive data returned by an access to password |
| main.go:32:10:32:17 | password | main.go:32:10:32:17 | password | main.go:32:10:32:17 | password | $@ flows to a logging call. | main.go:32:10:32:17 | password | Sensitive data returned by an access to password |
| main.go:33:17:33:24 | password | main.go:33:17:33:24 | password | main.go:33:17:33:24 | password | $@ flows to a logging call. | main.go:33:17:33:24 | password | Sensitive data returned by an access to password |
| main.go:34:11:34:18 | password | main.go:34:11:34:18 | password | main.go:34:11:34:18 | password | $@ flows to a logging call. | main.go:34:11:34:18 | password | Sensitive data returned by an access to password |
| main.go:35:12:35:19 | password | main.go:35:12:35:19 | password | main.go:35:12:35:19 | password | $@ flows to a logging call. | main.go:35:12:35:19 | password | Sensitive data returned by an access to password |
| main.go:36:10:36:17 | password | main.go:36:10:36:17 | password | main.go:36:10:36:17 | password | $@ flows to a logging call. | main.go:36:10:36:17 | password | Sensitive data returned by an access to password |
| main.go:37:17:37:24 | password | main.go:37:17:37:24 | password | main.go:37:17:37:24 | password | $@ flows to a logging call. | main.go:37:17:37:24 | password | Sensitive data returned by an access to password |
| main.go:38:11:38:18 | password | main.go:38:11:38:18 | password | main.go:38:11:38:18 | password | $@ flows to a logging call. | main.go:38:11:38:18 | password | Sensitive data returned by an access to password |
| main.go:39:12:39:19 | password | main.go:39:12:39:19 | password | main.go:39:12:39:19 | password | $@ flows to a logging call. | main.go:39:12:39:19 | password | Sensitive data returned by an access to password |
| main.go:40:10:40:17 | password | main.go:40:10:40:17 | password | main.go:40:10:40:17 | password | $@ flows to a logging call. | main.go:40:10:40:17 | password | Sensitive data returned by an access to password |
| main.go:41:17:41:24 | password | main.go:41:17:41:24 | password | main.go:41:17:41:24 | password | $@ flows to a logging call. | main.go:41:17:41:24 | password | Sensitive data returned by an access to password |
| main.go:42:11:42:18 | password | main.go:42:11:42:18 | password | main.go:42:11:42:18 | password | $@ flows to a logging call. | main.go:42:11:42:18 | password | Sensitive data returned by an access to password |
| main.go:43:12:43:19 | password | main.go:43:12:43:19 | password | main.go:43:12:43:19 | password | $@ flows to a logging call. | main.go:43:12:43:19 | password | Sensitive data returned by an access to password |
| main.go:44:14:44:21 | password | main.go:44:14:44:21 | password | main.go:44:14:44:21 | password | $@ flows to a logging call. | main.go:44:14:44:21 | password | Sensitive data returned by an access to password |
| main.go:47:12:47:19 | password | main.go:47:12:47:19 | password | main.go:47:12:47:19 | password | $@ flows to a logging call. | main.go:47:12:47:19 | password | Sensitive data returned by an access to password |
| main.go:48:17:48:24 | password | main.go:48:17:48:24 | password | main.go:48:17:48:24 | password | $@ flows to a logging call. | main.go:48:17:48:24 | password | Sensitive data returned by an access to password |
| main.go:55:35:55:42 | password | main.go:55:35:55:42 | password | main.go:55:35:55:42 | password | $@ flows to a logging call. | main.go:55:35:55:42 | password | Sensitive data returned by an access to password |
| overrides.go:13:14:13:23 | call to String | overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:9:9:9:16 | password | Sensitive data returned by an access to password |
| passwords.go:9:14:9:14 | x | passwords.go:30:8:30:15 | password | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:30:8:30:15 | password | Sensitive data returned by an access to password |
| passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:25:14:25:21 | password | Sensitive data returned by an access to password |
@@ -55,11 +55,11 @@
| passwords.go:127:14:127:21 | selection of y | passwords.go:122:13:122:25 | call to getPassword | passwords.go:127:14:127:21 | selection of y | $@ flows to a logging call. | passwords.go:122:13:122:25 | call to getPassword | Sensitive data returned by a call to getPassword |
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:12:22:12:29 | password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:12:22:12:29 | password | Sensitive data returned by an access to password |
edges
| klog.go:20:3:25:3 | range statement[1] | klog.go:21:27:21:33 | headers | provenance | |
| klog.go:20:30:20:37 | selection of Header | klog.go:20:3:25:3 | range statement[1] | provenance | Src:MaD:1 Config |
| klog.go:21:4:24:4 | range statement[1] | klog.go:22:15:22:20 | header | provenance | |
| klog.go:21:27:21:33 | headers | klog.go:21:4:24:4 | range statement[1] | provenance | Config |
| klog.go:28:13:28:20 | selection of Header | klog.go:28:13:28:41 | call to Get | provenance | Src:MaD:1 Config |
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:1 Config |
| klog.go:22:4:25:4 | range statement[1] | klog.go:23:15:23:20 | header | provenance | |
| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | range statement[1] | provenance | Config |
| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:1 Config |
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | |
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | |
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | |
@@ -101,42 +101,42 @@ edges
models
| 1 | Source: net/http; Request; true; Header; ; ; ; remote; manual |
nodes
| klog.go:20:3:25:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:20:30:20:37 | selection of Header | semmle.label | selection of Header |
| klog.go:21:4:24:4 | range statement[1] | semmle.label | range statement[1] |
| klog.go:21:27:21:33 | headers | semmle.label | headers |
| klog.go:22:15:22:20 | header | semmle.label | header |
| klog.go:28:13:28:20 | selection of Header | semmle.label | selection of Header |
| klog.go:28:13:28:41 | call to Get | semmle.label | call to Get |
| main.go:15:12:15:19 | password | semmle.label | password |
| main.go:16:17:16:24 | password | semmle.label | password |
| main.go:17:13:17:20 | password | semmle.label | password |
| main.go:18:14:18:21 | password | semmle.label | password |
| main.go:19:12:19:19 | password | semmle.label | password |
| main.go:20:17:20:24 | password | semmle.label | password |
| main.go:21:13:21:20 | password | semmle.label | password |
| main.go:22:14:22:21 | password | semmle.label | password |
| main.go:23:12:23:19 | password | semmle.label | password |
| main.go:24:17:24:24 | password | semmle.label | password |
| main.go:25:13:25:20 | password | semmle.label | password |
| main.go:26:14:26:21 | password | semmle.label | password |
| main.go:27:16:27:23 | password | semmle.label | password |
| main.go:30:10:30:17 | password | semmle.label | password |
| main.go:31:15:31:22 | password | semmle.label | password |
| main.go:32:11:32:18 | password | semmle.label | password |
| main.go:33:12:33:19 | password | semmle.label | password |
| main.go:34:10:34:17 | password | semmle.label | password |
| main.go:35:15:35:22 | password | semmle.label | password |
| main.go:36:11:36:18 | password | semmle.label | password |
| main.go:37:12:37:19 | password | semmle.label | password |
| main.go:38:10:38:17 | password | semmle.label | password |
| main.go:39:15:39:22 | password | semmle.label | password |
| main.go:40:11:40:18 | password | semmle.label | password |
| main.go:41:12:41:19 | password | semmle.label | password |
| main.go:42:14:42:21 | password | semmle.label | password |
| main.go:44:12:44:19 | password | semmle.label | password |
| main.go:45:17:45:24 | password | semmle.label | password |
| main.go:52:35:52:42 | password | semmle.label | password |
| klog.go:21:3:26:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header |
| klog.go:22:4:25:4 | range statement[1] | semmle.label | range statement[1] |
| klog.go:22:27:22:33 | headers | semmle.label | headers |
| klog.go:23:15:23:20 | header | semmle.label | header |
| klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |
| klog.go:29:13:29:41 | call to Get | semmle.label | call to Get |
| main.go:16:12:16:19 | password | semmle.label | password |
| main.go:17:19:17:26 | password | semmle.label | password |
| main.go:18:13:18:20 | password | semmle.label | password |
| main.go:19:14:19:21 | password | semmle.label | password |
| main.go:20:12:20:19 | password | semmle.label | password |
| main.go:21:19:21:26 | password | semmle.label | password |
| main.go:22:13:22:20 | password | semmle.label | password |
| main.go:23:14:23:21 | password | semmle.label | password |
| main.go:24:12:24:19 | password | semmle.label | password |
| main.go:25:19:25:26 | password | semmle.label | password |
| main.go:26:13:26:20 | password | semmle.label | password |
| main.go:27:14:27:21 | password | semmle.label | password |
| main.go:28:16:28:23 | password | semmle.label | password |
| main.go:32:10:32:17 | password | semmle.label | password |
| main.go:33:17:33:24 | password | semmle.label | password |
| main.go:34:11:34:18 | password | semmle.label | password |
| main.go:35:12:35:19 | password | semmle.label | password |
| main.go:36:10:36:17 | password | semmle.label | password |
| main.go:37:17:37:24 | password | semmle.label | password |
| main.go:38:11:38:18 | password | semmle.label | password |
| main.go:39:12:39:19 | password | semmle.label | password |
| main.go:40:10:40:17 | password | semmle.label | password |
| main.go:41:17:41:24 | password | semmle.label | password |
| main.go:42:11:42:18 | password | semmle.label | password |
| main.go:43:12:43:19 | password | semmle.label | password |
| main.go:44:14:44:21 | password | semmle.label | password |
| main.go:47:12:47:19 | password | semmle.label | password |
| main.go:48:17:48:24 | password | semmle.label | password |
| main.go:55:35:55:42 | password | semmle.label | password |
| overrides.go:9:9:9:16 | password | semmle.label | password |
| overrides.go:13:14:13:23 | call to String | semmle.label | call to String |
| passwords.go:8:12:8:12 | definition of x | semmle.label | definition of x |

View File

@@ -1,2 +1,4 @@
query: Security/CWE-312/CleartextLogging.ql
postprocess: utils/test/PrettyPrintModels.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -3,9 +3,10 @@ package main
//go:generate depstubber -vendor k8s.io/klog "" Info
import (
"k8s.io/klog"
"net/http"
"strings"
"k8s.io/klog"
)
func mask(key, value string) string {
@@ -17,15 +18,15 @@ func mask(key, value string) string {
func klogTest() {
http.HandleFunc("/klog", func(w http.ResponseWriter, r *http.Request) {
for name, headers := range r.Header {
for name, headers := range r.Header { // $ Source
for _, header := range headers {
klog.Info(header) // NOT OK
klog.Info(header) // $ Alert
klog.Info(mask(name, header)) // OK
}
}
klog.Info(r.Header.Get("Accept")) // OK
klog.Info(r.Header["Content-Type"]) // OK
klog.Info(r.Header.Get("Authorization")) // NOT OK
klog.Info(r.Header.Get("Authorization")) // $ Alert
})
http.ListenAndServe(":80", nil)
}

View File

@@ -4,51 +4,54 @@ package main
//go:generate depstubber -vendor github.com/golang/glog "" Info
import (
"log"
"github.com/golang/glog"
"github.com/sirupsen/logrus"
"log"
)
func main() {
password := "P4ssw0rd"
log.Print(password)
log.Printf("", password)
log.Printf(password, "")
log.Println(password)
log.Fatal(password)
log.Fatalf("", password)
log.Fatalf(password, "")
log.Fatalln(password)
log.Panic(password)
log.Panicf("", password)
log.Panicf(password, "")
log.Panicln(password)
log.Output(0, password)
log.Print(password) // $ Alert
log.Printf("%s", password) // $ Alert
log.Printf(password, "") // $ Alert
log.Println(password) // $ Alert
log.Fatal(password) // $ Alert
log.Fatalf("%s", password) // $ Alert
log.Fatalf(password, "") // $ Alert
log.Fatalln(password) // $ Alert
log.Panic(password) // $ Alert
log.Panicf("%s", password) // $ Alert
log.Panicf(password, "") // $ Alert
log.Panicln(password) // $ Alert
log.Output(0, password) // $ Alert
log.Printf("%T", password)
l := log.Default()
l.Print(password)
l.Printf("", password)
l.Printf(password, "")
l.Println(password)
l.Fatal(password)
l.Fatalf("", password)
l.Fatalf(password, "")
l.Fatalln(password)
l.Panic(password)
l.Panicf("", password)
l.Panicf(password, "")
l.Panicln(password)
l.Output(0, password)
l.Print(password) // $ Alert
l.Printf("%s", password) // $ Alert
l.Printf(password, "") // $ Alert
l.Println(password) // $ Alert
l.Fatal(password) // $ Alert
l.Fatalf("%s", password) // $ Alert
l.Fatalf(password, "") // $ Alert
l.Fatalln(password) // $ Alert
l.Panic(password) // $ Alert
l.Panicf("%s", password) // $ Alert
l.Panicf(password, "") // $ Alert
l.Panicln(password) // $ Alert
l.Output(0, password) // $ Alert
l.Printf("%T", password)
glog.Info(password)
logrus.Warning(password)
glog.Info(password) // $ Alert
logrus.Warning(password) // $ Alert
fields := make(logrus.Fields)
fields["pass"] = password
entry := logrus.WithFields(fields)
entry.Errorf("")
entry = logrus.WithField("pass", password)
entry = logrus.WithField("pass", password) // $ Alert
entry.Panic("")
}

View File

@@ -6,10 +6,10 @@ type s struct{}
func (_ s) String() string {
password := "horsebatterystaplecorrect"
return password
return password // $ Source
}
func overrideTest(x s, y fmt.Stringer) {
fmt.Println(x.String()) // NOT OK
fmt.Println(x.String()) // $ Alert
fmt.Println(y.String()) // OK
}

View File

@@ -6,7 +6,7 @@ import (
)
func myLog(x string) {
log.Println(x) // NOT OK
log.Println(x) // $ Alert
}
func redact(kind, value string) string {
@@ -22,33 +22,33 @@ func test() {
x := "horsebatterystapleincorrect"
var o passStruct
log.Println(password) // NOT OK
log.Println(o.password) // NOT OK
log.Println(getPassword()) // NOT OK
log.Println(o.getPassword()) // NOT OK
log.Println(password) // $ Alert
log.Println(o.password) // $ Alert
log.Println(getPassword()) // $ Alert
log.Println(o.getPassword()) // $ Alert
myLog(password)
myLog(password) // $ Source
log.Panic(password) // NOT OK
log.Panic(password) // $ Alert
log.Println(name + ", " + password) // NOT OK
log.Println(name + ", " + password) // $ Alert
obj1 := passStruct{
password: x,
password: x, // $ Source
}
log.Println(obj1) // NOT OK
log.Println(obj1) // $ Alert
obj2 := xStruct{
x: password,
x: password, // $ Source
}
log.Println(obj2) // NOT OK
log.Println(obj2) // $ Alert
var obj3 xStruct
log.Println(obj3) // caught because of the below line
obj3.x = password // NOT OK
log.Println(obj3) // $ SPURIOUS: Alert // caught because of the below line and def-use flow
obj3.x = password // $ Source
fixed_password := "cowbatterystaplecorrect"
log.Println(fixed_password) // Probably OK, but caught
log.Println(fixed_password) // $ Alert // Probably OK
log.Println(IncorrectPasswordError) // OK
@@ -83,12 +83,12 @@ func test() {
log.Println(password_sha) // OK
utilityObject := passSetStruct{
passwordSet: make(map[string]bool),
passwordSet: make(map[string]bool), // $ Source
}
log.Println(utilityObject) // NOT OK
log.Println(utilityObject) // $ Alert
secret := password
log.Printf("pw: %s", secret) // NOT OK
secret := password // $ Source
log.Printf("pw: %s", secret) // $ Alert
log.Println("Password is: " + redact("password", password))
@@ -98,33 +98,33 @@ func test() {
if t.test(y) {
f()
// ...
log.Println("Password is: " + password) // NOT OK
log.Println("Password is: " + password) // $ Alert
// ...
}
if t.test(y) {
if f() {
log.Println("Password is: " + password) // NOT OK
log.Println("Password is: " + password) // $ Alert
}
}
if os.Getenv("APP_ENV") != "production" {
log.Println("Password is: " + password) // OK, but still flagged
log.Println("Password is: " + password) // $ SPURIOUS: Alert
}
var password1 stringable = stringable{"arstneio"}
log.Println(name + ", " + password1.String()) // NOT OK
log.Println(name + ", " + password1.String()) // $ Alert
config := Config{
password: x,
password: x, // $ Source
hostname: "tarski",
x: password,
y: getPassword(),
x: password, // $ Source
y: getPassword(), // $ Source
}
log.Println(config.hostname) // OK
log.Println(config) // NOT OK
log.Println(config.x) // NOT OK
log.Println(config.y) // NOT OK
log.Println(config) // $ Alert
log.Println(config.x) // $ Alert
log.Println(config.y) // $ Alert
obj4 := xStruct{
x: "aaaaa",

View File

@@ -9,8 +9,8 @@ func testProtobuf() {
password := "P@ssw0rd"
query := &query.Query{}
query.Description = password
query.Description = password // $ Source
log.Println(query.GetDescription()) // NOT OK
log.Println(query.GetDescription()) // $ Alert
log.Println(query.GetId()) // OK
}

View File

@@ -66,6 +66,19 @@ class TestClass extends Class {
}
}
/**
* A class that is likely a test class. That is either a definite test class, or
* a class whose name, package, or location suggests that it might be a test class.
*/
class LikelyTestClass extends Class {
LikelyTestClass() {
this instanceof TestClass or
this.getName().toLowerCase().matches("%test%") or
this.getPackage().getName().toLowerCase().matches("%test%") or
this.getLocation().getFile().getAbsolutePath().matches("%/src/test/java%")
}
}
/**
* A test method declared within a JUnit 3.8 test class.
*/
@@ -185,6 +198,37 @@ class TestMethod extends Method {
}
}
/**
* A method that is likely a test method.
*/
class LikelyTestMethod extends Method {
LikelyTestMethod() {
this.getDeclaringType() instanceof LikelyTestClass
or
this instanceof TestMethod
or
this instanceof LikelyJunitTest
}
}
/**
* A `Method` that is public, has no parameters,
* has a "void" return type, AND either has a name that starts with "test" OR
* has an annotation that ends with "Test"
*/
class LikelyJunitTest extends Method {
LikelyJunitTest() {
this.isPublic() and
this.getReturnType().hasName("void") and
this.hasNoParameters() and
(
this.getName().matches("JUnit%") or
this.getName().matches("test%") or
this.getAnAnnotation().getType().getName().matches("%Test")
)
}
}
/**
* A TestNG annotation used to mark a method that runs "before".
*/

View File

@@ -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>;

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