From f50b974f2a5448c21c0f2be0a6f70c7c94f3f959 Mon Sep 17 00:00:00 2001 From: LI-Jialu <55438527+LI-Jialu@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:01:25 +0800 Subject: [PATCH 1/2] fix(read): reject fractional PDF page ranges --- packages/core/src/tools/read-handler.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/src/tools/read-handler.ts b/packages/core/src/tools/read-handler.ts index 3771a7e0..1e2ba939 100644 --- a/packages/core/src/tools/read-handler.ts +++ b/packages/core/src/tools/read-handler.ts @@ -552,11 +552,13 @@ function parsePositiveInt(value: string, label: string): number { if (!Number.isFinite(numeric)) { throw new Error(`${label} must be a number.`); } - const integer = Math.trunc(numeric); - if (integer < 1) { + if (!Number.isInteger(numeric)) { + throw new Error(`${label} must be an integer.`); + } + if (numeric < 1) { throw new Error(`${label} must be >= 1.`); } - return integer; + return numeric; } function readNotebook(filePath: string): string { From e783c1b47b5e7eec161b9368329bf59238498008 Mon Sep 17 00:00:00 2001 From: LI-Jialu <55438527+LI-Jialu@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:04:07 +0800 Subject: [PATCH 2/2] test(read): cover fractional PDF page ranges Add a regression test for rejecting fractional PDF page ranges. --- packages/core/src/tests/tool-handlers.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/core/src/tests/tool-handlers.test.ts b/packages/core/src/tests/tool-handlers.test.ts index 735c0274..a28e81a6 100644 --- a/packages/core/src/tests/tool-handlers.test.ts +++ b/packages/core/src/tests/tool-handlers.test.ts @@ -998,6 +998,22 @@ test("Read returns an acknowledgement for images and attaches the image as a fol ); }); +test("Read rejects fractional PDF page ranges", async () => { + const workspace = createTempWorkspace(); + const filePath = path.join(workspace, "sample.pdf"); + fs.writeFileSync(filePath, makePdfWithPages(4), "utf8"); + + for (const pages of ["1.9", "2.1-3.9"]) { + const readResult = await handleReadTool( + { file_path: filePath, pages }, + createContext("pdf-fractional-pages", workspace) + ); + + assert.equal(readResult.ok, false); + assert.match(readResult.error ?? "", /must be an integer/); + } +}); + function createContext( sessionId: string, projectRoot: string, @@ -1024,6 +1040,11 @@ function createTempWorkspace(): string { return dir; } +function makePdfWithPages(pageCount: number): string { + const pages = Array.from({ length: pageCount }, (_, index) => `${index + 1} 0 obj << /Type /Page >> endobj`); + return ["%PDF-1.4", ...pages, "%%EOF", ""].join("\n"); +} + async function readSnippet( filePath: string, sessionId: string,