Skip to content

Clear image.src on loadImage error to release partial cairo state - #2580

Closed
iurisilvio wants to merge 1 commit into
Automattic:masterfrom
iurisilvio:fix/loadImage-clear-src-on-error
Closed

Clear image.src on loadImage error to release partial cairo state#2580
iurisilvio wants to merge 1 commit into
Automattic:masterfrom
iurisilvio:fix/loadImage-clear-src-on-error

Conversation

@iurisilvio

Copy link
Copy Markdown
Contributor

Fixes #2576.

loadImage() in index.js rejects the Promise on error but doesn't clear image.src. The Image keeps a reference to the input buffer (and, depending on the format, any partial cairo surface) until V8 garbage-collects the Image wrapper. Under sustained load on malformed inputs that fail mid-decode, this delays cleanup arbitrarily.

The fix assigns image.src = Buffer.alloc(0) before rejecting, which triggers Image::SetSource()clearData() synchronously — destroying any partial cairo surface and resetting the buffer reference.

One-line change; the full rationale and a standalone repro are in #2576.

loadImage's onerror handler rejects the Promise but leaves image.src
pointing at the input buffer. When libjpeg/libpng allocated a cairo
surface before failing mid-decode, that surface stays attached to the
Image until V8 GC — under sustained load on malformed inputs this
delays cleanup arbitrarily.

Assign Buffer.alloc(0) before reject so clearData() runs synchronously.
@iurisilvio iurisilvio closed this Jun 25, 2026
iurisilvio added a commit to iurisilvio/node-canvas that referenced this pull request Jun 25, 2026
Trim the fork to only the memory leaks reproduced with before/after RSS:
- JPEG EXIF rotation (rotate90/rotate270) leak (Automattic#2574, merged upstream)
- RsvgHandle / partial cairo surface leak on SVG decode error paths (Automattic#2585)

Revert everything else back to v3.2.3 after testing: image.src-on-error
(Automattic#2580, no measurable effect), libjpeg longjmp data/src free (Automattic#2581, not
reproducible on libjpeg-turbo), cairo_pattern_t refcount (Automattic#2582), CanvasPattern
source-retention UAF guard (Automattic#2583), rare decoder error-path frees (Automattic#2587), and
the node-addon-api 8 / NAPI_EXPERIMENTAL experiment. Built on node-addon-api 7.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loadImage() doesn't clear image.src on error, delaying cleanup of partial cairo state

1 participant