{"record":{"id":"b176f2a0ca387290","repo":"parallax/jsPDF","slug":"image-dimensions-exceed-512mb-which-is-too-large-b176f2","errorCode":null,"errorMessage":"Image dimensions exceed 512MB, which is too large.","messagePattern":"Image dimensions exceed 512MB, which is too large\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/libs/omggif.js","lineNumber":615,"sourceCode":"    return frames.length;\n  };\n\n  this.loopCount = function() {\n    return loop_count;\n  };\n\n  this.frameInfo = function(frame_num) {\n    if (frame_num < 0 || frame_num >= frames.length)\n      throw new Error(\"Frame index out of range.\");\n    return frames[frame_num];\n  };\n\n  this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {\n    var frame = this.frameInfo(frame_num);\n    var num_pixels = frame.width * frame.height;\n\n    if (num_pixels > 512 * 1024 * 1024) {\n      throw new Error(\"Image dimensions exceed 512MB, which is too large.\");\n    }\n\n    var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.\n    GifReaderLZWOutputIndexStream(\n      buf,\n      frame.data_offset,\n      index_stream,\n      num_pixels\n    );\n    var palette_offset = frame.palette_offset;\n\n    // NOTE(deanm): It seems to be much faster to compare index to 256 than\n    // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in\n    // the profile, not sure if it's related to using a Uint8Array.\n    var trans = frame.transparent_index;\n    if (trans === null) trans = 256;\n\n    // We are possibly just blitting to a portion of the entire frame.","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/parallax/jsPDF/blob/a3930ce03a585a26b2c76d12a0f413ce96f6d1a3/src/libs/omggif.js#L597-L633","documentation":"Thrown in decodeAndBlitFrameBGRA when frame.width * frame.height exceeds 512*1024*1024 pixels. It prevents allocating a Uint8Array of index data that would exhaust memory. This is a defensive ceiling on a single GIF frame's pixel count before the LZW decode and blit.","triggerScenarios":"Decoding a GIF frame whose stored width*height product is enormous (e.g. a crafted 'decompression bomb' GIF with a huge logical frame, or a legitimately very large image). The check fires before allocation so no huge buffer is created.","commonSituations":"Processing untrusted user-uploaded GIFs that may be maliciously oversized; embedding a high-resolution GIF into a PDF; a corrupt dimension field inflating the computed pixel count.","solutions":["Pre-check reader.width/height and the frame's width/height (via frameInfo) and reject or downscale before decoding.","Sanitize/re-encode oversized GIFs with an image tool before passing to jsPDF.","Validate uploaded GIFs against a max pixel budget at the application boundary."],"exampleFix":"// before\nreader.decodeAndBlitFrameBGRA(0, pixels);\n\n// after\nvar info = reader.frameInfo(0);\nvar px = info.width * info.height;\nif (px > 256 * 1024 * 1024) {\n  throw new Error('GIF frame too large to embed safely: ' + px + ' pixels');\n}\nreader.decodeAndBlitFrameBGRA(0, pixels);","handlingStrategy":"validation","validationCode":"var MAX_PIXELS = 256 * 1024 * 1024; // stay under jsPDF's 512M ceiling\nvar info = reader.frameInfo(0);\nif (info.width * info.height > MAX_PIXELS) {\n  throw new Error('Frame too large: ' + info.width + 'x' + info.height);\n}\nreader.decodeAndBlitFrameBGRA(0, pixels);","typeGuard":"function frameWithinBudget(reader, idx, maxPixels) {\n  var i = reader.frameInfo(idx);\n  return (i.width * i.height) <= maxPixels;\n}","tryCatchPattern":"try {\n  reader.decodeAndBlitFrameBGRA(0, pixels);\n} catch (e) {\n  if (/exceed 512MB/.test(e.message)) {\n    return downscaleOrReject(e);\n  }\n  throw e;\n}","preventionTips":["Cap accepted GIF pixel dimensions at your application boundary.","Downscale very large GIFs before embedding in a PDF.","Treat a frame near the 512M-pixel ceiling as a possible decompression bomb."],"tags":["gif","memory","bounds-check","omggif"],"backgroundTag":null,"analyzedSha":"a3930ce03a585a26b2c76d12a0f413ce96f6d1a3","analyzedAt":"2026-08-13T05:33:39.648Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}