Skip to content

Commit ed91fcf

Browse files
committed
fix(init): add size guard and deduplicate JSON minification in preReadCommonFiles
- Add stat check before reading files in preReadCommonFiles, skipping files larger than MAX_FILE_BYTES (256KB). Prevents memory spikes from large files like Gemfile.lock. - Extract minifyJson() helper and use it in both preReadCommonFiles and readSingleFile to eliminate duplicated JSON.stringify(JSON.parse()) logic. Made-with: Cursor
1 parent f997526 commit ed91fcf

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

src/lib/init/local-ops.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ function prettyPrintJson(content: string, indent: JsonIndent): string {
8080
}
8181
}
8282

83+
/** Strip whitespace/formatting from JSON. Returns input unchanged if not valid JSON. */
84+
function minifyJson(content: string): string {
85+
try {
86+
return JSON.stringify(JSON.parse(content));
87+
} catch {
88+
return content;
89+
}
90+
}
91+
8392
/**
8493
* Patterns that indicate shell injection. Commands run via `spawn` (no shell),
8594
* so these have no runtime effect — they are defense-in-depth against command
@@ -387,13 +396,13 @@ export async function preReadCommonFiles(
387396
}
388397
try {
389398
const absPath = path.join(directory, filePath);
399+
const stat = await fs.promises.stat(absPath);
400+
if (stat.size > MAX_FILE_BYTES) {
401+
continue;
402+
}
390403
let content = await fs.promises.readFile(absPath, "utf-8");
391404
if (filePath.endsWith(".json")) {
392-
try {
393-
content = JSON.stringify(JSON.parse(content));
394-
} catch {
395-
// Not valid JSON — send as-is
396-
}
405+
content = minifyJson(content);
397406
}
398407
if (totalBytes + content.length <= MAX_PREREAD_TOTAL_BYTES) {
399408
cache[filePath] = content;
@@ -540,13 +549,8 @@ async function readSingleFile(
540549
content = await fs.promises.readFile(absPath, "utf-8");
541550
}
542551

543-
// Minify JSON files by stripping whitespace/formatting
544552
if (filePath.endsWith(".json")) {
545-
try {
546-
content = JSON.stringify(JSON.parse(content));
547-
} catch {
548-
// Not valid JSON (truncated, JSONC, etc.) — send as-is
549-
}
553+
content = minifyJson(content);
550554
}
551555

552556
return content;

0 commit comments

Comments
 (0)