{"record":{"id":"d844029a250a025c","repo":"tonhowtf/omniget","slug":"png-com-tamanho-de-chunk-inv-lido","errorCode":null,"errorMessage":"PNG com tamanho de chunk inválido","messagePattern":"PNG com tamanho de chunk inválido","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/exif.rs","lineNumber":246,"sourceCode":"        }\n        i = end;\n    }\n    Ok(out)\n}\n\nconst PNG_DROP: &[&[u8; 4]] = &[b\"tEXt\", b\"zTXt\", b\"iTXt\", b\"eXIf\", b\"tIME\", b\"dSIG\"];\n\nfn strip_png(data: &[u8]) -> anyhow::Result<Vec<u8>> {\n    let mut out = Vec::with_capacity(data.len());\n    out.extend_from_slice(&data[0..8]);\n    let mut i = 8usize;\n    while i + 8 <= data.len() {\n        let len = u32::from_be_bytes([data[i], data[i + 1], data[i + 2], data[i + 3]]) as usize;\n        let ctype: [u8; 4] = [data[i + 4], data[i + 5], data[i + 6], data[i + 7]];\n        let end = i\n            .checked_add(12)\n            .and_then(|v| v.checked_add(len))\n            .ok_or_else(|| anyhow!(\"PNG com tamanho de chunk inválido\"))?;\n        if end > data.len() {\n            return Err(anyhow!(\"PNG truncado\"));\n        }\n        if !PNG_DROP.iter().any(|d| d.as_slice() == ctype) {\n            out.extend_from_slice(&data[i..end]);\n        }\n        i = end;\n        if &ctype == b\"IEND\" {\n            break;\n        }\n    }\n    Ok(out)\n}\n\nfn strip_webp(data: &[u8]) -> anyhow::Result<Vec<u8>> {\n    let mut body: Vec<u8> = Vec::with_capacity(data.len());\n    body.extend_from_slice(b\"WEBP\");\n    let mut i = 12usize;","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/exif.rs#L228-L264","documentation":"strip_png walks PNG chunks after the 8-byte signature, reading each chunk's length (4 bytes BE) and type (4 bytes), where each chunk spans 12 + len bytes total. It uses checked arithmetic and throws this error if the chunk size computation overflows (i + 12 + len exceeds usize).","triggerScenarios":"Calling strip_bytes()/strip_png() on data whose PNG chunk length field is corrupt/huge such that 12 + len overflows usize — i.e. malformed or non-PNG data that happens to be passed to the PNG stripper.","commonSituations":"Processing a corrupted/truncated PNG with garbage length bytes; feeding a JPEG or other file mistakenly identified as PNG; fuzzed or maliciously crafted images where the length field is 0xFFFFFFFF or similar.","solutions":["Validate the file is a real PNG (8-byte signature and sane IHDR) before calling strip_bytes","Treat the input as corrupted and skip metadata stripping for this file","Sanity-check the first chunk length (should be 13 for IHDR) before parsing","Regenerate or re-encode the source image if it is corrupted"],"exampleFix":"// before\nlet cleaned = exif::strip_bytes(&data).unwrap_or(data);\n// after\nlet is_png = data.starts_with(b\"\\x89PNG\\r\\n\\x1a\\n\");\nlet cleaned = if is_png {\n    exif::strip_bytes(&data).unwrap_or_else(|_| data.clone())\n} else { data };","handlingStrategy":"try-catch","validationCode":"fn looks_like_png(data: &[u8]) -> bool {\n    data.len() >= 33 && data.starts_with(b\"\\x89PNG\\r\\n\\x1a\\n\")\n        && u32::from_be_bytes([data[8+8], data[8+9], data[8+10], data[8+11]]) <= data.len() as u32\n}","typeGuard":"fn is_safe_png(data: &[u8]) -> bool {\n    data.starts_with(b\"\\x89PNG\\r\\n\\x1a\\n\") && data.len() >= 8\n}","tryCatchPattern":"let out = match exif::strip_bytes(&data) {\n    Ok(clean) => clean,\n    Err(e) if e.to_string().contains(\"PNG\") => {\n        warn!(\"imagem PNG corrompida, mantendo original: {e}\");\n        data\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Verify the PNG signature before running the metadata stripper","Fall back to the original bytes when stripping fails — stripping is best-effort","Treat untrusted images defensively; corrupted length fields indicate malformed input"],"tags":["png","image","malformed-input","metadata"],"backgroundTag":"unexpected-response-shape","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}