#!/usr/bin/env node /** * Patch W7: health-check.js 时间回拨防护 * 注入 safeAge(t) 统一处理 Date.now() - mtime,max(0, diff) 防负值 * 幂等: sentinel W7_SAFE_AGE_v1 */ const fs = require('fs'); const path = require('path'); const TARGET = path.join(__dirname, '..', 'health-check.js'); const SENTINEL = 'W7_SAFE_AGE_v1'; function main() { if (!fs.existsSync(TARGET)) { console.error('[patch-w7] missing target'); process.exit(2); } const src = fs.readFileSync(TARGET, 'utf8'); if (src.includes(SENTINEL)) { console.error('[patch-w7] already applied, skip'); process.exit(0); } // 1) 注入 safeAge helper (在 JSON_MODE 声明后) const anchor1 = "const JSON_MODE = process.argv.includes('--json');"; if (!src.includes(anchor1)) { console.error('[patch-w7] anchor1 missing'); process.exit(3); } const helperBlock = anchor1 + "\n\n" + "// " + SENTINEL + ": 时间回拨防护 (NTP 回跳/跨时区/休眠恢复)\n" + "function safeAge(t) {\n" + " const ts = typeof t === 'number' ? t : (t && t.getTime ? t.getTime() : 0);\n" + " const d = Date.now() - ts;\n" + " return d < 0 ? 0 : d;\n" + "}\n"; let patched = src.replace(anchor1, helperBlock); // 2) 替换 4 处 Date.now() - X 调用点 const replacements = [ { from: "const lockAge = (Date.now() - fs.statSync(lockFile).mtimeMs) / 3600000;", to: "const lockAge = safeAge(fs.statSync(lockFile).mtimeMs) / 3600000;" }, { from: "const daysSince = genDate ? Math.floor((Date.now() - genDate.getTime()) / 86400000) : -1;", to: "const daysSince = genDate ? Math.floor(safeAge(genDate) / 86400000) : -1;", all: true }, { from: "return (Date.now() - created) > 30 * 60 * 1000;", to: "return safeAge(created) > 30 * 60 * 1000;" } ]; let hitCount = 0; for (const r of replacements) { if (r.all) { while (patched.includes(r.from)) { patched = patched.replace(r.from, r.to); hitCount++; } } else { if (!patched.includes(r.from)) { console.error('[patch-w7] miss:', r.from.slice(0,60)); process.exit(4); } patched = patched.replace(r.from, r.to); hitCount++; } } if (hitCount < 4) { console.error('[patch-w7] expected 4 hits, got', hitCount); process.exit(5); } if (patched === src) { console.error('[patch-w7] nothing changed'); process.exit(6); } const bakDir = path.join(path.dirname(TARGET), 'patches', 'bak'); if (!fs.existsSync(bakDir)) fs.mkdirSync(bakDir, { recursive: true }); const bak = path.join(bakDir, 'health-check.js.bak.w7.' + Date.now()); fs.writeFileSync(bak, src); const tmp = TARGET + '.tmp.' + process.pid; fs.writeFileSync(tmp, patched); fs.renameSync(tmp, TARGET); console.error('[patch-w7] applied, hits=' + hitCount + ', bak=' + bak); } main();