Skip to content

Commit 80d5d6a

Browse files
committed
fix: reject fractional PDF page selections
1 parent 7cfc66a commit 80d5d6a

3 files changed

Lines changed: 31 additions & 0 deletions

File tree

src/agents/tools/pdf-tool.helpers.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ describe("parsePageRange", () => {
7474
expect(() => parsePageRange("abc", 20)).toThrow("Invalid page number");
7575
});
7676

77+
it("throws on fractional page number", () => {
78+
expect(() => parsePageRange("1.5", 20)).toThrow('Invalid page number: "1.5"');
79+
});
80+
81+
it("throws when any comma-separated page number is fractional", () => {
82+
expect(() => parsePageRange("1,1.5", 20)).toThrow('Invalid page number: "1.5"');
83+
});
84+
7785
it("throws on invalid range (start > end)", () => {
7886
expect(() => parsePageRange("5-3", 20)).toThrow("Invalid page range");
7987
});

src/agents/tools/pdf-tool.helpers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export function parsePageRange(range: string, maxPages: number): number[] {
6565
pages.add(i);
6666
}
6767
} else {
68+
if (!/^\d+$/.test(part)) {
69+
throw new Error(`Invalid page number: "${part}"`);
70+
}
6871
const num = Number(part);
6972
if (!Number.isFinite(num) || num < 1) {
7073
throw new Error(`Invalid page number: "${part}"`);

src/agents/tools/pdf-tool.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,26 @@ describe("createPdfTool", () => {
568568
});
569569
});
570570

571+
it("rejects fractional pages before native PDF analysis", async () => {
572+
await withTempPdfAgentDir(async (agentDir) => {
573+
await stubPdfToolInfra(agentDir, { provider: "anthropic", input: ["text", "document"] });
574+
const nativeSpy = vi
575+
.spyOn(pdfNativeProviders, "anthropicAnalyzePdf")
576+
.mockResolvedValue("native summary");
577+
const cfg = withPdfModel(ANTHROPIC_PDF_MODEL);
578+
const tool = requirePdfTool((await loadCreatePdfTool())({ config: cfg, agentDir }));
579+
580+
await expect(
581+
tool.execute("t1", {
582+
prompt: "summarize",
583+
pdf: "/tmp/doc.pdf",
584+
pages: "1.5",
585+
}),
586+
).rejects.toThrow('Invalid page number: "1.5"');
587+
expect(nativeSpy).not.toHaveBeenCalled();
588+
});
589+
});
590+
571591
it("rejects password parameter for native PDF providers", async () => {
572592
await withTempPdfAgentDir(async (agentDir) => {
573593
await stubPdfToolInfra(agentDir, { provider: "anthropic", input: ["text", "document"] });

0 commit comments

Comments
 (0)