{"record":{"id":"332a13fe5983aba6","repo":"tonhowtf/omniget","slug":"n-o-achei-a-assinatura-pdf-o-arquivo-n-o-parece-um-pdf","errorCode":null,"errorMessage":"não achei a assinatura %PDF- — o arquivo não parece um PDF","messagePattern":"não achei a assinatura %PDF- — o arquivo não parece um PDF","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf_repair.rs","lineNumber":346,"sourceCode":"    for i in 0..n.min(header.len() / 2) {\n        let num = header[i * 2] as u32;\n        let start = first + header[i * 2 + 1];\n        let stop = if i + 1 < n.min(header.len() / 2) {\n            first + header[i * 2 + 3]\n        } else {\n            decoded.len()\n        };\n        if start <= stop && stop <= decoded.len() {\n            out.push((num, decoded[start..stop].to_vec()));\n        }\n    }\n    out\n}\n\n/// Reescreve o arquivo com uma xref nova no fim. Devolve `(bytes, objetos)`.\npub fn rebuild_xref(data: &[u8]) -> anyhow::Result<(Vec<u8>, usize)> {\n    let head = find_first(data, b\"%PDF-\")\n        .ok_or_else(|| anyhow!(\"não achei a assinatura %PDF- — o arquivo não parece um PDF\"))?;\n    // Lixo antes do cabeçalho desloca todos os offsets: corta fora.\n    let body = &data[head..];\n    let objects = scan_objects(body);\n    if objects.is_empty() {\n        return Err(anyhow!(\n            \"nenhum objeto encontrado — arquivo vazio ou cifrado\"\n        ));\n    }\n\n    let mut out = body.to_vec();\n    if !out.ends_with(b\"\\n\") {\n        out.push(b'\\n');\n    }\n    let mut by_num: std::collections::BTreeMap<u32, (usize, u16)> =\n        objects.iter().map(|(n, o, g)| (*n, (*o, *g))).collect();\n\n    // PDF 1.5+ comprime objeto dentro de objeto. Reescreve cada um solto no\n    // fim do arquivo — é o que deixa a xref plana voltar a fazer sentido.","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf_repair.rs#L328-L364","documentation":"`rebuild_xref` requires the input bytes to contain a `%PDF-` signature, located with `find_first`. If the marker is absent anywhere in the file, it refuses to proceed because it cannot determine where the PDF body starts. The error says the file does not look like a PDF at all.","triggerScenarios":"Passing an empty file, a text/HTML error page saved as .pdf, an encrypted/proprietary container, or a truncated download that lost the header to `rebuild_xref` (or to `run`, which calls it).","commonSituations":"Downloads that returned an HTML login/error page with a .pdf filename; files uploaded over FTP in ASCII mode corrupting the header; users renaming unrelated files to .pdf; attempting repair on an empty 0-byte file.","solutions":["Open the file in a hex/text viewer and confirm it starts with `%PDF-`; if not, the repair path cannot help","Re-download or re-export the file from its original source","Strip email/mime wrappers if the file is an embedded attachment (the PDF may be base64 inside)","Check file size — a 0-byte or few-hundred-byte 'PDF' is almost certainly not one"],"exampleFix":"// before\nlet data = std::fs::read(\"broken.pdf\")?;\nlet (bytes, objs) = rebuild_xref(&data)?;\n// after\nlet data = std::fs::read(\"broken.pdf\")?;\nif !data.windows(5).any(|w| w == b\"%PDF-\") {\n    eprintln!(\"not a PDF — aborting repair\");\n    return Ok(());\n}\nlet (bytes, objs) = rebuild_xref(&data)?;","handlingStrategy":"validation","validationCode":"fn looks_like_pdf(data: &[u8]) -> bool {\n    data.windows(5).any(|w| w == b\"%PDF-\")\n}\n// usage: if !looks_like_pdf(&data) { reject the file before calling rebuild_xref }","typeGuard":"fn is_pdf(data: &[u8]) -> bool {\n    data.len() > 100 && data.windows(1024.min(data.len())).any(|w| w.starts_with(b\"%PDF-\"))\n}","tryCatchPattern":"match rebuild_xref(&data) {\n    Err(e) if e.to_string().contains(\"%PDF-\") => {\n        eprintln!(\"input is not a PDF; re-download or convert the file first\");\n    }\n    other => other?,\n}","preventionTips":["Check the first KB of any file for the %PDF- marker before attempting repair","Reject 0-byte files and files whose size matches an HTML error page","Re-download suspicious files in binary mode","Validate the user-supplied path before reading and repairing"],"tags":["pdf","validation","file-format","rust"],"backgroundTag":"invalid-argument-format","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}