Skip to content

fix(deps): drop the image-size resolution that broke metro asset sizing - #35

Open
sapta100ms wants to merge 2 commits into
mainfrom
fix/dependabot-113-114-image-size
Open

fix(deps): drop the image-size resolution that broke metro asset sizing#35
sapta100ms wants to merge 2 commits into
mainfrom
fix/dependabot-113-114-image-size

Conversation

@sapta100ms

@sapta100ms sapta100ms commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

About Dependabot alerts #113 and #114 (image-size, both high).

Headline

Neither alert can be fixed by any version bump. They are being dismissed separately. What this PR fixes is a different, real bug: the pin that was protecting against an older advisory has been silently breaking metro's image asset sizing.

Why no bump can fix #113 / #114

Advisory Range Patched
#113 GHSA-w3rx-r6r6-pgpr — ICNS parser infinite loop <= 2.0.2 none
#114 GHSA-5p2g-fcmc-qvqq — JXL/HEIF parser infinite loops <= 2.0.2 none

2.0.2 is the latest published release (latest dist-tag) and sits inside both ranges. There is nothing to upgrade to.

How the pin got there — it was correct when it was made

Date Event
2025-04-02 GHSA-m5qc-5hw7-8vg7 published: >= 1.1.0, < 1.2.1 → 1.2.1 and >= 2.0.0, < 2.0.2 → 2.0.2. Alert #14 opens the same day.
2025-05-15 Commit c5e89ea "update image-size version" adds "image-size": "2.0.2" to resolutions (which previously held only @types/react).
2025-12-02 Merged as #11 "Image size upgrade" — "as suggested by github 'dependabot' for a vulnerability existing in image-size below version 1.1.1". Alert #14 closes.
2026-06-10 GHSA-w3rx-r6r6-pgpr and GHSA-5p2g-fcmc-qvqq published, both <= 2.0.2, no fix. The pin now protects nothing.
2026-08-20 #33 correctly notes no patched version exists and leaves the pin alone.

At the time it was added, 2.0.2 genuinely was a patched version for the advisory being chased. The pin did its job and alert #14 closed.

The subtle part: that same advisory was also patched at 1.2.1 on the 1.x line — and 1.2.1 is what metro asks for. Pinning 1.2.1 would have closed #14 and stayed inside metro's major. Pinning 2.0.2 closed #14 but crossed it.

What crossing the major broke

image-size v2 is ESM-first. require() returns an object with a named imageSize export instead of a callable, and file-path input moved to a separate ./fromFile entry. But metro/src/Assets.js:6 does:

const getImageSize = require("image-size");

and calls it at :31 and :140. Reproduced against the installed copy:

typeof require('image-size'): object
keys: [ 'default', 'disableTypes', 'imageSize', 'types' ]
is callable: false

metro-style call -> TypeError: getImageSize is not a function

Any bundle containing a PNG or JPEG asset fails. After this change the identical call returns 512x86. This went unnoticed for roughly fifteen months.

Why dropping to 1.2.1 loses no security

There are exactly three image-size advisories. The only one with a fix is GHSA-m5qc-5hw7-8vg7 — alert #14, already closed — and its 1.x patch line is 1.2.1 precisely:

GHSA-m5qc-5hw7-8vg7:  >= 1.1.0, < 1.2.1 -> 1.2.1  ;  >= 2.0.0, < 2.0.2 -> 2.0.2

We land exactly on 1.2.1, so nothing reopens. #113 and #114 affect 1.2.1 and 2.0.2 identically.

Changes

  1. Remove "image-size": "2.0.2" from resolutions — metro resolves its intended ^1.0.2 → 1.2.1 and the callable export returns.
  2. Add a //image-size note beside the existing //resolutions note, recording why this must stay unpinned so the next alert sweep does not reintroduce a 2.x pin.

On dismissing #113 / #114

Being dismissed separately. For the record, the rationale:

  • image-size is reached only through metro — bundle/build time, never in the shipped app
  • inputs are the repo's own asset files, author-controlled, not untrusted user uploads
  • the vulnerable parsers are ICNS, JXL and HEIF; React Native assets are PNG/JPEG and metro never feeds it those formats

Revisit if upstream ships a fix metro's major can consume.

Verification

  • yarn install --immutable succeeds
  • yarn typecheck passes
  • yarn test passes
  • yarn prepack (bob build) succeeds across commonjs, module, typescript
  • Only image-size@1.2.1 resolves on disk
  • metro's exact call pattern verified working (was throwing before)

Branched off main at 1bda5f2.

This repo has no .github/ directory, so no CI validates the PR — the above was run locally.

🤖 Generated with Claude Code

sapta100ms and others added 2 commits September 4, 2026 12:48
The resolutions block pinned image-size to 2.0.2, crossing the major
boundary of metro's own requirement (^1.0.2). That pin achieved nothing
and broke image asset bundling.

It achieved nothing because both open advisories cover every published
version with no fix available:

  #113 GHSA-w3rx-r6r6-pgpr  high  <= 2.0.2  -> NONE  ICNS parser infinite loop
  #114 GHSA-5p2g-fcmc-qvqq  high  <= 2.0.2  -> NONE  JXL/HEIF parser infinite loops

2.0.2 sits inside both ranges, so forcing it left the repo exactly as
exposed as before.

It broke bundling because image-size v2 is ESM-first: require() returns
an object with a named `imageSize` export rather than a callable
function, and file-path input moved to a separate ./fromFile entry.
metro/src/Assets.js:6 does `const getImageSize = require("image-size")`
and calls it at :31 and :140, which raises

  TypeError: getImageSize is not a function

on any bundle containing a PNG or JPEG asset. Reproduced directly
against the installed copy; with 1.2.1 the same call returns 512x86.

Removing the resolution restores 1.2.1, metro's intended major. This is
security-neutral: of the three image-size advisories, the only one with
a fix (GHSA-m5qc-5hw7-8vg7, this repo's already-closed #14) is patched
in 1.2.1 for the 1.x line, and the other two affect 1.2.1 and 2.0.2
alike. Nothing reopens.

#113 and #114 cannot be closed by any version bump and need a risk
decision instead -- see the PR description.

Verified: yarn install --immutable, typecheck, jest and prepack (bob
build, all three targets) pass, and only image-size 1.2.1 resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a //image-size note beside the existing //resolutions note, so the
2.x pin is not reintroduced by a future alert sweep. Explains that metro
needs v1's callable require() export, that 1.2.1 patches the same
advisory the old pin targeted, and that the two remaining advisories
have no patched release at all.

Co-Authored-By: Claude Opus 5 (1M context) <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.

1 participant