mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(api): reject non-PDF inputs in pdf-to-image
acceptedInputs is [.pdf], but pdf-to-image validated by calling mupdf.openDocument(buf, 'application/pdf'); mupdf sniffs the real format and opens JPEGs/PNGs/etc. as 1-page image-documents, returning 200. So non-PDF (incl. truncated/hostile) inputs were accepted, violating the contract and the hostile-input robustness check -- the one pre-existing failure surfaced by the full integration run. Gate all three endpoints (convert/info/preview) on the %PDF- magic bytes. Verified: truncated.jpg -> 400, valid PDF -> 200; the hostile-inputs test passes.
This commit is contained in:
@@ -171,6 +171,13 @@ async function readPdfFromParts(
|
||||
return { fileBuffer, settingsRaw };
|
||||
}
|
||||
|
||||
// PDFs begin with "%PDF-" within the first bytes. mupdf.openDocument sniffs the
|
||||
// real format and would otherwise accept non-PDF inputs (images, etc.),
|
||||
// violating the .pdf-only contract; gate on the magic bytes up front.
|
||||
function isPdfBuffer(buf: Buffer): boolean {
|
||||
return buf.subarray(0, 1024).includes("%PDF-");
|
||||
}
|
||||
|
||||
// ── Route registration ───────────────────────────────────────────
|
||||
export function registerPdfToImage(app: FastifyInstance) {
|
||||
// ── Info endpoint ────────────────────────────────────────────
|
||||
@@ -190,6 +197,10 @@ export function registerPdfToImage(app: FastifyInstance) {
|
||||
return reply.status(400).send({ error: "No PDF file provided" });
|
||||
}
|
||||
|
||||
if (!isPdfBuffer(fileBuffer)) {
|
||||
return reply.status(400).send({ error: "Invalid or corrupt PDF file" });
|
||||
}
|
||||
|
||||
let doc: mupdf.Document | null = null;
|
||||
try {
|
||||
doc = mupdf.Document.openDocument(fileBuffer, "application/pdf");
|
||||
@@ -228,6 +239,10 @@ export function registerPdfToImage(app: FastifyInstance) {
|
||||
return reply.status(400).send({ error: "No PDF file provided" });
|
||||
}
|
||||
|
||||
if (!isPdfBuffer(fileBuffer)) {
|
||||
return reply.status(400).send({ error: "Invalid or corrupt PDF file" });
|
||||
}
|
||||
|
||||
let doc: mupdf.Document | null = null;
|
||||
try {
|
||||
doc = mupdf.Document.openDocument(fileBuffer, "application/pdf");
|
||||
@@ -292,6 +307,10 @@ export function registerPdfToImage(app: FastifyInstance) {
|
||||
return reply.status(400).send({ error: "No PDF file provided" });
|
||||
}
|
||||
|
||||
if (!isPdfBuffer(fileBuffer)) {
|
||||
return reply.status(400).send({ error: "Invalid or corrupt PDF file" });
|
||||
}
|
||||
|
||||
let settings: z.infer<typeof settingsSchema>;
|
||||
try {
|
||||
const parsed = settingsRaw ? JSON.parse(settingsRaw) : {};
|
||||
|
||||
Reference in New Issue
Block a user