bookworm-smart-assistant/scripts/patches/patch-w7-safe-age.js

75 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
/**
* Patch W7: health-check.js 时间回拨防护
* 注入 safeAge(t) 统一处理 Date.now() - mtimemax(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();