fix(plan-canvas): validate opened PDF handle

This commit is contained in:
haelyra
2026-08-28 16:47:36 -04:00
parent 93cec5aa6c
commit 3fbc1ad164
2 changed files with 24 additions and 2 deletions
+2 -2
View File
@@ -115,9 +115,9 @@ function assertLoopbackUrl(value) {
function isCompletePdf(file, fsImpl = fs) {
let fd;
try {
const stat = fsImpl.statSync(file);
if (!stat.isFile() || stat.size < 12) return false;
fd = fsImpl.openSync(file, 'r');
const stat = fsImpl.fstatSync(fd);
if (!stat.isFile() || stat.size < 12) return false;
const head = Buffer.alloc(5);
fsImpl.readSync(fd, head, 0, head.length, 0);
const tailLength = Math.min(2048, stat.size);
+22
View File
@@ -102,6 +102,28 @@ async function main() {
fs.rmSync(tmp, { recursive: true, force: true });
});
await test('validates PDF metadata from the opened file handle', () => {
const content = Buffer.from('%PDF-1.4\nlocal plan\n%%EOF\n');
const fsImpl = {
openSync(file, flags) {
assert.strictEqual(file, '/private/export.pdf');
assert.strictEqual(flags, 'r');
return 41;
},
fstatSync(fd) {
assert.strictEqual(fd, 41);
return { isFile: () => true, size: content.length };
},
readSync(fd, target, offset, length, position) {
assert.strictEqual(fd, 41);
return content.copy(target, offset, position, position + length);
},
closeSync(fd) { assert.strictEqual(fd, 41); },
statSync() { throw new Error('path metadata must not be checked before opening'); }
};
assert.strictEqual(isCompletePdf('/private/export.pdf', fsImpl), true);
});
await test('renders, terminates its private browser, and removes temporary state', async () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'plan-canvas-pdf-test-'));
let spawned = null;