{"record":{"id":"1b9e9c657490d951","repo":"toeverything/AFFiNE","slug":"image-pixel-count-exceeds-limit","errorCode":null,"errorMessage":"image pixel count exceeds limit","messagePattern":"image pixel count exceeds limit","errorType":"validation","errorClass":"napi::Error","httpStatus":null,"severity":"error","filePath":"packages/backend/native/src/image.rs","lineNumber":96,"sourceCode":"}\n\nfn read_dimensions(input: &[u8], format: ImageFormat) -> AnyResult<(u32, u32)> {\n  ImageReader::with_format(Cursor::new(input), format)\n    .into_dimensions()\n    .context(\"failed to decode image\")\n}\n\nfn validate_dimensions(width: u32, height: u32) -> AnyResult<()> {\n  if width == 0 || height == 0 {\n    bail!(\"failed to decode image\");\n  }\n\n  if width > MAX_IMAGE_DIMENSION || height > MAX_IMAGE_DIMENSION {\n    bail!(\"image dimensions exceed limit\");\n  }\n\n  if u64::from(width) * u64::from(height) > MAX_IMAGE_PIXELS {\n    bail!(\"image pixel count exceeds limit\");\n  }\n\n  Ok(())\n}\n\nfn decode_image(input: &[u8], format: ImageFormat) -> AnyResult<DynamicImage> {\n  Ok(match format {\n    ImageFormat::Gif => {\n      let decoder = GifDecoder::new(Cursor::new(input)).context(\"failed to decode image\")?;\n      let frame = decoder\n        .into_frames()\n        .next()\n        .transpose()\n        .context(\"failed to decode image\")?\n        .context(\"image does not contain any frames\")?;\n      DynamicImage::ImageRgba8(frame.into_buffer())\n    }\n    ImageFormat::Png => {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/native/src/image.rs#L78-L114","documentation":"An image-decode safety guard in validate_dimensions: after the width/height are non-zero and within MAX_IMAGE_DIMENSION, this fires when width * height (computed in u64 to avoid overflow) exceeds MAX_IMAGE_PIXELS. It protects the decoder from decompression-bomb images whose individual dimensions are legal but whose total pixel count would exhaust memory; the faulting input is the oversized image buffer passed to process_image_inner.","triggerScenarios":"Raised in validate_dimensions when width multiplied by height exceeds MAX_IMAGE_PIXELS, guarding against decompression bombs.","commonSituations":"The image's total pixel count is above the safety cap even though each dimension may look acceptable. Reduce resolution before upload.","solutions":["Resize the image to reduce total pixel count.","Process the image in tiles if supported."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}