fix(extension): workbench.html 0-byte 파괴 방지 — pre-read/pre-write 안전 가드 추가

This commit is contained in:
Variet Worker
2026-03-12 17:05:29 +09:00
parent 52c9526fdb
commit a9feee6faa
5 changed files with 30 additions and 1 deletions

View File

@@ -459,6 +459,12 @@ async function setupApprovalObserver() {
continue;
}
let html = fs.readFileSync(htmlPath, 'utf8');
// SAFETY: Refuse to patch if file is empty or suspiciously small
// (race condition: another extension instance may be mid-write)
if (html.length < 500 || !html.includes('<!DOCTYPE html>')) {
logToFile(`[OBSERVER] ${htmlFileName} appears corrupt or empty (${html.length} bytes) — SKIPPING to prevent further damage`);
continue;
}
// CRITICAL: Patch CSP to allow inline scripts.
// Default CSP has script-src 'self' 'unsafe-eval' blob: — NO 'unsafe-inline'.
// Without 'unsafe-inline', all inline <script> tags are silently blocked.
@@ -490,6 +496,11 @@ async function setupApprovalObserver() {
html = html.replace('</html>', `\n${inlineMarkerStart}\n<script>\n${combinedScript}\n</script>\n${inlineMarkerEnd}\n</html>`);
logToFile(`[OBSERVER] ${htmlFileName} inline script INSERTED`);
}
// SAFETY: Final validation before write — never write empty or invalid HTML
if (html.length < 500 || !html.includes('<!DOCTYPE html>')) {
logToFile(`[OBSERVER] ${htmlFileName} WOULD BE CORRUPT after patching (${html.length} bytes) — ABORTING write`);
continue;
}
fs.writeFileSync(htmlPath, html, 'utf8');
}
catch (e) {

File diff suppressed because one or more lines are too long

View File

@@ -441,6 +441,13 @@ async function setupApprovalObserver() {
}
let html = fs.readFileSync(htmlPath, 'utf8');
// SAFETY: Refuse to patch if file is empty or suspiciously small
// (race condition: another extension instance may be mid-write)
if (html.length < 500 || !html.includes('<!DOCTYPE html>')) {
logToFile(`[OBSERVER] ${htmlFileName} appears corrupt or empty (${html.length} bytes) — SKIPPING to prevent further damage`);
continue;
}
// CRITICAL: Patch CSP to allow inline scripts.
// Default CSP has script-src 'self' 'unsafe-eval' blob: — NO 'unsafe-inline'.
// Without 'unsafe-inline', all inline <script> tags are silently blocked.
@@ -483,6 +490,11 @@ async function setupApprovalObserver() {
`\n${inlineMarkerStart}\n<script>\n${combinedScript}\n</script>\n${inlineMarkerEnd}\n</html>`);
logToFile(`[OBSERVER] ${htmlFileName} inline script INSERTED`);
}
// SAFETY: Final validation before write — never write empty or invalid HTML
if (html.length < 500 || !html.includes('<!DOCTYPE html>')) {
logToFile(`[OBSERVER] ${htmlFileName} WOULD BE CORRUPT after patching (${html.length} bytes) — ABORTING write`);
continue;
}
fs.writeFileSync(htmlPath, html, 'utf8');
} catch (e: any) {
logToFile(`[OBSERVER] ${htmlFileName} patch error: ${e.message}`);