Skip to content

Instantly share code, notes, and snippets.

@ryan-williams
Last active February 27, 2026 15:09
Show Gist options
  • Select an option

  • Save ryan-williams/51fa8e1e56008da63b436cedb60e51ea to your computer and use it in GitHub Desktop.

Select an option

Save ryan-williams/51fa8e1e56008da63b436cedb60e51ea to your computer and use it in GitHub Desktop.

ImageMagick/ImageMagick#8582 SIGABRT (double-free) converting SVG with gradientTransform on <linearGradient>

Description

magick crashes with a double-free (SIGABRT, exit code 134) when converting any SVG containing a gradientTransform attribute on a <linearGradient> element. Removing the attribute makes conversion succeed. ImageMagick 6 is not affected.

Error output

free(): double free detected in tcache 2
Aborted (core dumped)

Minimal reproducer SVG

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
  <defs>
    <linearGradient id="g" gradientTransform="matrix(1 0 0 1 0 0)" gradientUnits="userSpaceOnUse">
      <stop offset="0" style="stop-color:red"/>
      <stop offset="1" style="stop-color:blue"/>
    </linearGradient>
  </defs>
  <rect fill="url(#g)" width="512" height="512"/>
</svg>

Removing gradientTransform="matrix(1 0 0 1 0 0)" (even though it's an identity matrix) makes the conversion succeed.

Steps to reproduce

# Save the SVG above as crash.svg, then:
magick crash.svg crash.png
# → exit code 134 (SIGABRT)

CI repro

Full automated repro with GitHub Actions: https://github.com/ryan-williams/imagemagick-svg-crash

GHA run showing the crash: https://github.com/ryan-williams/imagemagick-svg-crash/actions/runs/22469220910

Versions tested

Version Result
ImageMagick 7.1.2-16 (Beta), Ubuntu x86_64 (source build) crashes (double-free)
ImageMagick 7.1.2-15, macOS arm64 (Homebrew) crashes
ImageMagick 6.9.12-98, Ubuntu x86_64 (apt) works fine
librsvg 2.58.0 (rsvg-convert) works fine

Root cause

Introduced in 9db96365e (2026-02-15, tag 7.1.2-14) — the security fix for GHSA-xpg8-7m6m-jf56. That commit changed value in SVGStartElement's attribute loop from a non-owned const char * alias to a heap-allocated char * via SVGEscapeString(), with DestroyString(value) added at the end of each iteration. The gradientTransform and transform inner token-parsing loops have reassigned value to tokens[j+1] since 2009 (3ed852eea); previously harmless, this now leaks the original allocation and double-frees the token.

Fix: #8583

System info

Tested on macOS arm64 (Homebrew) and Ubuntu x86_64 (GHA). Both crash with IM7; IM6 works fine on both.


This issue was generated with the help of Claude Code (claude-opus-4-6).

Try installing InkscapeSent from my iPhoneOn Feb 26, 2026, at 6:30 PM, Ryan Williams @.***> wrote:ryan-williams created an issue (ImageMagick/ImageMagick#8582) Description magick crashes with a double-free (SIGABRT, exit code 134) when converting any SVG containing a gradientTransform attribute on a element. Removing the attribute makes conversion succeed. ImageMagick 6 is not affected. Error output free(): double free detected in tcache 2 Aborted (core dumped)

Minimal reproducer SVG Removing gradientTransform="matrix(1 0 0 1 0 0)" (even though it's an identity matrix) makes the conversion succeed. Steps to reproduce

Save the SVG above as crash.svg, then:

magick crash.svg crash.png

→ exit code 134 (SIGABRT)

CI repro Full automated repro with GitHub Actions: https://github.com/ryan-williams/imagemagick-svg-crash GHA run showing the crash: https://github.com/ryan-williams/imagemagick-svg-crash/actions/runs/22469220910 Versions tested

Version Result

ImageMagick 7.1.2-16 (Beta), Ubuntu x86_64 (source build) crashes (double-free)

ImageMagick 7.1.2-15, macOS arm64 (Homebrew) crashes

ImageMagick 6.9.12-98, Ubuntu x86_64 (apt) works fine

librsvg 2.58.0 (rsvg-convert) works fine

System info Tested on macOS arm64 (Homebrew) and Ubuntu x86_64 (GHA). Both crash with IM7; IM6 works fine on both.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

Root cause

Introduced in 9db96365e (2026-02-15, tag 7.1.2-14) — the security fix for GHSA-xpg8-7m6m-jf56.

That commit changed value in SVGStartElement's attribute loop from a const char * alias (pointing directly into attributes[i+1], never freed) to a heap-allocated char * via SVGEscapeString(), with DestroyString(value) added at the end of each iteration.

The gradientTransform and transform inner token-parsing loops have had value=(char *) tokens[j+1] since the SVG coder was first written (2009, 3ed852eea). Before 9db96365e, that was harmless — value wasn't owned memory. After, reassigning value inside the inner loop:

  1. Leaks the original SVGEscapeString() allocation (pointer is clobbered)
  2. Double-frees tokens[j+1] (freed once by the token cleanup loop, then again by DestroyString(value))

Fix in #8583: use a separate token_value local in each inner loop.

(Also added to the issue description above.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment