mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 12:15:57 +00:00
fix(hardening): handle regex literals in sync-call scanner
This commit is contained in:
@@ -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 |
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user