circle-ir 4.16.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/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +37 -8
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +13 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js +48 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +58 -8
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +19 -3
- package/dist/analysis/passes/sink-filter-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 +38 -11
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/browser/circle-ir.js +134 -15
- package/package.json +1 -1
|
@@ -369,25 +369,44 @@ function resolveJavaDerivedAnchor(varName, derived, realSourceByVar, codeLines,
|
|
|
369
369
|
* const-prop never seeds those derived names. Argument-style derivations
|
|
370
370
|
* (`shown = encodeForPage(nick)`) must keep the veto so sanitizer credit holds.
|
|
371
371
|
*/
|
|
372
|
-
function javaReceiverChainDerivedVar(
|
|
372
|
+
function javaReceiverChainDerivedVar(rhsByLocal, localVar, seedVar) {
|
|
373
373
|
if (!seedVar || localVar === seedVar)
|
|
374
374
|
return false;
|
|
375
|
+
const rhsList = rhsByLocal.get(localVar);
|
|
376
|
+
if (!rhsList)
|
|
377
|
+
return false;
|
|
375
378
|
const esc = seedVar.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
376
379
|
const receiverOnRhs = new RegExp(`(?:^|[^\\w.$])${esc}\\s*\\.`, 'u');
|
|
380
|
+
return rhsList.some(rhs => receiverOnRhs.test(rhs));
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* cognium-dev#806 — the assignment RHS texts of each Java local, indexed once
|
|
384
|
+
* per file. `javaReceiverChainDerivedVar` used to re-run its declaration regex
|
|
385
|
+
* over every line for every (source, derived local) pair, which made large
|
|
386
|
+
* files take seconds. Same per-line matching, done once.
|
|
387
|
+
*/
|
|
388
|
+
function indexJavaLocalAssignments(code) {
|
|
377
389
|
const declRe = /^\s*(?:public|private|protected|static|final|volatile|transient|\s)*\s*(?:[A-Za-z_][\w.]*(?:\s*<[^>]*>)?(?:\s*\[\s*\])*)\s+([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
|
|
378
390
|
const assignRe = /^\s*([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
|
|
391
|
+
const index = new Map();
|
|
379
392
|
for (const line of code.split('\n')) {
|
|
380
393
|
const trimmed = line.trimStart();
|
|
381
394
|
if (trimmed.startsWith('//') || trimmed.startsWith('*'))
|
|
382
395
|
continue;
|
|
396
|
+
// Cheap pre-check: neither regex can match a line without `=` and `;`.
|
|
397
|
+
if (!line.includes('=') || !line.includes(';'))
|
|
398
|
+
continue;
|
|
383
399
|
const m = declRe.exec(line) ?? assignRe.exec(line);
|
|
384
|
-
if (!m
|
|
400
|
+
if (!m)
|
|
385
401
|
continue;
|
|
402
|
+
const list = index.get(m[1]);
|
|
386
403
|
const rhs = stripJavaTrailingComment(m[2]);
|
|
387
|
-
if (
|
|
388
|
-
|
|
404
|
+
if (list)
|
|
405
|
+
list.push(rhs);
|
|
406
|
+
else
|
|
407
|
+
index.set(m[1], [rhs]);
|
|
389
408
|
}
|
|
390
|
-
return
|
|
409
|
+
return index;
|
|
391
410
|
}
|
|
392
411
|
function makeConstPropVeto(constProp, graph, sources, code, language, sanitizers) {
|
|
393
412
|
const lines = typeof code === 'string' ? code.split('\n') : [];
|
|
@@ -553,16 +572,24 @@ export class TaintPropagationPass {
|
|
|
553
572
|
// into const-prop's tainted set so DFG + expression-scan vetoes keep them.
|
|
554
573
|
// Per-source seeding + receiver filter avoids argument-style derivations
|
|
555
574
|
// (`shown = encodeForPage(nick)`) that must stay vetoed for sanitizer credit.
|
|
575
|
+
// cognium-dev#806: index the assignments once, visit each seed name once,
|
|
576
|
+
// and skip the file-wide derivation when no local not already tainted has
|
|
577
|
+
// a `seed.` receiver on its RHS (only such locals can be added).
|
|
556
578
|
if (ctx.language === 'java' && typeof ctx.code === 'string') {
|
|
579
|
+
const rhsByLocal = indexJavaLocalAssignments(ctx.code);
|
|
580
|
+
const seen = new Set();
|
|
557
581
|
for (const s of sources) {
|
|
558
|
-
if (!s.variable)
|
|
582
|
+
if (!s.variable || seen.has(s.variable))
|
|
559
583
|
continue;
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
584
|
+
seen.add(s.variable);
|
|
585
|
+
const seedVar = s.variable;
|
|
586
|
+
const candidates = [...rhsByLocal.keys()].filter(v => !constProp.tainted.has(v) && javaReceiverChainDerivedVar(rhsByLocal, v, seedVar));
|
|
587
|
+
if (candidates.length === 0)
|
|
588
|
+
continue;
|
|
589
|
+
const derived = buildJavaTaintedVars(ctx.code, new Set([seedVar]));
|
|
590
|
+
for (const v of candidates) {
|
|
591
|
+
if (derived.has(v))
|
|
564
592
|
constProp.tainted.add(v);
|
|
565
|
-
}
|
|
566
593
|
}
|
|
567
594
|
}
|
|
568
595
|
}
|