fix(hardening): handle regex literals in sync-call scanner

This commit is contained in:
Tam Nhu Tran
2026-02-12 15:01:33 +07:00
parent 8193e9d67f
commit bb9d846a54
4 changed files with 97 additions and 20 deletions
+2 -2
View File
@@ -31,9 +31,9 @@ Baseline captured: `2026-02-12`.
| Metric | Baseline |
|---|---:|
| Sync fs occurrences (all) | 807 |
| Sync fs occurrences (all) | 835 |
| Sync fs files affected (all) | 100 |
| Sync fs occurrences (runtime hotpaths) | 696 |
| Sync fs occurrences (runtime hotpaths) | 724 |
| Sync fs files affected (runtime hotpaths) | 89 |
| Legacy shim markers | 131 |
| Legacy shim files affected | 56 |
+25 -15
View File
@@ -1,9 +1,9 @@
{
"scope": "src/**/*.{ts,tsx,js,jsx,mjs,cjs}",
"syncFs": {
"totalOccurrences": 807,
"totalOccurrences": 835,
"filesAffected": 100,
"hotpathOccurrences": 696,
"hotpathOccurrences": 724,
"hotpathFilesAffected": 89,
"topHotpathFiles": [
{
@@ -113,6 +113,24 @@
],
"markers": []
},
{
"file": "src/web-server/routes/cliproxy-stats-routes.ts",
"count": 20,
"calls": [
"closeSync",
"existsSync",
"fstatSync",
"mkdirSync",
"openSync",
"readdirSync",
"readFileSync",
"readSync",
"renameSync",
"statSync",
"writeFileSync"
],
"markers": []
},
{
"file": "src/web-server/routes/misc-routes.ts",
"count": 20,
@@ -144,17 +162,6 @@
"writeFileSync"
],
"markers": []
},
{
"file": "src/commands/cleanup-command.ts",
"count": 16,
"calls": [
"existsSync",
"lstatSync",
"readdirSync",
"unlinkSync"
],
"markers": []
}
],
"topFilesOverall": [
@@ -294,14 +301,17 @@
"markers": []
},
{
"file": "src/web-server/routes/misc-routes.ts",
"file": "src/web-server/routes/cliproxy-stats-routes.ts",
"count": 20,
"calls": [
"copyFileSync",
"closeSync",
"existsSync",
"fstatSync",
"mkdirSync",
"openSync",
"readdirSync",
"readFileSync",
"readSync",
"renameSync",
"statSync",
"writeFileSync"
+3 -3
View File
@@ -6,9 +6,9 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}`
| Metric | Value |
|---|---:|
| Sync fs occurrences (all) | 807 |
| Sync fs occurrences (all) | 835 |
| Sync fs files affected (all) | 100 |
| Sync fs occurrences (runtime hotpaths) | 696 |
| Sync fs occurrences (runtime hotpaths) | 724 |
| Sync fs files affected (runtime hotpaths) | 89 |
| Legacy shim markers | 131 |
| Legacy shim files affected | 56 |
@@ -24,9 +24,9 @@ Scope: `src/**/*.{ts,tsx,js,jsx,mjs,cjs}`
| `src/utils/claude-dir-installer.ts` | 21 | copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync |
| `src/cliproxy/binary/version-cache.ts` | 20 | existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync |
| `src/management/recovery-manager.ts` | 20 | copyFileSync, existsSync, mkdirSync, renameSync, writeFileSync |
| `src/web-server/routes/cliproxy-stats-routes.ts` | 20 | closeSync, existsSync, fstatSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, renameSync, statSync, writeFileSync |
| `src/web-server/routes/misc-routes.ts` | 20 | copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync |
| `src/web-server/routes/persist-routes.ts` | 17 | closeSync, copyFileSync, existsSync, lstatSync, openSync, readdirSync, readSync, renameSync, unlinkSync, writeFileSync |
| `src/commands/cleanup-command.ts` | 16 | existsSync, lstatSync, readdirSync, unlinkSync |
## Top Legacy Shim Marker Files
+67
View File
@@ -124,6 +124,12 @@ function summarize(items, limit = 10) {
}));
}
function isRegexLiteralStart(previousSignificantChar) {
return (
previousSignificantChar === '' || '([{:;,=!?+-*%^&|~<>'.includes(previousSignificantChar)
);
}
function stripComments(sourceText) {
let output = '';
let index = 0;
@@ -132,6 +138,9 @@ function stripComments(sourceText) {
let inSingleQuote = false;
let inDoubleQuote = false;
let inTemplateLiteral = false;
let inRegexLiteral = false;
let inRegexCharClass = false;
let previousSignificantChar = '';
while (index < sourceText.length) {
const current = sourceText[index];
@@ -161,6 +170,50 @@ function stripComments(sourceText) {
continue;
}
if (inRegexLiteral) {
if (current === '\n' || current === '\r') {
output += current;
index += 1;
inRegexLiteral = false;
inRegexCharClass = false;
continue;
}
output += ' ';
if (current === '\\') {
output += next === '\n' || next === '\r' ? next : ' ';
index += 2;
continue;
}
if (!inRegexCharClass && current === '[') {
inRegexCharClass = true;
index += 1;
continue;
}
if (inRegexCharClass && current === ']') {
inRegexCharClass = false;
index += 1;
continue;
}
if (!inRegexCharClass && current === '/') {
index += 1;
while (index < sourceText.length && /[a-z]/i.test(sourceText[index])) {
output += ' ';
index += 1;
}
inRegexLiteral = false;
previousSignificantChar = 'r';
continue;
}
index += 1;
continue;
}
if (inSingleQuote) {
output += current === '\n' || current === '\r' ? current : ' ';
if (current === '\\') {
@@ -170,6 +223,7 @@ function stripComments(sourceText) {
}
if (current === "'") {
inSingleQuote = false;
previousSignificantChar = 's';
}
index += 1;
continue;
@@ -184,6 +238,7 @@ function stripComments(sourceText) {
}
if (current === '"') {
inDoubleQuote = false;
previousSignificantChar = 's';
}
index += 1;
continue;
@@ -198,6 +253,7 @@ function stripComments(sourceText) {
}
if (current === '`') {
inTemplateLiteral = false;
previousSignificantChar = 's';
}
index += 1;
continue;
@@ -217,6 +273,14 @@ function stripComments(sourceText) {
continue;
}
if (current === '/' && isRegexLiteralStart(previousSignificantChar)) {
output += ' ';
index += 1;
inRegexLiteral = true;
inRegexCharClass = false;
continue;
}
if (current === "'") {
inSingleQuote = true;
output += ' ';
@@ -239,6 +303,9 @@ function stripComments(sourceText) {
}
output += current;
if (!/\s/.test(current)) {
previousSignificantChar = current;
}
index += 1;
}