Summary
Found during fine-grained code-quality review (second pass) at commit 14fbf3e (develop). Severity: low — bug. Four utility-layer defects in ornn-web/src/utils/:
formatFileSize out-of-range output (formatters.ts:9-15): units stop at GB — ≥1 TB yields "1.0 undefined"; negative input yields NaN (Math.log(<0)). The unit tests stop at exactly 1 GB so both are uncovered. Fix: clamp the unit index and guard negatives.
buildFrontmatter doesn't escape newlines in quoted YAML scalars (frontmatterBuilder.ts:25-38): a description containing \n is double-quoted but the literal newline is emitted raw — YAML line-folding silently rewrites content (newline → space) or breaks parsing. Fix: add .replace(/\n/g, "\\n") to the escape chain.
- LLM-supplied script filenames not path-sanitized (
generationParser.ts:121-126): scripts/${s.filename} accepts ../, absolute, or backslash names straight from model output into the preview tree and the upload ZIP. The hand-written guard in zipValidator.ts:53-62 (isUnsafeEntryPath) shows the project cares about exactly this class — the generative path skips it (backend is the only line of defense). Fix: reject/normalize segments the same way.
- Zip-bomb cap rides on a JSZip private field with silent-off fallback (
zipValidator.ts:206-214): entry._data?.uncompressedSize ?? 0 — a JSZip internals change makes every entry contribute 0 and the 50 MB cap silently disables. Fix: treat missing _data as unverifiable and fail closed.
Summary
Found during fine-grained code-quality review (second pass) at commit
14fbf3e(develop). Severity: low — bug. Four utility-layer defects inornn-web/src/utils/:formatFileSizeout-of-range output (formatters.ts:9-15): units stop at GB — ≥1 TB yields"1.0 undefined"; negative input yields NaN (Math.log(<0)). The unit tests stop at exactly 1 GB so both are uncovered. Fix: clamp the unit index and guard negatives.buildFrontmatterdoesn't escape newlines in quoted YAML scalars (frontmatterBuilder.ts:25-38): a description containing\nis double-quoted but the literal newline is emitted raw — YAML line-folding silently rewrites content (newline → space) or breaks parsing. Fix: add.replace(/\n/g, "\\n")to the escape chain.generationParser.ts:121-126):scripts/${s.filename}accepts../, absolute, or backslash names straight from model output into the preview tree and the upload ZIP. The hand-written guard inzipValidator.ts:53-62(isUnsafeEntryPath) shows the project cares about exactly this class — the generative path skips it (backend is the only line of defense). Fix: reject/normalize segments the same way.zipValidator.ts:206-214):entry._data?.uncompressedSize ?? 0— a JSZip internals change makes every entry contribute 0 and the 50 MB cap silently disables. Fix: treat missing_dataas unverifiable and fail closed.