{"record":{"id":"6795d8c181e80a15","repo":"parallax/jsPDF","slug":"invalid-gif-87a-89a-header","errorCode":null,"errorMessage":"Invalid GIF 87a/89a header.","messagePattern":"Invalid GIF 87a/89a header\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/libs/omggif.js","lineNumber":432,"sourceCode":"    buf[cur_subblock] = p - cur_subblock - 1;\n    buf[p++] = 0;\n  }\n  return p;\n}\n\nfunction GifReader(buf) {\n  var p = 0;\n\n  // - Header (GIF87a or GIF89a).\n  if (\n    buf[p++] !== 0x47 ||\n    buf[p++] !== 0x49 ||\n    buf[p++] !== 0x46 ||\n    buf[p++] !== 0x38 ||\n    ((buf[p++] + 1) & 0xfd) !== 0x38 ||\n    buf[p++] !== 0x61\n  ) {\n    throw new Error(\"Invalid GIF 87a/89a header.\");\n  }\n\n  // - Logical Screen Descriptor.\n  var width = buf[p++] | (buf[p++] << 8);\n  var height = buf[p++] | (buf[p++] << 8);\n  var pf0 = buf[p++]; // <Packed Fields>.\n  var global_palette_flag = pf0 >> 7;\n  var num_global_colors_pow2 = pf0 & 0x7;\n  var num_global_colors = 1 << (num_global_colors_pow2 + 1);\n  var background = buf[p++];\n  buf[p++]; // Pixel aspect ratio (unused?).\n\n  var global_palette_offset = null;\n  var global_palette_size = null;\n\n  if (global_palette_flag) {\n    global_palette_offset = p;\n    global_palette_size = num_global_colors;","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/libs/omggif.js#L414-L450","documentation":"Thrown by the GifReader constructor when the first six bytes do not match the ASCII header 'GIF87a' or 'GIF89a'. The check decodes bytes and verifies the 'GIF8' prefix plus a 7/9 (via (b+1)&0xfd === 0x38) and trailing 'a'. Any non-GIF or truncated buffer fails here.","triggerScenarios":"Passing a PNG/JPEG/WebP/BMP buffer to GifReader; passing a buffer shorter than 6 bytes; corrupted/truncated download; base64 string instead of bytes.","commonSituations":"Generic image pipeline misrouting non-GIF data to the GIF decoder; serving a file with the wrong MIME/extension; incomplete fetch returning partial bytes.","solutions":["Sniff the magic bytes (0x47 0x49 0x46 'GIF') before constructing GifReader.","Route by actual format (use the matching decoder for PNG/JPEG/etc.).","Ensure you pass a complete Uint8Array/ArrayBuffer, not a base64 string."],"exampleFix":"// before\nvar reader = new GifReader(buffer);\n// after\nif (buffer.length >= 6 && buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {\n  var reader = new GifReader(buffer);\n}","handlingStrategy":"type-guard","validationCode":"function isGif(buf){ return buf && buf.length >= 6 && buf[0]===0x47 && buf[1]===0x49 && buf[2]===0x46 && buf[3]===0x38; }\nif (isGif(buffer)) new GifReader(buffer);","typeGuard":"function isGifBuffer(buf){ return buf instanceof Uint8Array && buf.length >= 6 && buf[0]===0x47 && buf[1]===0x49 && buf[2]===0x46; }","tryCatchPattern":"try { var r = new GifReader(buffer); } catch (e) { if (/Invalid GIF/.test(e.message)) { /* route to correct decoder */ } else throw e; }","preventionTips":["Sniff GIF magic bytes before decoding","Validate buffer length >= 6"],"tags":["gif","omggif","image","file-format","validation","magic-bytes"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}