Skip to content

RuntimeError: memory access out of bounds on _MagickImageCollection_Coalesce  #173

@geocine

Description

@geocine

magick-wasm version

0.0.30

Description

Running coalesce inside readCollection on a huge GIF causes the native module to throw a memory access out of bounds exception

VM2835:1 Error processing GIF: RuntimeError: memory access out of bounds
    at magick.dfc94ac5f18be68f99c9.wasm:0x8f67
    at magick.dfc94ac5f18be68f99c9.wasm:0x2809f3
    at magick.dfc94ac5f18be68f99c9.wasm:0x80938
    at magick.dfc94ac5f18be68f99c9.wasm:0x151a9d
    at magick.dfc94ac5f18be68f99c9.wasm:0x384918
    at magick.dfc94ac5f18be68f99c9.wasm:0x8e91f3
    at e._MagickImageCollection_Coalesce (magick.js:8:1)
    at magick-image-collection.ts:439:1
    at magick-image-collection.ts:811:1
    at exception.ts:39:1
    at Ge.use (int-pointer.ts:18:1)
    at T.use (exception.ts:38:1)
    at magick-image-collection.ts:809:1
    at Me.attachImages (magick-image-collection.ts:729:1)
    at Me.replaceImages (magick-image-collection.ts:809:1)
    at Me.coalesce (magick-image-collection.ts:439:1)

Steps to Reproduce

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ImageMagick WASM Demo</title>
  </head>
  <body>
    <h1>Upload a GIF File</h1>
    <input type="file" id="fileInput" accept="image/gif" />
    <div id="output"></div>
    <script type="module">
      import { ImageMagick, MagickFormat, initializeImageMagick } from "https://esm.sh/@imagemagick/[email protected]/dist/index.mjs";

      // Initialize
      async function start() {
        try {
          const wasmUrl = "https://esm.sh/@imagemagick/[email protected]/dist/magick.wasm";
          const wasmBinary = await fetch(wasmUrl).then(response => response.arrayBuffer());
          
          await initializeImageMagick(wasmBinary);

          const fileInput = document.getElementById('fileInput');
          fileInput.addEventListener('change', async (event) => {
            const file = event.target.files[0];
            if (file) {
              const arrayBuffer = await file.arrayBuffer();
              const uint8Array = new Uint8Array(arrayBuffer);

              // Wait for the ImageMagick WASM module to initialize
              ImageMagick.readCollection(uint8Array, MagickFormat.Gif, (images) => {
                images.coalesce(); // Process images with coalesce
              });
            }
          });
        } catch (error) {
          console.error("Failed to initialize ImageMagick:", error);
        }
      }

      start();
    </script>
  </body>
</html>

Images

https://drive.google.com/file/d/1jeToienatAO07jRmZYpLMlK0MJgBFUcx/view?usp=sharing

This is a zipped file with the GIF image used.

Format                                   : GIF
Format/Info                              : Graphics Interchange Format
File size                                : 90.7 MiB

Image
Format                                   : GIF
Format/Info                              : Graphics Interchange Format
Format profile                           : 89a
Width                                    : 1 331 pixels
Height                                   : 1 331 pixels
Compression mode                         : Lossless

The GIF has 201 frames as read by ImageMagick.readCollection

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions