circle-ir 4.15.0 → 4.16.1
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/configs/sinks/golang.json +4 -4
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +11 -7
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/constant-caller-gate.d.ts +39 -0
- package/dist/analysis/constant-caller-gate.d.ts.map +1 -0
- package/dist/analysis/constant-caller-gate.js +298 -0
- package/dist/analysis/constant-caller-gate.js.map +1 -0
- package/dist/analysis/constant-propagation/evaluator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/evaluator.js +3 -1
- package/dist/analysis/constant-propagation/evaluator.js.map +1 -1
- package/dist/analysis/constant-propagation/patterns.d.ts +19 -0
- package/dist/analysis/constant-propagation/patterns.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/patterns.js +33 -0
- package/dist/analysis/constant-propagation/patterns.js.map +1 -1
- package/dist/analysis/constant-propagation/propagator.d.ts +59 -0
- package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/propagator.js +396 -49
- package/dist/analysis/constant-propagation/propagator.js.map +1 -1
- package/dist/analysis/constant-propagation/types.d.ts +9 -0
- package/dist/analysis/constant-propagation/types.d.ts.map +1 -1
- package/dist/analysis/findings.d.ts.map +1 -1
- package/dist/analysis/findings.js +134 -0
- package/dist/analysis/findings.js.map +1 -1
- package/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +127 -3
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/java-array-element-keys.d.ts +14 -0
- package/dist/analysis/java-array-element-keys.d.ts.map +1 -0
- package/dist/analysis/java-array-element-keys.js +36 -0
- package/dist/analysis/java-array-element-keys.js.map +1 -0
- package/dist/analysis/js-crlf-strip.d.ts +26 -0
- package/dist/analysis/js-crlf-strip.d.ts.map +1 -0
- package/dist/analysis/js-crlf-strip.js +244 -0
- package/dist/analysis/js-crlf-strip.js.map +1 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +25 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js +157 -12
- package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts +38 -3
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +1234 -127
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.js +53 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.js.map +1 -1
- package/dist/analysis/passes/plaintext-password-storage-pass.d.ts +6 -0
- package/dist/analysis/passes/plaintext-password-storage-pass.d.ts.map +1 -1
- package/dist/analysis/passes/plaintext-password-storage-pass.js +160 -0
- package/dist/analysis/passes/plaintext-password-storage-pass.js.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.d.ts +1 -1
- package/dist/analysis/passes/scan-secrets-pass.d.ts.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.js +7 -1
- package/dist/analysis/passes/scan-secrets-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +326 -34
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/taint-matcher-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-matcher-pass.js +2 -2
- package/dist/analysis/passes/taint-matcher-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +1376 -58
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/weak-hash-pass.d.ts +6 -0
- package/dist/analysis/passes/weak-hash-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-hash-pass.js +191 -4
- package/dist/analysis/passes/weak-hash-pass.js.map +1 -1
- package/dist/analysis/passes/weak-random-pass.d.ts +5 -0
- package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-random-pass.js +30 -0
- package/dist/analysis/passes/weak-random-pass.js.map +1 -1
- package/dist/analysis/project-callee-escape-gate.d.ts +40 -0
- package/dist/analysis/project-callee-escape-gate.d.ts.map +1 -0
- package/dist/analysis/project-callee-escape-gate.js +243 -0
- package/dist/analysis/project-callee-escape-gate.js.map +1 -0
- package/dist/analysis/rust-literal-guard-rebind.d.ts +34 -0
- package/dist/analysis/rust-literal-guard-rebind.d.ts.map +1 -0
- package/dist/analysis/rust-literal-guard-rebind.js +197 -0
- package/dist/analysis/rust-literal-guard-rebind.js.map +1 -0
- package/dist/analysis/rust-literal-guard.d.ts +33 -0
- package/dist/analysis/rust-literal-guard.d.ts.map +1 -0
- package/dist/analysis/rust-literal-guard.js +422 -0
- package/dist/analysis/rust-literal-guard.js.map +1 -0
- package/dist/analysis/scalar-derivation.d.ts +8 -0
- package/dist/analysis/scalar-derivation.d.ts.map +1 -1
- package/dist/analysis/scalar-derivation.js +172 -0
- package/dist/analysis/scalar-derivation.js.map +1 -1
- package/dist/analysis/taint-matcher.d.ts +2 -2
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +531 -31
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analysis/taint-propagation.d.ts +26 -1
- package/dist/analysis/taint-propagation.d.ts.map +1 -1
- package/dist/analysis/taint-propagation.js +234 -13
- package/dist/analysis/taint-propagation.js.map +1 -1
- package/dist/analyzer.d.ts +16 -2
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +13 -3
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +24432 -19928
- package/dist/core/circle-ir-core.cjs +4936 -3575
- package/dist/core/circle-ir-core.js +4936 -3575
- package/dist/core/extractors/calls.d.ts +12 -1
- package/dist/core/extractors/calls.d.ts.map +1 -1
- package/dist/core/extractors/calls.js +332 -22
- package/dist/core/extractors/calls.js.map +1 -1
- package/dist/core/extractors/dfg.js +102 -10
- package/dist/core/extractors/dfg.js.map +1 -1
- package/dist/core/extractors/types.d.ts +5 -1
- package/dist/core/extractors/types.d.ts.map +1 -1
- package/dist/core/extractors/types.js +62 -0
- package/dist/core/extractors/types.js.map +1 -1
- package/dist/graph/analysis-pass.d.ts +6 -1
- package/dist/graph/analysis-pass.d.ts.map +1 -1
- package/dist/graph/analysis-pass.js +2 -1
- package/dist/graph/analysis-pass.js.map +1 -1
- package/dist/navigation/navigation-index.d.ts +134 -14
- package/dist/navigation/navigation-index.d.ts.map +1 -1
- package/dist/navigation/navigation-index.js +1158 -104
- package/dist/navigation/navigation-index.js.map +1 -1
- package/dist/navigation/types.d.ts +59 -2
- package/dist/navigation/types.d.ts.map +1 -1
- package/dist/resolution/cross-file.d.ts +9 -0
- package/dist/resolution/cross-file.d.ts.map +1 -1
- package/dist/resolution/cross-file.js +102 -43
- package/dist/resolution/cross-file.js.map +1 -1
- package/dist/resolution/type-hierarchy.d.ts +3 -0
- package/dist/resolution/type-hierarchy.d.ts.map +1 -1
- package/dist/resolution/type-hierarchy.js +45 -1
- package/dist/resolution/type-hierarchy.js.map +1 -1
- package/dist/types/index.d.ts +33 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import { firstRebind } from './rust-literal-guard-rebind.js';
|
|
2
|
+
const CREDITED_TYPES = [
|
|
3
|
+
'command_injection', 'path_traversal', 'sql_injection', 'ssrf', 'open_redirect',
|
|
4
|
+
'xss', 'code_injection', 'ldap_injection', 'xpath_injection', 'log_injection',
|
|
5
|
+
'trust_boundary', 'external_taint_escape',
|
|
6
|
+
];
|
|
7
|
+
/** `code` with comments blanked and string / char literal bodies replaced by spaces (same length). */
|
|
8
|
+
function maskRust(code) {
|
|
9
|
+
const out = code.split('');
|
|
10
|
+
const n = code.length;
|
|
11
|
+
const blank = (from, to) => {
|
|
12
|
+
for (let k = from; k < to; k++)
|
|
13
|
+
if (out[k] !== '\n')
|
|
14
|
+
out[k] = ' ';
|
|
15
|
+
};
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < n) {
|
|
18
|
+
const c = code[i];
|
|
19
|
+
if (c === '/' && code[i + 1] === '/') {
|
|
20
|
+
let j = i;
|
|
21
|
+
while (j < n && code[j] !== '\n')
|
|
22
|
+
j++;
|
|
23
|
+
blank(i, j);
|
|
24
|
+
i = j;
|
|
25
|
+
}
|
|
26
|
+
else if (c === '/' && code[i + 1] === '*') {
|
|
27
|
+
let j = i + 2;
|
|
28
|
+
let depth = 1;
|
|
29
|
+
while (j < n && depth > 0) {
|
|
30
|
+
if (code[j] === '/' && code[j + 1] === '*') {
|
|
31
|
+
depth++;
|
|
32
|
+
j += 2;
|
|
33
|
+
}
|
|
34
|
+
else if (code[j] === '*' && code[j + 1] === '/') {
|
|
35
|
+
depth--;
|
|
36
|
+
j += 2;
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
j++;
|
|
40
|
+
}
|
|
41
|
+
blank(i, j);
|
|
42
|
+
i = j;
|
|
43
|
+
}
|
|
44
|
+
else if (c === 'r' && /^r#*"/.test(code.slice(i, i + 12)) && !/[\w]/.test(code[i - 1] ?? ' ')) {
|
|
45
|
+
const hashes = /^r(#*)"/.exec(code.slice(i, i + 12))[1].length;
|
|
46
|
+
const close = '"' + '#'.repeat(hashes);
|
|
47
|
+
const end = code.indexOf(close, i + 2 + hashes);
|
|
48
|
+
const j = end === -1 ? n : end + close.length;
|
|
49
|
+
blank(i + 2 + hashes, Math.max(i + 2 + hashes, j - close.length));
|
|
50
|
+
i = j;
|
|
51
|
+
}
|
|
52
|
+
else if (c === '"') {
|
|
53
|
+
let j = i + 1;
|
|
54
|
+
while (j < n && code[j] !== '"')
|
|
55
|
+
j += code[j] === '\\' ? 2 : 1;
|
|
56
|
+
blank(i + 1, j);
|
|
57
|
+
i = j + 1;
|
|
58
|
+
}
|
|
59
|
+
else if (c === "'") {
|
|
60
|
+
// A char literal ('x', '\n', '\u{..}'), not a lifetime ('a).
|
|
61
|
+
const m = /^'(?:\\(?:u\{[0-9a-fA-F]+\}|x[0-9a-fA-F]{2}|.)|[^\\'])'/.exec(code.slice(i, i + 14));
|
|
62
|
+
if (m) {
|
|
63
|
+
blank(i + 1, i + m[0].length - 1);
|
|
64
|
+
i += m[0].length;
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
i++;
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
return out.join('');
|
|
73
|
+
}
|
|
74
|
+
/** Index of the `}` matching the `{` at `open` in `masked`, or -1. */
|
|
75
|
+
function matchBrace(masked, open) {
|
|
76
|
+
let depth = 0;
|
|
77
|
+
for (let i = open; i < masked.length; i++) {
|
|
78
|
+
if (masked[i] === '{')
|
|
79
|
+
depth++;
|
|
80
|
+
else if (masked[i] === '}' && --depth === 0)
|
|
81
|
+
return i;
|
|
82
|
+
}
|
|
83
|
+
return -1;
|
|
84
|
+
}
|
|
85
|
+
const STR = String.raw `"(?:[^"\\]|\\.)*"`;
|
|
86
|
+
const VAR = String.raw `([A-Za-z_]\w*)(?:\s*\.\s*as_str\s*\(\s*\))?`;
|
|
87
|
+
/** The guarded variable when `cond` is a literal allow-list rejection condition, else null. */
|
|
88
|
+
function guardedVariable(cond) {
|
|
89
|
+
const c = cond.trim();
|
|
90
|
+
let m;
|
|
91
|
+
// `!matches!(x, "a" | "b")`
|
|
92
|
+
if ((m = new RegExp(String.raw `^!\s*matches!\s*\(\s*${VAR}\s*,\s*((?:\|\s*)?${STR}(?:\s*\|\s*${STR})*)\s*,?\s*\)$`).exec(c))) {
|
|
93
|
+
return m[1];
|
|
94
|
+
}
|
|
95
|
+
// `!["a", "b"].contains(&x)`
|
|
96
|
+
if ((m = new RegExp(String.raw `^!\s*\[\s*${STR}(?:\s*,\s*${STR})*\s*,?\s*\]\s*\.\s*contains\s*\(\s*&\s*${VAR}\s*\)$`).exec(c))) {
|
|
97
|
+
return m[1];
|
|
98
|
+
}
|
|
99
|
+
// `!(x == "a" || x == "b")`
|
|
100
|
+
if ((m = /^!\s*\(([\s\S]*)\)$/.exec(c))) {
|
|
101
|
+
return chain(m[1], '||', '==');
|
|
102
|
+
}
|
|
103
|
+
// `x != "a" && x != "b"`
|
|
104
|
+
return chain(c, '&&', '!=');
|
|
105
|
+
}
|
|
106
|
+
/** Terms joined by `joiner`, each `V op "lit"` or `"lit" op V` with one shared V. */
|
|
107
|
+
function chain(text, joiner, op) {
|
|
108
|
+
const other = joiner === '||' ? '&&' : '||';
|
|
109
|
+
if (text.includes(other) || /[()]/.test(text.replace(/\.\s*as_str\s*\(\s*\)/g, '').replace(new RegExp(STR, 'g'), '""'))) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
let name = null;
|
|
113
|
+
const parts = text.split(joiner);
|
|
114
|
+
for (const part of parts) {
|
|
115
|
+
const t = part.trim();
|
|
116
|
+
const m = new RegExp(String.raw `^(?:${VAR}\s*${op}\s*${STR}|${STR}\s*${op}\s*${VAR})$`).exec(t);
|
|
117
|
+
if (!m)
|
|
118
|
+
return null;
|
|
119
|
+
const v = m[1] ?? m[2];
|
|
120
|
+
if (name !== null && v !== name)
|
|
121
|
+
return null;
|
|
122
|
+
name = v;
|
|
123
|
+
}
|
|
124
|
+
return name;
|
|
125
|
+
}
|
|
126
|
+
const KEYWORDS = new Set([
|
|
127
|
+
'let', 'mut', 'ref', 'as', 'if', 'else', 'return', 'true', 'false', 'self', 'move', 'in', 'for',
|
|
128
|
+
'while', 'loop', 'match', 'fn', 'pub', 'use', 'mod', 'const', 'static', 'unsafe', 'where', 'dyn',
|
|
129
|
+
'impl', 'break', 'continue', 'crate', 'super', 'async', 'await', 'box', 'type', 'struct', 'enum',
|
|
130
|
+
'str', 'u8', 'u16', 'u32', 'u64', 'usize', 'i8', 'i16', 'i32', 'i64', 'isize', 'bool', 'char', 'f32', 'f64',
|
|
131
|
+
]);
|
|
132
|
+
/**
|
|
133
|
+
* True when the (masked) `line` reads a value other than `name`: another
|
|
134
|
+
* local, a lower-case free or module-qualified call (`std::env::args()`), or
|
|
135
|
+
* an inline format argument (`{other}`). Method names, associated functions
|
|
136
|
+
* of a type (`Command::new`), macros, type names and closure parameters are
|
|
137
|
+
* not values.
|
|
138
|
+
*/
|
|
139
|
+
function readsOtherValue(original, masked, name) {
|
|
140
|
+
for (const m of original.matchAll(new RegExp(STR, 'g'))) {
|
|
141
|
+
for (const f of m[0].matchAll(/(?<!\{)\{([A-Za-z_]\w*)(?:[:}])/g))
|
|
142
|
+
if (f[1] !== name)
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
const closureParams = new Set();
|
|
146
|
+
for (const m of masked.matchAll(/\|\s*([\w\s,&:()]*?)\s*\|/g)) {
|
|
147
|
+
for (const p of m[1].matchAll(/[A-Za-z_]\w*/g))
|
|
148
|
+
closureParams.add(p[0]);
|
|
149
|
+
}
|
|
150
|
+
const re = /[A-Za-z_]\w*/g;
|
|
151
|
+
let m;
|
|
152
|
+
while ((m = re.exec(masked)) !== null) {
|
|
153
|
+
const id = m[0];
|
|
154
|
+
const before = masked.slice(0, m.index);
|
|
155
|
+
const after = masked.slice(m.index + id.length);
|
|
156
|
+
if (id === name || KEYWORDS.has(id) || closureParams.has(id))
|
|
157
|
+
continue;
|
|
158
|
+
if (/\.\s*$/.test(before))
|
|
159
|
+
continue; // method or field
|
|
160
|
+
if (/^\s*!/.test(after) && !/^\s*!=/.test(after))
|
|
161
|
+
continue; // macro
|
|
162
|
+
if (/[A-Z]/.test(id[0]))
|
|
163
|
+
continue; // type, variant, constant
|
|
164
|
+
if (/(?:\blet\s+(?:mut\s+)?)$/.test(before))
|
|
165
|
+
continue; // the binding being introduced
|
|
166
|
+
if (/::\s*$/.test(before))
|
|
167
|
+
continue; // path tail (`io::stdin` handled by its head)
|
|
168
|
+
return true; // other local, free call, module path
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* `&mut` parameter only: the bare name passed as a call argument can be
|
|
174
|
+
* mutated by the callee (checked per line).
|
|
175
|
+
*/
|
|
176
|
+
function passesMutParam(line, n) {
|
|
177
|
+
if (!new RegExp(String.raw `(?<![\w.])(?:[A-Za-z_]\w*(?:\s*::\s*[A-Za-z_]\w*)*)\s*\((?:[^)]*,\s*)?${n}\b`).test(line))
|
|
178
|
+
return false;
|
|
179
|
+
// Exclude method calls on name itself (`name.foo(`), handled by firstRebind.
|
|
180
|
+
return !new RegExp(String.raw `\b${n}\s*\.\s*\w+\s*\(`).test(line) || new RegExp(String.raw `(?<![\w.])\w+\s*\(\s*${n}\b`).test(line);
|
|
181
|
+
}
|
|
182
|
+
export function findRustLiteralEqualityGuardSanitizers(code) {
|
|
183
|
+
const masked = maskRust(code);
|
|
184
|
+
const origLines = code.split('\n');
|
|
185
|
+
const maskedLines = masked.split('\n');
|
|
186
|
+
const lineStarts = [];
|
|
187
|
+
for (let i = 0, off = 0; i < origLines.length; i++) {
|
|
188
|
+
lineStarts.push(off);
|
|
189
|
+
off += origLines[i].length + 1;
|
|
190
|
+
}
|
|
191
|
+
const lineOf = (idx) => {
|
|
192
|
+
let lo = 0, hi = lineStarts.length - 1;
|
|
193
|
+
while (lo < hi) {
|
|
194
|
+
const mid = (lo + hi + 1) >> 1;
|
|
195
|
+
if (lineStarts[mid] <= idx)
|
|
196
|
+
lo = mid;
|
|
197
|
+
else
|
|
198
|
+
hi = mid - 1;
|
|
199
|
+
}
|
|
200
|
+
return lo; // 0-based
|
|
201
|
+
};
|
|
202
|
+
const out = [];
|
|
203
|
+
for (const ifm of masked.matchAll(/\bif\b/g)) {
|
|
204
|
+
const at = ifm.index;
|
|
205
|
+
if (/\belse\s*$/.test(masked.slice(Math.max(0, at - 12), at)))
|
|
206
|
+
continue;
|
|
207
|
+
if (/\blet\b/.test(masked.slice(at + 2, at + 8)))
|
|
208
|
+
continue; // `if let`
|
|
209
|
+
// Condition: up to the `{` that opens the block, at bracket depth 0.
|
|
210
|
+
let depth = 0;
|
|
211
|
+
let open = -1;
|
|
212
|
+
for (let i = at + 2; i < masked.length; i++) {
|
|
213
|
+
const ch = masked[i];
|
|
214
|
+
if (ch === '(' || ch === '[')
|
|
215
|
+
depth++;
|
|
216
|
+
else if (ch === ')' || ch === ']')
|
|
217
|
+
depth--;
|
|
218
|
+
else if (ch === '{' && depth === 0) {
|
|
219
|
+
open = i;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
else if (ch === ';' || ch === '}')
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (open < 0)
|
|
226
|
+
continue;
|
|
227
|
+
const name = guardedVariable(code.slice(at + 2, open));
|
|
228
|
+
if (name === null)
|
|
229
|
+
continue;
|
|
230
|
+
const close = matchBrace(masked, open);
|
|
231
|
+
if (close < 0)
|
|
232
|
+
continue;
|
|
233
|
+
if (/^\s*else\b/.test(masked.slice(close + 1, close + 12)))
|
|
234
|
+
continue;
|
|
235
|
+
// The block must reject at its own top level (not inside an inner branch).
|
|
236
|
+
// Strip nested braces and braceless closure bodies (`|…| expr`) so a
|
|
237
|
+
// `return` inside a closure does not count as the guard rejecting.
|
|
238
|
+
const body = masked.slice(open + 1, close).split('');
|
|
239
|
+
for (let i = 0, d = 0; i < body.length; i++) {
|
|
240
|
+
if (body[i] === '{') {
|
|
241
|
+
d++;
|
|
242
|
+
body[i] = ' ';
|
|
243
|
+
}
|
|
244
|
+
else if (body[i] === '}') {
|
|
245
|
+
d--;
|
|
246
|
+
body[i] = ' ';
|
|
247
|
+
}
|
|
248
|
+
else if (d > 0 && body[i] !== '\n')
|
|
249
|
+
body[i] = ' ';
|
|
250
|
+
}
|
|
251
|
+
let bodyText = body.join('');
|
|
252
|
+
bodyText = bodyText.replace(/\|\s*[\w\s,&:()]*?\s*\|\s*[^;{}]*/g, ' ');
|
|
253
|
+
if (!/(?<![\w.#])(?:return\b|panic\s*!|unreachable\s*!|bail\s*!|(?:std\s*::\s*)?process\s*::\s*exit\s*\()/.test(bodyText))
|
|
254
|
+
continue;
|
|
255
|
+
// Credit region: after the guard block to the end of the enclosing block.
|
|
256
|
+
let end = masked.length;
|
|
257
|
+
for (let i = close + 1, d = 0; i < masked.length; i++) {
|
|
258
|
+
if (masked[i] === '{')
|
|
259
|
+
d++;
|
|
260
|
+
else if (masked[i] === '}' && --d < 0) {
|
|
261
|
+
end = i;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Is the guarded binding a `&mut` parameter of the enclosing function?
|
|
266
|
+
let mutParam = false;
|
|
267
|
+
{
|
|
268
|
+
const before = masked.slice(0, at);
|
|
269
|
+
let fnOpen = -1;
|
|
270
|
+
for (const m of before.matchAll(/\bfn\s+\w+\s*(?:<[^>]*>)?\s*\(/g))
|
|
271
|
+
fnOpen = m.index + m[0].length - 1;
|
|
272
|
+
if (fnOpen >= 0) {
|
|
273
|
+
let depth = 1, fnClose = -1;
|
|
274
|
+
for (let i = fnOpen + 1; i < at; i++) {
|
|
275
|
+
if (masked[i] === '(')
|
|
276
|
+
depth++;
|
|
277
|
+
else if (masked[i] === ')' && --depth === 0) {
|
|
278
|
+
fnClose = i;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (fnClose > fnOpen) {
|
|
283
|
+
const params = masked.slice(fnOpen + 1, fnClose);
|
|
284
|
+
mutParam = new RegExp(String.raw `\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(params);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Could the binding be `mut`? Any `mut name` / `name: &mut` before the
|
|
289
|
+
// guard counts (wider than needed, which only ends the credit sooner).
|
|
290
|
+
const mutBinding = mutParam || new RegExp(String.raw `\bmut\s+${name}\b|\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(masked.slice(0, at));
|
|
291
|
+
// Whole lines after the guard's closing line, up to the line before the
|
|
292
|
+
// enclosing block's closing brace (or the end of the file).
|
|
293
|
+
const firstLine = lineOf(close) + 1;
|
|
294
|
+
const lastLine = end === masked.length ? origLines.length - 1 : lineOf(end) - 1;
|
|
295
|
+
let stop = lastLine + 1;
|
|
296
|
+
// A rebind or mutation ends the credit (scanned over the whole region, so a
|
|
297
|
+
// pattern or parameter list wrapped over lines is seen in one piece);
|
|
298
|
+
// inside a later loop it ends at the loop.
|
|
299
|
+
let rebindLine = lastLine + 1;
|
|
300
|
+
const rb = firstRebind(masked, close + 1, end, name, { mutBinding });
|
|
301
|
+
if (rb >= 0)
|
|
302
|
+
rebindLine = lineOf(rb);
|
|
303
|
+
if (mutParam) {
|
|
304
|
+
for (let l = firstLine; l < rebindLine && l <= lastLine; l++) {
|
|
305
|
+
if (passesMutParam(maskedLines[l], name)) {
|
|
306
|
+
rebindLine = l;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (rebindLine <= lastLine) {
|
|
312
|
+
const l = rebindLine;
|
|
313
|
+
stop = l;
|
|
314
|
+
for (const lp of masked.slice(close + 1, end).matchAll(/\b(?:for|while|loop)\b[^{;]*\{/g)) {
|
|
315
|
+
const lpOpen = close + 1 + lp.index + lp[0].length - 1;
|
|
316
|
+
const lpClose = matchBrace(masked, lpOpen);
|
|
317
|
+
const lpLine = lineOf(lpOpen);
|
|
318
|
+
if (lpClose >= 0 && lineOf(lpClose) >= l && lpLine <= l)
|
|
319
|
+
stop = Math.min(stop, lpLine);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const mention = new RegExp(String.raw `(?<![\w.])${name}\b`);
|
|
323
|
+
for (let l = firstLine; l < stop && l <= lastLine; l++) {
|
|
324
|
+
if (!mention.test(maskedLines[l]))
|
|
325
|
+
continue;
|
|
326
|
+
// Evaluate "reads another value" over the whole statement that contains
|
|
327
|
+
// this mention (up to a terminating `;` or the matching close of the
|
|
328
|
+
// enclosing call), not only the single line the name sits on.
|
|
329
|
+
// The line itself is checked too, so a second statement on the same
|
|
330
|
+
// line (`a(tool); b(other);`) also ends the credit for that line.
|
|
331
|
+
const stmt = statementSpan(code, masked, lineStarts[l], end);
|
|
332
|
+
if (readsOtherValue(stmt.orig, stmt.masked, name))
|
|
333
|
+
continue;
|
|
334
|
+
if (readsOtherValue(origLines[l], maskedLines[l], name))
|
|
335
|
+
continue;
|
|
336
|
+
out.push({
|
|
337
|
+
type: 'rust_literal_equality_guard',
|
|
338
|
+
method: 'guard',
|
|
339
|
+
line: l + 1,
|
|
340
|
+
sanitizes: CREDITED_TYPES,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return out;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Exact text of the statement that contains `lineStart` (absolute index),
|
|
348
|
+
* clipped to `endIdx`. Walks back to the previous `;` / `{` / `}` at depth 0
|
|
349
|
+
* and forward to a terminating `;` (or unmatched closer), so a multi-line
|
|
350
|
+
* `format!(…, tool, extra)` is considered as one statement without pulling in
|
|
351
|
+
* the enclosing function signature.
|
|
352
|
+
*/
|
|
353
|
+
function statementSpan(code, masked, lineStart, endIdx) {
|
|
354
|
+
// Walk back to the previous statement boundary at bracket depth 0.
|
|
355
|
+
let start = lineStart;
|
|
356
|
+
let depth = 0;
|
|
357
|
+
for (let i = lineStart - 1; i >= 0; i--) {
|
|
358
|
+
const ch = masked[i];
|
|
359
|
+
if (ch === ')' || ch === ']')
|
|
360
|
+
depth++;
|
|
361
|
+
else if (ch === '(' || ch === '[') {
|
|
362
|
+
if (depth === 0) {
|
|
363
|
+
start = i + 1;
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
depth--;
|
|
367
|
+
}
|
|
368
|
+
else if (ch === '}') {
|
|
369
|
+
if (depth === 0) {
|
|
370
|
+
start = i + 1;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
depth++; // matching an earlier `{` when walking back through nested blocks
|
|
374
|
+
}
|
|
375
|
+
else if (ch === '{') {
|
|
376
|
+
if (depth === 0) {
|
|
377
|
+
start = i + 1;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
depth--;
|
|
381
|
+
}
|
|
382
|
+
else if (ch === ';' && depth === 0) {
|
|
383
|
+
start = i + 1;
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
if (i === 0)
|
|
387
|
+
start = 0;
|
|
388
|
+
}
|
|
389
|
+
// Walk forward to terminating `;` at depth 0, or stop at `endIdx` / unmatched `}`.
|
|
390
|
+
depth = 0;
|
|
391
|
+
let stop = Math.min(endIdx, masked.length);
|
|
392
|
+
for (let i = start; i < stop; i++) {
|
|
393
|
+
const ch = masked[i];
|
|
394
|
+
if (ch === '(' || ch === '[')
|
|
395
|
+
depth++;
|
|
396
|
+
else if (ch === ')' || ch === ']') {
|
|
397
|
+
if (depth === 0) {
|
|
398
|
+
stop = i;
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
depth--;
|
|
402
|
+
}
|
|
403
|
+
else if (ch === '{')
|
|
404
|
+
depth++;
|
|
405
|
+
else if (ch === '}') {
|
|
406
|
+
if (depth === 0) {
|
|
407
|
+
stop = i;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
depth--;
|
|
411
|
+
}
|
|
412
|
+
else if (ch === ';' && depth === 0) {
|
|
413
|
+
stop = i + 1;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
orig: code.slice(start, stop),
|
|
419
|
+
masked: masked.slice(start, stop),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=rust-literal-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust-literal-guard.js","sourceRoot":"","sources":["../../src/analysis/rust-literal-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,4 +22,12 @@ export declare function isScalarDerivation(rhs: string, language: string): boole
|
|
|
22
22
|
* by a whole-expression measure or test. Taint does not flow into these defs.
|
|
23
23
|
*/
|
|
24
24
|
export declare function scalarDerivedDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
|
|
25
|
+
/**
|
|
26
|
+
* DFG def ids of a Go local initialised by `make(<type>, <len>[, <cap>])` whose
|
|
27
|
+
* every size argument is an integer literal or a variable rejected above a
|
|
28
|
+
* constant earlier in the same function (`if n > K { return }`). The buffer
|
|
29
|
+
* holds zero values; its size is bounded, so the request text that chose the
|
|
30
|
+
* size does not reach a sink through it. An unbounded size is not credited.
|
|
31
|
+
*/
|
|
32
|
+
export declare function boundedMakeDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
|
|
25
33
|
//# sourceMappingURL=scalar-derivation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scalar-derivation.d.ts","sourceRoot":"","sources":["../../src/analysis/scalar-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAyGhD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkBzE;AAgBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAaxG"}
|
|
1
|
+
{"version":3,"file":"scalar-derivation.d.ts","sourceRoot":"","sources":["../../src/analysis/scalar-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAyGhD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkBzE;AAgBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAaxG;AA0ID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAsBtG"}
|
|
@@ -193,4 +193,176 @@ export function scalarDerivedDefIds(defs, code, language) {
|
|
|
193
193
|
}
|
|
194
194
|
return out;
|
|
195
195
|
}
|
|
196
|
+
/** An integer literal, optionally with `_` separators or a hex/binary/octal prefix. */
|
|
197
|
+
const GO_INT_LITERAL = /^(?:0[xX][0-9a-fA-F_]+|0[bB][01_]+|0[oO]?[0-7_]+|[1-9][0-9_]*|0)$/;
|
|
198
|
+
/** Braces in a Go line, with string, rune and raw-string literals blanked out. */
|
|
199
|
+
function goBraceText(text) {
|
|
200
|
+
return text.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`[^`]*`/g, '""');
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Names `n` bounded by `if <... n > K | n >= K ...> { ...; return|panic|continue }`
|
|
204
|
+
* in `lines[from .. to)` where the guard still dominates line `to`. The condition
|
|
205
|
+
* may join the bound with `||` only: under `&&` the branch would not reject every
|
|
206
|
+
* large value. K is an integer literal or a name in `consts` (a same-file integer
|
|
207
|
+
* `const`, see `goIntConstNames`).
|
|
208
|
+
*
|
|
209
|
+
* A guard only holds while the block it sits in is open: once the brace depth
|
|
210
|
+
* falls below the guard's depth (the enclosing `if`, loop, closure or `else`
|
|
211
|
+
* branch closed), or a new `case`/`default` clause of the same switch starts,
|
|
212
|
+
* other paths reach `to` without passing the guard. A write to `n` after the
|
|
213
|
+
* guard (`n = …`, `n op= …`, `n++`, `n--`, or `&n` handed to a callee such as
|
|
214
|
+
* `fmt.Sscanf`) voids every bound on it.
|
|
215
|
+
*/
|
|
216
|
+
function goUpperBoundGuardedAt(lines, from, to, name, consts) {
|
|
217
|
+
const esc = name.replace(/[$]/g, '\\$');
|
|
218
|
+
const bound = new RegExp(`^\\(*\\s*${esc}\\s*>=?\\s*([\\w]+)\\s*\\)*$`);
|
|
219
|
+
const reassign = new RegExp(`(?:^|[\\s,;(])${esc}(?:\\s*,\\s*\\w+)*\\s*(?::=|=(?!=)|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\^=|&\\^=|<<=|>>=)` +
|
|
220
|
+
`|(?<![\\w.])${esc}\\s*(?:\\+\\+|--)` +
|
|
221
|
+
`|(?<![&\\w])&\\s*${esc}\\b`);
|
|
222
|
+
// Depth (in braces) of each guard still in force, in source order.
|
|
223
|
+
let guards = [];
|
|
224
|
+
let depth = 0;
|
|
225
|
+
for (let i = from; i < to; i++) {
|
|
226
|
+
const text = lines[i].replace(/\s*\/\/.*$/, '').trim();
|
|
227
|
+
if (guards.length > 0 && reassign.test(text))
|
|
228
|
+
guards = [];
|
|
229
|
+
const ifm = /^if\s+(.+?)\s*\{$/.exec(text);
|
|
230
|
+
if (ifm && i + 1 < to) {
|
|
231
|
+
const cond = ifm[1];
|
|
232
|
+
if (!cond.includes('&&')) {
|
|
233
|
+
const parts = cond.split('||').map((p) => p.trim());
|
|
234
|
+
const hit = parts.some((p) => {
|
|
235
|
+
const m = bound.exec(p);
|
|
236
|
+
return m !== null && (GO_INT_LITERAL.test(m[1]) || consts.has(m[1]));
|
|
237
|
+
});
|
|
238
|
+
if (hit) {
|
|
239
|
+
// The guard block must end in an exit before its closing brace.
|
|
240
|
+
let inner = 1;
|
|
241
|
+
let last = '';
|
|
242
|
+
let j = i + 1;
|
|
243
|
+
for (; j < to; j++) {
|
|
244
|
+
const t = lines[j].replace(/\s*\/\/.*$/, '').trim();
|
|
245
|
+
for (const ch of goBraceText(t))
|
|
246
|
+
inner += ch === '{' ? 1 : ch === '}' ? -1 : 0;
|
|
247
|
+
if (inner <= 0)
|
|
248
|
+
break;
|
|
249
|
+
if (t)
|
|
250
|
+
last = t;
|
|
251
|
+
}
|
|
252
|
+
if (inner <= 0 && /^(?:return\b|panic\(|continue\b)/.test(last)) {
|
|
253
|
+
// The block opened and closed on lines i..j; depth is unchanged.
|
|
254
|
+
guards.push(depth);
|
|
255
|
+
i = j;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (guards.length > 0 && /^(?:case\b.*|default\s*):$/.test(text)) {
|
|
262
|
+
guards = guards.filter((d) => d < depth);
|
|
263
|
+
}
|
|
264
|
+
for (const ch of goBraceText(text)) {
|
|
265
|
+
if (ch === '{')
|
|
266
|
+
depth++;
|
|
267
|
+
else if (ch === '}') {
|
|
268
|
+
depth--;
|
|
269
|
+
if (guards.length > 0)
|
|
270
|
+
guards = guards.filter((d) => d <= depth);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return guards.length > 0;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Names declared exactly once in the file, as a package- or function-level
|
|
278
|
+
* `const NAME [type] = <integer literal>` (alone or inside a `const ( … )` block),
|
|
279
|
+
* and never otherwise defined: no `:=` or `var` of the same name, no parameter,
|
|
280
|
+
* result or range variable of that name, no second `const` of it. A name that
|
|
281
|
+
* could be shadowed by a variable is not a constant bound.
|
|
282
|
+
*/
|
|
283
|
+
function goIntConstNames(lines) {
|
|
284
|
+
const decl = /^(?:const\s+)?([A-Za-z_]\w*)(?:\s+[\w.]+)?\s*=\s*([\w]+)\s*$/;
|
|
285
|
+
const found = new Map();
|
|
286
|
+
let inBlock = false;
|
|
287
|
+
const declLines = new Set();
|
|
288
|
+
for (let i = 0; i < lines.length; i++) {
|
|
289
|
+
const text = lines[i].replace(/\s*\/\/.*$/, '').trim();
|
|
290
|
+
if (inBlock) {
|
|
291
|
+
if (text === ')') {
|
|
292
|
+
inBlock = false;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const m = decl.exec(text);
|
|
296
|
+
if (m && GO_INT_LITERAL.test(m[2]) && !/^const\b/.test(text)) {
|
|
297
|
+
found.set(m[1], (found.get(m[1]) ?? 0) + 1);
|
|
298
|
+
declLines.add(i);
|
|
299
|
+
}
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (/^const\s*\($/.test(text)) {
|
|
303
|
+
inBlock = true;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (/^const\s/.test(text)) {
|
|
307
|
+
const m = decl.exec(text);
|
|
308
|
+
if (m && GO_INT_LITERAL.test(m[2])) {
|
|
309
|
+
found.set(m[1], (found.get(m[1]) ?? 0) + 1);
|
|
310
|
+
declLines.add(i);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const out = new Set();
|
|
315
|
+
for (const [name, count] of found) {
|
|
316
|
+
if (count !== 1)
|
|
317
|
+
continue;
|
|
318
|
+
const esc = name.replace(/[$]/g, '\\$');
|
|
319
|
+
const other = new RegExp(`(?:^|[\\s,(])${esc}(?:\\s*,\\s*[\\w]+)*\\s*(?::=|=(?!=))` +
|
|
320
|
+
`|\\b(?:var|const|type|func)\\s+${esc}\\b` +
|
|
321
|
+
`|[(,]\\s*${esc}(?:\\s*,\\s*\\w+)*\\s+[\\w*\\[.]`);
|
|
322
|
+
const shadowed = lines.some((l, i) => {
|
|
323
|
+
if (declLines.has(i))
|
|
324
|
+
return false;
|
|
325
|
+
const t = l.replace(/\s*\/\/.*$/, '');
|
|
326
|
+
return new RegExp(`(?<![\\w.])${esc}(?![\\w])`).test(t) && other.test(t);
|
|
327
|
+
});
|
|
328
|
+
if (!shadowed)
|
|
329
|
+
out.add(name);
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* DFG def ids of a Go local initialised by `make(<type>, <len>[, <cap>])` whose
|
|
335
|
+
* every size argument is an integer literal or a variable rejected above a
|
|
336
|
+
* constant earlier in the same function (`if n > K { return }`). The buffer
|
|
337
|
+
* holds zero values; its size is bounded, so the request text that chose the
|
|
338
|
+
* size does not reach a sink through it. An unbounded size is not credited.
|
|
339
|
+
*/
|
|
340
|
+
export function boundedMakeDefIds(defs, code, language) {
|
|
341
|
+
const out = new Set();
|
|
342
|
+
if (language !== 'go')
|
|
343
|
+
return out;
|
|
344
|
+
const lines = code.split('\n');
|
|
345
|
+
const consts = goIntConstNames(lines);
|
|
346
|
+
for (const def of defs) {
|
|
347
|
+
if (def.kind !== 'local')
|
|
348
|
+
continue;
|
|
349
|
+
const text = lines[def.line - 1];
|
|
350
|
+
if (text === undefined)
|
|
351
|
+
continue;
|
|
352
|
+
const rhs = initializerOf(text, def.variable, 'go');
|
|
353
|
+
const mk = rhs === null ? null : /^make\(\s*(\[\][\w.*]+|map\[[^\]]+\][\w.*]+)\s*,\s*([^()]*?)\s*\)$/.exec(rhs);
|
|
354
|
+
if (!mk)
|
|
355
|
+
continue;
|
|
356
|
+
const sizes = mk[2].split(',').map((s) => s.trim());
|
|
357
|
+
if (sizes.length > 2 || sizes.some((s) => s === ''))
|
|
358
|
+
continue;
|
|
359
|
+
let fnStart = def.line - 1;
|
|
360
|
+
while (fnStart > 0 && !/^func\b/.test(lines[fnStart]))
|
|
361
|
+
fnStart--;
|
|
362
|
+
const ok = sizes.every((s) => GO_INT_LITERAL.test(s) || (/^[A-Za-z_]\w*$/.test(s) && goUpperBoundGuardedAt(lines, fnStart, def.line - 1, s, consts)));
|
|
363
|
+
if (ok)
|
|
364
|
+
out.add(def.id);
|
|
365
|
+
}
|
|
366
|
+
return out;
|
|
367
|
+
}
|
|
196
368
|
//# sourceMappingURL=scalar-derivation.js.map
|