pi-lens 3.8.73 → 3.8.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1116 -0
- package/README.md +37 -21
- package/dist/clients/atomic-write.js +3 -3
- package/dist/clients/bus-events-logger.js +5 -1
- package/dist/clients/cache/rule-cache.js +43 -2
- package/dist/clients/cache-observability.js +211 -0
- package/dist/clients/call-graph.js +20 -0
- package/dist/clients/cascade-logger.js +5 -1
- package/dist/clients/complexity-client.js +4 -7
- package/dist/clients/dependency-checker.js +151 -20
- package/dist/clients/diagnostic-dispositions.js +22 -2
- package/dist/clients/dispatch/auxiliary-lsp.js +34 -0
- package/dist/clients/dispatch/dispatcher.js +16 -1
- package/dist/clients/dispatch/fact-store.js +11 -0
- package/dist/clients/dispatch/facts/function-facts.js +14 -0
- package/dist/clients/dispatch/facts/import-facts.js +100 -101
- package/dist/clients/dispatch/facts/tree-sitter-facts.js +5 -8
- package/dist/clients/dispatch/facts/try-catch-facts.js +13 -0
- package/dist/clients/dispatch/integration.js +94 -15
- package/dist/clients/dispatch/rules/async-noise.js +1 -0
- package/dist/clients/dispatch/rules/unsafe-boundary.js +7 -0
- package/dist/clients/dispatch/runners/ast-grep-napi.js +24 -1
- package/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -1
- package/dist/clients/dispatch/runners/tree-sitter.js +153 -166
- package/dist/clients/dispatch/runners/utils/runner-helpers.js +17 -18
- package/dist/clients/feature-hints.js +53 -7
- package/dist/clients/file-kinds.js +86 -31
- package/dist/clients/fix-worklog.js +14 -2
- package/dist/clients/generated-artifacts.js +21 -0
- package/dist/clients/gzip-stage-write.js +84 -0
- package/dist/clients/installer/index.js +358 -129
- package/dist/clients/knip-client.js +64 -1
- package/dist/clients/language-profile.js +61 -72
- package/dist/clients/latency-logger.js +6 -16
- package/dist/clients/lens-config.js +128 -165
- package/dist/clients/lens-engine.js +39 -5
- package/dist/clients/lens-flag-registry.js +285 -0
- package/dist/clients/lens-map.js +2 -7
- package/dist/clients/log-cleanup.js +6 -17
- package/dist/clients/lsp/cascade-tier.js +22 -2
- package/dist/clients/lsp/client.js +74 -10
- package/dist/clients/lsp/config.js +62 -9
- package/dist/clients/lsp/index.js +34 -24
- package/dist/clients/lsp/language.js +4 -1
- package/dist/clients/lsp/launch.js +8 -6
- package/dist/clients/lsp/server.js +84 -29
- package/dist/clients/lsp-document-symbols.js +112 -0
- package/dist/clients/mcp/analyze.js +5 -4
- package/dist/clients/mcp/review.js +36 -3
- package/dist/clients/module-report.js +100 -80
- package/dist/clients/ndjson-logger.js +51 -21
- package/dist/clients/path-keyed-map.js +76 -0
- package/dist/clients/path-utils.js +35 -0
- package/dist/clients/performance-report.js +327 -0
- package/dist/clients/pipeline.js +7 -0
- package/dist/clients/project-changes.js +77 -4
- package/dist/clients/project-diagnostics/extractors.js +26 -115
- package/dist/clients/project-diagnostics/fresh-fetch.js +149 -19
- package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +109 -0
- package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +37 -5
- package/dist/clients/project-diagnostics/scanner.js +247 -127
- package/dist/clients/project-lens-config.js +53 -26
- package/dist/clients/project-report.js +39 -14
- package/dist/clients/project-scale.js +8 -10
- package/dist/clients/project-snapshot-persist-worker.js +6 -0
- package/dist/clients/project-snapshot.js +611 -7
- package/dist/clients/quiet-window.js +9 -1
- package/dist/clients/read-expansion.js +22 -12
- package/dist/clients/read-guard.js +78 -0
- package/dist/clients/redact/secrets.js +449 -0
- package/dist/clients/resource-sampler.js +133 -14
- package/dist/clients/reverse-deps.js +48 -0
- package/dist/clients/review-graph/builder.js +1522 -179
- package/dist/clients/review-graph/persist-worker.js +10 -0
- package/dist/clients/review-graph/query.js +5 -0
- package/dist/clients/review-graph/shared-extraction-ir.js +90 -0
- package/dist/clients/review-graph-logger.js +24 -0
- package/dist/clients/runtime-agent-end.js +4 -2
- package/dist/clients/runtime-coordinator.js +2 -2
- package/dist/clients/runtime-session.js +433 -59
- package/dist/clients/runtime-tool-call.js +46 -14
- package/dist/clients/runtime-turn.js +97 -26
- package/dist/clients/safe-spawn.js +102 -15
- package/dist/clients/session-start-observability.js +15 -0
- package/dist/clients/session-state-store.js +2 -1
- package/dist/clients/sessionstart-logger.js +18 -0
- package/dist/clients/sg-runner.js +48 -33
- package/dist/clients/source-filter.js +49 -25
- package/dist/clients/startup-marker.js +6 -0
- package/dist/clients/startup-timing.js +9 -0
- package/dist/clients/todo-scanner.js +30 -3
- package/dist/clients/tree-sitter-cache.js +147 -139
- package/dist/clients/tree-sitter-client.js +1340 -67
- package/dist/clients/tree-sitter-logger.js +43 -1
- package/dist/clients/tree-sitter-query-loader.js +110 -11
- package/dist/clients/tree-sitter-shared.js +43 -19
- package/dist/clients/tree-sitter-symbol-extractor.js +71 -4
- package/dist/clients/widget-state.js +50 -14
- package/dist/clients/word-index-logger.js +44 -0
- package/dist/clients/word-index.js +252 -35
- package/dist/clients/workspace-topology.js +11 -1
- package/dist/index.js +45544 -39255
- package/dist/mcp/analyze-cli.js +3 -0
- package/dist/mcp/cli.js +110 -0
- package/dist/mcp/server.js +63 -8
- package/dist/tools/lens-diagnostics.js +47 -5
- package/dist/tools/lsp-navigation.js +5 -28
- package/dist/tools/symbol-search.js +21 -2
- package/docs/agent-guide.md +247 -0
- package/docs/astplayground.md +3 -4
- package/docs/audit1.md +5 -5
- package/docs/environment-variables.md +153 -11
- package/docs/features.md +4 -3
- package/docs/globalconfig.md +56 -4
- package/docs/language-coverage.md +2 -2
- package/docs/mcp.md +17 -16
- package/docs/servercapabilities.md +5 -2
- package/docs/settings.md +181 -0
- package/docs/tools.md +14 -0
- package/docs/tree-sitter_rules_catalog.md +11 -31
- package/docs/usage.md +13 -0
- package/package.json +139 -138
- package/rules/ast-grep-rules/rule-tests/hardcoded-url-js-test.yml +1 -0
- package/rules/ast-grep-rules/rule-tests/hardcoded-url-test.yml +2 -0
- package/rules/ast-grep-rules/rule-tests/no-case-declarations-js-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-case-declarations-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-javascript-url-js-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/no-javascript-url-test.yml +10 -0
- package/rules/ast-grep-rules/rule-tests/strict-equality-js-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-equality-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-inequality-js-test.yml +3 -0
- package/rules/ast-grep-rules/rule-tests/strict-inequality-test.yml +4 -0
- package/rules/ast-grep-rules/rules/hardcoded-url-js.yml +22 -4
- package/rules/ast-grep-rules/rules/hardcoded-url.yml +22 -4
- package/rules/ast-grep-rules/rules/no-case-declarations-js.yml +4 -3
- package/rules/ast-grep-rules/rules/no-case-declarations.yml +4 -3
- package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +10 -0
- package/rules/ast-grep-rules/rules/no-console-except-error.yml +10 -0
- package/rules/ast-grep-rules/rules/no-javascript-url-js.yml +42 -6
- package/rules/ast-grep-rules/rules/no-javascript-url.yml +42 -6
- package/rules/ast-grep-rules/rules/strict-equality-js.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-equality.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-inequality-js.yml +14 -1
- package/rules/ast-grep-rules/rules/strict-inequality.yml +14 -1
- package/rules/tree-sitter-queries/cpp/no-memset-sensitive-data.yml +9 -3
- package/rules/tree-sitter-queries/cpp/no-scoped-lock-without-args.yml +6 -6
- package/rules/tree-sitter-queries/css/calc-spacing.yml +8 -6
- package/rules/tree-sitter-queries/go/go-mutex-copy.yml +21 -18
- package/rules/tree-sitter-queries/go/go-shared-map-write-goroutine.yml +3 -3
- package/rules/tree-sitter-queries/java/infinite-loop-java.yml +3 -3
- package/rules/tree-sitter-queries/java/junit-call-super.yml +6 -4
- package/rules/tree-sitter-queries/java/no-double-checked-locking.yml +10 -8
- package/rules/tree-sitter-queries/java/no-field-shadowing.yml +1 -1
- package/rules/tree-sitter-queries/java/prepared-statement-valid-indices.yml +2 -3
- package/rules/tree-sitter-queries/java/resources-closed.yml +2 -2
- package/rules/tree-sitter-queries/java/springboot-default-package.yml +6 -3
- package/rules/tree-sitter-queries/java/switch-fall-through.yml +6 -4
- package/rules/tree-sitter-queries/java/switch-non-case-labels.yml +4 -3
- package/rules/tree-sitter-queries/java/tests-include-assertions.yml +6 -5
- package/rules/tree-sitter-queries/javascript/switch-case-termination-js.yml +5 -8
- package/rules/tree-sitter-queries/javascript/switch-non-case-labels.yml +3 -2
- package/rules/tree-sitter-queries/kotlin/prepared-statement-indices.yml +9 -5
- package/rules/tree-sitter-queries/php/this-in-static-context.yml +5 -5
- package/rules/tree-sitter-queries/python/exit-signature-check.yml +2 -9
- package/rules/tree-sitter-queries/python/in-operator-unsupported.yml +3 -4
- package/rules/tree-sitter-queries/python/no-super-torchscript.yml +4 -8
- package/rules/tree-sitter-queries/python/notimplemented-boolean-context.yml +1 -5
- package/rules/tree-sitter-queries/python/python-empty-except.yml +1 -1
- package/rules/tree-sitter-queries/python/return-in-init.yml +0 -2
- package/rules/tree-sitter-queries/python/yield-return-outside-function.yml +0 -3
- package/rules/tree-sitter-queries/ruby/ruby-command-injection.yml +1 -12
- package/rules/tree-sitter-queries/ruby/ruby-eval.yml +1 -1
- package/rules/tree-sitter-queries/ruby/ruby-insecure-deserialization.yml +4 -4
- package/rules/tree-sitter-queries/ruby/ruby-insecure-random.yml +4 -11
- package/rules/tree-sitter-queries/ruby/ruby-open-struct.yml +1 -1
- package/rules/tree-sitter-queries/ruby/ruby-string-eval.yml +2 -3
- package/rules/tree-sitter-queries/ruby/ruby-weak-hash.yml +4 -4
- package/rules/tree-sitter-queries/rust/rust-lock-held-across-await.yml +4 -3
- package/rules/tree-sitter-queries/typescript/console-statement.yml +11 -0
- package/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +4 -9
- package/rules/tree-sitter-queries/typescript/empty-switch-case.yml +13 -9
- package/rules/tree-sitter-queries/typescript/infinite-loop.yml +2 -2
- package/rules/tree-sitter-queries/typescript/mixed-async-styles.yml +10 -1
- package/rules/tree-sitter-queries/typescript/switch-case-termination.yml +5 -8
- package/rules/tree-sitter-queries/typescript/ts-insecure-random.yml +7 -10
- package/rules/tree-sitter-queries/typescript/unsafe-regex.yml +4 -2
- package/rules/typos/_typos.toml +17 -0
- package/skills/pi-lens-write-tree-sitter-rule/SKILL.md +5 -0
- package/dist/clients/config-enabled-shape.js +0 -39
- package/docs/env_variables.md +0 -10
- package/rules/tree-sitter-queries/abap-disabled/delete-where.yml +0 -46
- package/rules/tree-sitter-queries/cpp/no-confused-move-forward.yml +0 -59
- package/rules/tree-sitter-queries/cpp/noexcept-functions.yml +0 -58
- package/rules/tree-sitter-queries/java/mockito-initialized.yml +0 -66
- package/rules/tree-sitter-queries/java/no-wait-notify-on-thread.yml +0 -58
- package/rules/tree-sitter-queries/java/short-circuit-logic.yml +0 -57
- package/rules/tree-sitter-queries/java/spring-session-attributes-setcomplete.yml +0 -75
- package/rules/tree-sitter-queries/plsql-disabled/delete-update-where.yml +0 -56
- package/rules/tree-sitter-queries/plsql-disabled/end-loop-semicolon.yml +0 -51
- package/rules/tree-sitter-queries/plsql-disabled/fetch-bulk-collect-limit.yml +0 -47
- package/rules/tree-sitter-queries/plsql-disabled/forallsave-exceptions.yml +0 -51
- package/rules/tree-sitter-queries/plsql-disabled/nchar-nvarchar2-bytes.yml +0 -54
- package/rules/tree-sitter-queries/plsql-disabled/not-null-initialization.yml +0 -59
- package/rules/tree-sitter-queries/plsql-disabled/raise-application-error-codes.yml +0 -50
- package/rules/tree-sitter-queries/typescript-disabled/ts-path-traversal.yml +0 -71
|
@@ -15,13 +15,49 @@ note: |
|
|
|
15
15
|
`.only`/`.skip`/`.each` variants): a test asserting that a guard REJECTS a
|
|
16
16
|
`javascript:` URL — e.g. `expect(openBrowser("javascript:...")).toBe(false)`
|
|
17
17
|
— is the adversarial input the code is meant to reject, not a real sink.
|
|
18
|
+
|
|
19
|
+
Also excludes literals used as the needle in a defensive string check —
|
|
20
|
+
`url.startsWith("javascript:")`, `.endsWith(...)`, `.includes(...)`,
|
|
21
|
+
`.indexOf(...)`, `.search(...)`, `.match(...)` — or as one side of an
|
|
22
|
+
equality/inequality comparison (`url === "javascript:..."`). These are the
|
|
23
|
+
code detecting/rejecting a javascript: URL, not introducing one (refs
|
|
24
|
+
#533). Deliberately NOT excluded: `.replace(...)`/`.replaceAll(...)`,
|
|
25
|
+
since the literal there could be the replacement (second) argument —
|
|
26
|
+
i.e. the malicious payload being substituted IN — and excluding the
|
|
27
|
+
whole call would hide that true positive.
|
|
28
|
+
|
|
29
|
+
IMPORTANT: unlike the expect/it/test/describe exclusion above, these two
|
|
30
|
+
new exclusions deliberately do NOT use `stopBy: end`. `inside` without
|
|
31
|
+
`stopBy` only checks the immediate parent, so the literal must be a
|
|
32
|
+
DIRECT argument/operand of the defensive call/comparison — not merely
|
|
33
|
+
somewhere in its subtree. Without this constraint, a real sink smuggled
|
|
34
|
+
inside the call/comparison would go unflagged, e.g.
|
|
35
|
+
`candidates.includes(link.href = "javascript:alert(1)")` (assignment
|
|
36
|
+
nested in `.includes()`'s argument), `arr.includes((a.href =
|
|
37
|
+
"javascript:...", true))` (comma operator), or `(a.href =
|
|
38
|
+
"javascript:...") === expected` (assignment nested in a `===` operand) —
|
|
39
|
+
in all three the literal's immediate parent is the assignment
|
|
40
|
+
expression, not the `arguments`/`binary_expression` node, so it stays
|
|
41
|
+
flagged.
|
|
18
42
|
rule:
|
|
19
43
|
kind: string
|
|
20
44
|
regex: '^"javascript:'
|
|
21
45
|
not:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
46
|
+
any:
|
|
47
|
+
- inside:
|
|
48
|
+
stopBy: end
|
|
49
|
+
kind: call_expression
|
|
50
|
+
has:
|
|
51
|
+
field: function
|
|
52
|
+
regex: "^(expect|it|test|describe)(\\.\\w+)?$"
|
|
53
|
+
- inside:
|
|
54
|
+
kind: arguments
|
|
55
|
+
inside:
|
|
56
|
+
kind: call_expression
|
|
57
|
+
has:
|
|
58
|
+
field: function
|
|
59
|
+
regex: "\\.(startsWith|endsWith|includes|indexOf|search|match)$"
|
|
60
|
+
- inside:
|
|
61
|
+
kind: binary_expression
|
|
62
|
+
has:
|
|
63
|
+
regex: "^(===|!==|==|!=)$"
|
|
@@ -5,6 +5,19 @@ severity: warning
|
|
|
5
5
|
note: |
|
|
6
6
|
== performs type coercion which leads to unexpected comparisons.
|
|
7
7
|
Use === for strict equality checks.
|
|
8
|
+
EXCEPT `$X == null` / `$X == undefined` (and the reversed operand order):
|
|
9
|
+
`== null` is the canonical JS/TS idiom for "is null or undefined" —
|
|
10
|
+
rewriting it to `===` changes behavior by dropping the other nullish
|
|
11
|
+
case, which is a real bug, not a style fix (#966).
|
|
8
12
|
rule:
|
|
9
|
-
|
|
13
|
+
all:
|
|
14
|
+
- pattern: $X == $Y
|
|
15
|
+
- not:
|
|
16
|
+
any:
|
|
17
|
+
- has:
|
|
18
|
+
field: right
|
|
19
|
+
regex: "^(null|undefined)$"
|
|
20
|
+
- has:
|
|
21
|
+
field: left
|
|
22
|
+
regex: "^(null|undefined)$"
|
|
10
23
|
fix: $X === $Y
|
|
@@ -5,6 +5,19 @@ severity: warning
|
|
|
5
5
|
note: |
|
|
6
6
|
== performs type coercion which leads to unexpected comparisons.
|
|
7
7
|
Use === for strict equality checks.
|
|
8
|
+
EXCEPT `$X == null` / `$X == undefined` (and the reversed operand order):
|
|
9
|
+
`== null` is the canonical JS/TS idiom for "is null or undefined" —
|
|
10
|
+
rewriting it to `===` changes behavior by dropping the other nullish
|
|
11
|
+
case, which is a real bug, not a style fix (#966).
|
|
8
12
|
rule:
|
|
9
|
-
|
|
13
|
+
all:
|
|
14
|
+
- pattern: $X == $Y
|
|
15
|
+
- not:
|
|
16
|
+
any:
|
|
17
|
+
- has:
|
|
18
|
+
field: right
|
|
19
|
+
regex: "^(null|undefined)$"
|
|
20
|
+
- has:
|
|
21
|
+
field: left
|
|
22
|
+
regex: "^(null|undefined)$"
|
|
10
23
|
fix: $X === $Y
|
|
@@ -5,6 +5,19 @@ severity: warning
|
|
|
5
5
|
note: |
|
|
6
6
|
!= performs type coercion which leads to unexpected comparisons.
|
|
7
7
|
Use !== for strict inequality checks.
|
|
8
|
+
EXCEPT `$X != null` / `$X != undefined` (and the reversed operand order):
|
|
9
|
+
`!= null` is the canonical JS/TS idiom for "is not null or undefined" —
|
|
10
|
+
rewriting it to `!==` changes behavior by dropping the other nullish
|
|
11
|
+
case, which is a real bug, not a style fix (#966).
|
|
8
12
|
rule:
|
|
9
|
-
|
|
13
|
+
all:
|
|
14
|
+
- pattern: $X != $Y
|
|
15
|
+
- not:
|
|
16
|
+
any:
|
|
17
|
+
- has:
|
|
18
|
+
field: right
|
|
19
|
+
regex: "^(null|undefined)$"
|
|
20
|
+
- has:
|
|
21
|
+
field: left
|
|
22
|
+
regex: "^(null|undefined)$"
|
|
10
23
|
fix: $X !== $Y
|
|
@@ -5,6 +5,19 @@ severity: warning
|
|
|
5
5
|
note: |
|
|
6
6
|
!= performs type coercion which leads to unexpected comparisons.
|
|
7
7
|
Use !== for strict inequality checks.
|
|
8
|
+
EXCEPT `$X != null` / `$X != undefined` (and the reversed operand order):
|
|
9
|
+
`!= null` is the canonical JS/TS idiom for "is not null or undefined" —
|
|
10
|
+
rewriting it to `!==` changes behavior by dropping the other nullish
|
|
11
|
+
case, which is a real bug, not a style fix (#966).
|
|
8
12
|
rule:
|
|
9
|
-
|
|
13
|
+
all:
|
|
14
|
+
- pattern: $X != $Y
|
|
15
|
+
- not:
|
|
16
|
+
any:
|
|
17
|
+
- has:
|
|
18
|
+
field: right
|
|
19
|
+
regex: "^(null|undefined)$"
|
|
20
|
+
- has:
|
|
21
|
+
field: left
|
|
22
|
+
regex: "^(null|undefined)$"
|
|
10
23
|
fix: $X !== $Y
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
# Detects memset used to clear sensitive data
|
|
3
3
|
id: no-memset-sensitive-data
|
|
4
4
|
name: memset Should Not Be Used to Delete Sensitive Data
|
|
5
|
-
severity:
|
|
5
|
+
severity: warning
|
|
6
6
|
category: security
|
|
7
7
|
defect_class: security
|
|
8
|
-
inline_tier:
|
|
8
|
+
inline_tier: warning
|
|
9
9
|
language: cpp
|
|
10
10
|
|
|
11
11
|
message: "memset should not be used to delete sensitive data — use SecureZeroMemory or explicit_bzero"
|
|
@@ -28,10 +28,16 @@ description: |
|
|
|
28
28
|
query: |
|
|
29
29
|
(call_expression
|
|
30
30
|
function: (identifier) @FUNC (#eq? @FUNC "memset")
|
|
31
|
-
arguments: (argument_list
|
|
31
|
+
arguments: (argument_list
|
|
32
|
+
(_) @DEST
|
|
33
|
+
(_) @VALUE
|
|
34
|
+
(_) @SIZE) @ARGS)
|
|
32
35
|
|
|
33
36
|
metavars:
|
|
34
37
|
- FUNC
|
|
38
|
+
- DEST
|
|
39
|
+
- VALUE
|
|
40
|
+
- SIZE
|
|
35
41
|
- ARGS
|
|
36
42
|
|
|
37
43
|
post_filter: memset_for_sensitive_data
|
|
@@ -22,15 +22,15 @@ description: |
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
query: |
|
|
25
|
-
(declaration
|
|
26
|
-
type: (
|
|
27
|
-
name: (type_identifier) @TYPE
|
|
28
|
-
declarator: (
|
|
29
|
-
|
|
25
|
+
((declaration
|
|
26
|
+
type: (qualified_identifier
|
|
27
|
+
name: (type_identifier) @TYPE)
|
|
28
|
+
declarator: (identifier) @DECL)
|
|
29
|
+
(#eq? @TYPE "scoped_lock"))
|
|
30
30
|
|
|
31
31
|
metavars:
|
|
32
32
|
- TYPE
|
|
33
|
-
-
|
|
33
|
+
- DECL
|
|
34
34
|
|
|
35
35
|
post_filter: scoped_lock_empty_args
|
|
36
36
|
|
|
@@ -21,15 +21,17 @@ description: |
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
query: |
|
|
24
|
-
(call_expression
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
(
|
|
28
|
-
|
|
24
|
+
((call_expression
|
|
25
|
+
(function_name) @FUNC
|
|
26
|
+
(arguments
|
|
27
|
+
(_) @LEFT
|
|
28
|
+
(_) @RIGHT) @EXPR)
|
|
29
|
+
(#eq? @FUNC "calc"))
|
|
29
30
|
|
|
30
31
|
metavars:
|
|
31
32
|
- FUNC
|
|
32
|
-
-
|
|
33
|
+
- LEFT
|
|
34
|
+
- RIGHT
|
|
33
35
|
- EXPR
|
|
34
36
|
|
|
35
37
|
post_filter: calc_missing_spaces
|
|
@@ -6,33 +6,34 @@ defect_class: correctness
|
|
|
6
6
|
inline_tier: blocking
|
|
7
7
|
language: go
|
|
8
8
|
|
|
9
|
-
message: "sync.Mutex
|
|
9
|
+
message: "sync.Mutex parameter taken by value — the callee locks a copy; take *sync.Mutex instead"
|
|
10
10
|
|
|
11
11
|
description: |
|
|
12
12
|
A sync.Mutex must never be copied after first use. Copying a mutex copies
|
|
13
13
|
its internal state, so both copies appear unlocked even if the original
|
|
14
14
|
was locked — leading to data races and deadlocks.
|
|
15
15
|
|
|
16
|
-
This fires
|
|
17
|
-
|
|
16
|
+
This fires on a parameter declared as a bare `sync.Mutex`/`sync.RWMutex`
|
|
17
|
+
value: the call copies the lock, so the callee locks its own copy. Copies
|
|
18
|
+
through a struct that embeds a mutex (a value receiver, or a struct-typed
|
|
19
|
+
parameter) are NOT detected — that needs the struct definition, which this
|
|
20
|
+
single-file query cannot resolve.
|
|
18
21
|
|
|
19
|
-
✅ FIX:
|
|
22
|
+
✅ FIX: take the mutex as *sync.Mutex, or reach it through a pointer receiver.
|
|
20
23
|
|
|
21
24
|
❌ NEVER:
|
|
22
|
-
|
|
23
|
-
func work(s S) { s.mu.Lock() } // copies the mutex!
|
|
25
|
+
func work(mu sync.Mutex) { mu.Lock() } // locks a copy!
|
|
24
26
|
|
|
25
27
|
✅ SAFE:
|
|
26
|
-
func work(
|
|
28
|
+
func work(mu *sync.Mutex) { mu.Lock() }
|
|
27
29
|
|
|
28
30
|
query: |
|
|
29
|
-
(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
(#match? @FN "^(Mutex|RWMutex)$"))) @DECL
|
|
31
|
+
(parameter_declaration
|
|
32
|
+
type: (qualified_type
|
|
33
|
+
package: (package_identifier) @PKG
|
|
34
|
+
name: (type_identifier) @FN)
|
|
35
|
+
(#eq? @PKG "sync")
|
|
36
|
+
(#match? @FN "^(Mutex|RWMutex)$")) @DECL
|
|
36
37
|
|
|
37
38
|
metavars:
|
|
38
39
|
- PKG
|
|
@@ -49,9 +50,11 @@ tags:
|
|
|
49
50
|
|
|
50
51
|
examples:
|
|
51
52
|
bad: |
|
|
52
|
-
mu
|
|
53
|
-
|
|
53
|
+
func doWork(mu sync.Mutex) { // BAD - mu is a copy
|
|
54
|
+
mu.Lock()
|
|
55
|
+
}
|
|
54
56
|
|
|
55
57
|
good: |
|
|
56
|
-
mu
|
|
57
|
-
|
|
58
|
+
func doWork(mu *sync.Mutex) {
|
|
59
|
+
mu.Lock()
|
|
60
|
+
}
|
|
@@ -17,12 +17,12 @@ description: |
|
|
|
17
17
|
|
|
18
18
|
query: |
|
|
19
19
|
(go_statement
|
|
20
|
-
|
|
20
|
+
(call_expression
|
|
21
21
|
function: (func_literal
|
|
22
22
|
body: (block
|
|
23
23
|
(assignment_statement
|
|
24
|
-
left: (index_expression) @MAPWRITE
|
|
25
|
-
right: (_) @VALUE)))
|
|
24
|
+
left: (expression_list (index_expression) @MAPWRITE)
|
|
25
|
+
right: (expression_list (_) @VALUE))))
|
|
26
26
|
arguments: (argument_list) @ARGS))
|
|
27
27
|
|
|
28
28
|
metavars:
|
|
@@ -25,11 +25,11 @@ description: |
|
|
|
25
25
|
|
|
26
26
|
query: |
|
|
27
27
|
(while_statement
|
|
28
|
-
condition: (true) @COND
|
|
28
|
+
condition: (condition (true) @COND)
|
|
29
29
|
body: (block) @BODY)
|
|
30
30
|
(for_statement
|
|
31
|
-
condition
|
|
32
|
-
|
|
31
|
+
!condition
|
|
32
|
+
(block) @BODY)
|
|
33
33
|
|
|
34
34
|
metavars:
|
|
35
35
|
- COND
|
|
@@ -28,10 +28,12 @@ description: |
|
|
|
28
28
|
query: |
|
|
29
29
|
(method_declaration
|
|
30
30
|
(modifiers
|
|
31
|
-
(
|
|
32
|
-
name: (identifier) @OVERRIDE
|
|
33
|
-
name: (identifier) @METHOD
|
|
34
|
-
body: (block) @BODY
|
|
31
|
+
(marker_annotation
|
|
32
|
+
name: (identifier) @OVERRIDE))
|
|
33
|
+
name: (identifier) @METHOD
|
|
34
|
+
body: (block) @BODY
|
|
35
|
+
(#eq? @OVERRIDE "Override")
|
|
36
|
+
(#match? @METHOD "^(setUp|tearDown|setUpBeforeClass|tearDownAfterClass)$"))
|
|
35
37
|
|
|
36
38
|
metavars:
|
|
37
39
|
- OVERRIDE
|
|
@@ -28,18 +28,20 @@ description: |
|
|
|
28
28
|
|
|
29
29
|
query: |
|
|
30
30
|
(if_statement
|
|
31
|
-
condition: (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
condition: (condition
|
|
32
|
+
(binary_expression
|
|
33
|
+
left: (identifier) @FIELD
|
|
34
|
+
"=="
|
|
35
|
+
(null_literal) @NULL))
|
|
35
36
|
consequence: (block
|
|
36
37
|
(synchronized_statement
|
|
37
38
|
body: (block
|
|
38
39
|
(if_statement
|
|
39
|
-
condition: (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
condition: (condition
|
|
41
|
+
(binary_expression
|
|
42
|
+
left: (identifier) @FIELD2
|
|
43
|
+
"=="
|
|
44
|
+
(null_literal) @NULL2)))))))
|
|
43
45
|
|
|
44
46
|
metavars:
|
|
45
47
|
- FIELD
|
|
@@ -26,15 +26,14 @@ query: |
|
|
|
26
26
|
(method_invocation
|
|
27
27
|
name: (identifier) @METHOD (#match? @METHOD "^(setString|setInt|setLong|setDouble|setBoolean|getString|getInt|getLong|getDouble|getBoolean)$")
|
|
28
28
|
arguments: (argument_list
|
|
29
|
-
(decimal_integer_literal) @INDEX
|
|
29
|
+
(decimal_integer_literal) @INDEX
|
|
30
|
+
(#match? @INDEX "^0+$")) @ARGS)
|
|
30
31
|
|
|
31
32
|
metavars:
|
|
32
33
|
- METHOD
|
|
33
34
|
- INDEX
|
|
34
35
|
- ARGS
|
|
35
36
|
|
|
36
|
-
post_filter: invalid_statement_index
|
|
37
|
-
|
|
38
37
|
tags:
|
|
39
38
|
- reliability
|
|
40
39
|
- java
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
# Detects resources that should be closed (pre-Java 7 style)
|
|
3
3
|
id: resources-closed
|
|
4
4
|
name: Resources Should Be Closed
|
|
5
|
-
severity:
|
|
5
|
+
severity: warning
|
|
6
6
|
category: reliability
|
|
7
7
|
defect_class: correctness
|
|
8
|
-
inline_tier:
|
|
8
|
+
inline_tier: warning
|
|
9
9
|
language: java
|
|
10
10
|
|
|
11
11
|
message: "Resource '{{RESOURCE}}' should be closed in finally block"
|
|
@@ -30,9 +30,12 @@ description: |
|
|
|
30
30
|
query: |
|
|
31
31
|
(class_declaration
|
|
32
32
|
(modifiers
|
|
33
|
-
(
|
|
34
|
-
name: (identifier) @ANNOT
|
|
35
|
-
|
|
33
|
+
[(marker_annotation
|
|
34
|
+
name: (identifier) @ANNOT)
|
|
35
|
+
(annotation
|
|
36
|
+
name: (identifier) @ANNOT)])
|
|
37
|
+
name: (_) @CLASS
|
|
38
|
+
(#match? @ANNOT "^(SpringBootApplication|ComponentScan)$"))
|
|
36
39
|
|
|
37
40
|
metavars:
|
|
38
41
|
- ANNOT
|
|
@@ -29,11 +29,13 @@ description: |
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
query: |
|
|
32
|
-
(
|
|
32
|
+
(switch_expression
|
|
33
33
|
body: (switch_block
|
|
34
|
-
(
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
(switch_block_statement_group
|
|
35
|
+
(switch_label) @LABEL
|
|
36
|
+
(expression_statement)+)
|
|
37
|
+
(switch_block_statement_group
|
|
38
|
+
(switch_label) @NEXT_LABEL)))
|
|
37
39
|
|
|
38
40
|
metavars:
|
|
39
41
|
- LABEL
|
|
@@ -27,10 +27,11 @@ description: |
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
query: |
|
|
30
|
-
(
|
|
30
|
+
(switch_expression
|
|
31
31
|
body: (switch_block
|
|
32
|
-
(
|
|
33
|
-
(
|
|
32
|
+
(switch_block_statement_group
|
|
33
|
+
(labeled_statement
|
|
34
|
+
(identifier) @LABEL) @LABELED_STMT)))
|
|
34
35
|
|
|
35
36
|
metavars:
|
|
36
37
|
- LABEL
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
# Detects JUnit tests without assertions
|
|
3
3
|
id: tests-include-assertions
|
|
4
4
|
name: Tests Should Include Assertions
|
|
5
|
-
severity:
|
|
5
|
+
severity: warning
|
|
6
6
|
category: maintainability
|
|
7
7
|
defect_class: correctness
|
|
8
|
-
inline_tier:
|
|
8
|
+
inline_tier: warning
|
|
9
9
|
language: java
|
|
10
10
|
|
|
11
11
|
message: "Test method should include at least one assertion"
|
|
@@ -26,10 +26,11 @@ description: |
|
|
|
26
26
|
query: |
|
|
27
27
|
(method_declaration
|
|
28
28
|
(modifiers
|
|
29
|
-
(
|
|
30
|
-
name: (identifier) @TEST
|
|
29
|
+
(marker_annotation
|
|
30
|
+
name: (identifier) @TEST))
|
|
31
31
|
name: (identifier) @NAME
|
|
32
|
-
body: (block) @BODY
|
|
32
|
+
body: (block) @BODY
|
|
33
|
+
(#match? @TEST "^(Test|ParameterizedTest|RepeatedTest)$"))
|
|
33
34
|
|
|
34
35
|
metavars:
|
|
35
36
|
- TEST
|
|
@@ -26,16 +26,13 @@ description: |
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
query: |
|
|
29
|
-
(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
(expression_statement) @LAST))
|
|
34
|
-
(switch_case) @NEXT))
|
|
29
|
+
(switch_body
|
|
30
|
+
(switch_case) @CASE
|
|
31
|
+
.
|
|
32
|
+
[(switch_case) (switch_default)])
|
|
35
33
|
|
|
36
34
|
metavars:
|
|
37
|
-
-
|
|
38
|
-
- NEXT
|
|
35
|
+
- CASE
|
|
39
36
|
|
|
40
37
|
post_filter: no_terminating_statement
|
|
41
38
|
|
|
@@ -21,17 +21,21 @@ description: |
|
|
|
21
21
|
|
|
22
22
|
query: |
|
|
23
23
|
(call_expression
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
(
|
|
24
|
+
(navigation_expression
|
|
25
|
+
(simple_identifier)
|
|
26
|
+
(navigation_suffix
|
|
27
|
+
(simple_identifier) @METHOD))
|
|
28
|
+
(call_suffix
|
|
29
|
+
(value_arguments
|
|
30
|
+
(value_argument (integer_literal) @INDEX) @ARGS))
|
|
31
|
+
(#match? @METHOD "^(setString|setInt|setLong|getString|getInt|getLong)$")
|
|
32
|
+
(#eq? @INDEX "0"))
|
|
27
33
|
|
|
28
34
|
metavars:
|
|
29
35
|
- METHOD
|
|
30
36
|
- INDEX
|
|
31
37
|
- ARGS
|
|
32
38
|
|
|
33
|
-
post_filter: invalid_jdbc_index
|
|
34
|
-
|
|
35
39
|
tags:
|
|
36
40
|
- reliability
|
|
37
41
|
- kotlin
|
|
@@ -33,15 +33,15 @@ description: |
|
|
|
33
33
|
|
|
34
34
|
query: |
|
|
35
35
|
(method_declaration
|
|
36
|
-
(
|
|
37
|
-
"static")
|
|
36
|
+
(static_modifier)
|
|
38
37
|
body: (compound_statement
|
|
39
|
-
(
|
|
40
|
-
(
|
|
38
|
+
(return_statement
|
|
39
|
+
(member_access_expression
|
|
40
|
+
object: ((variable_name) @THIS
|
|
41
|
+
(#eq? @THIS "$this"))))) )
|
|
41
42
|
|
|
42
43
|
metavars:
|
|
43
44
|
- THIS
|
|
44
|
-
- VAR
|
|
45
45
|
|
|
46
46
|
tags:
|
|
47
47
|
- reliability
|
|
@@ -28,18 +28,11 @@ description: |
|
|
|
28
28
|
query: |
|
|
29
29
|
(function_definition
|
|
30
30
|
name: (identifier) @NAME (#eq? @NAME "__exit__")
|
|
31
|
-
parameters: (parameters
|
|
32
|
-
(_) @SELF
|
|
33
|
-
. (_) @PARAM1?
|
|
34
|
-
. (_) @PARAM2?
|
|
35
|
-
. (_) @PARAM3?))
|
|
31
|
+
parameters: (parameters) @PARAMS)
|
|
36
32
|
|
|
37
33
|
metavars:
|
|
38
34
|
- NAME
|
|
39
|
-
-
|
|
40
|
-
- PARAM1
|
|
41
|
-
- PARAM2
|
|
42
|
-
- PARAM3
|
|
35
|
+
- PARAMS
|
|
43
36
|
|
|
44
37
|
post_filter: exit_params_insufficient
|
|
45
38
|
|
|
@@ -25,12 +25,11 @@ query: |
|
|
|
25
25
|
(comparison_operator
|
|
26
26
|
(identifier) @OBJ
|
|
27
27
|
"in"
|
|
28
|
-
(
|
|
28
|
+
(_) @TARGET)
|
|
29
29
|
(comparison_operator
|
|
30
30
|
(identifier) @OBJ
|
|
31
|
-
"not"
|
|
32
|
-
|
|
33
|
-
(identifier) @TARGET)
|
|
31
|
+
"not in"
|
|
32
|
+
(_) @TARGET)
|
|
34
33
|
|
|
35
34
|
metavars:
|
|
36
35
|
- OBJ
|
|
@@ -17,19 +17,15 @@ description: |
|
|
|
17
17
|
✅ FIX: Use composition or avoid TorchScript for this class
|
|
18
18
|
|
|
19
19
|
query: |
|
|
20
|
-
(
|
|
21
|
-
(
|
|
22
|
-
(call
|
|
23
|
-
function: (identifier) @DEC (#match? @DEC "^(torch\.jit\.script|jit\.script)$")))
|
|
24
|
-
body: (block
|
|
25
|
-
(call
|
|
26
|
-
function: (identifier) @FUNC (#eq? @FUNC "super")) @CALL))
|
|
20
|
+
(call
|
|
21
|
+
function: (identifier) @FUNC (#eq? @FUNC "super")) @CALL
|
|
27
22
|
|
|
28
23
|
metavars:
|
|
29
|
-
- DEC
|
|
30
24
|
- FUNC
|
|
31
25
|
- CALL
|
|
32
26
|
|
|
27
|
+
post_filter: torchscript_super_call
|
|
28
|
+
|
|
33
29
|
tags:
|
|
34
30
|
- reliability
|
|
35
31
|
- python
|
|
@@ -28,13 +28,9 @@ query: |
|
|
|
28
28
|
condition: (identifier) @COND (#eq? @COND "NotImplemented"))
|
|
29
29
|
(while_statement
|
|
30
30
|
condition: (identifier) @COND (#eq? @COND "NotImplemented"))
|
|
31
|
-
(binary_operator
|
|
32
|
-
(identifier) @COND (#eq? @COND "NotImplemented")
|
|
33
|
-
("and" | "or"))
|
|
34
31
|
(boolean_operator
|
|
35
32
|
(identifier) @COND (#eq? @COND "NotImplemented"))
|
|
36
|
-
(
|
|
37
|
-
operator: ("not")
|
|
33
|
+
(not_operator
|
|
38
34
|
argument: (identifier) @COND (#eq? @COND "NotImplemented"))
|
|
39
35
|
|
|
40
36
|
metavars:
|