fix(image-node): upgrade to jimp v1 to clear unpatchable file-type advisory - #189
fix(image-node): upgrade to jimp v1 to clear unpatchable file-type advisory#189jnbn wants to merge 2 commits into
Conversation
@vibrant/image-node depends on @jimp/* 0.22, which pins file-type ^16.5.4. The 16.x line is affected by GHSA-5v7r-6r5c-r473 (infinite loop in the ASF parser on malformed input) and never received a patch, so every consumer of node-vibrant reports a moderate advisory that cannot be resolved from the outside: overriding file-type to a patched release breaks jimp, because 21.x is ESM-only and renamed fromBuffer to fileTypeFromBuffer. jimp 1.6.1 already depends on file-type ^21.3.3, which is past the fixes for both GHSA-5v7r-6r5c-r473 and GHSA-j47w-4g3g-c36v, so moving the image backend forward resolves it at the source. Three API differences are handled: - @jimp/custom's configure() is gone; jimp 1.x ships a preconfigured Jimp. - Jimp.read no longer takes a Buffer; buffers go through Jimp.fromBuffer. This also removes the type assertion the old code needed. - resize() takes an options object rather than positional arguments. ImageBase.scaleDown passes fractional dimensions, which jimp 0.x rounded internally. That rounding is now explicit at the call site so the resized bitmap is byte-for-byte what it was before. Output is unchanged. Verified against a corpus of 202 real images (a mix of JPEG and PNG, 1184 swatches across all six palette entries) comparing the palettes produced before and after: 1184 of 1184 identical, including population counts.
|
Jimp must continue to use the custom adapter: https://jimp-dev.github.io/jimp/guides/custom-jimp/ To avoid bundle size increases |
Importing the `jimp` bundle pulled in every plugin, of which this package calls only resize, and pushed all of them onto its dependents. Composed with createJimp instead, which is the v1 equivalent of the configure() call this package used before, with the five decoders that @jimp/types used to provide.
|
Good catch, thank you. Fixed in bdc8e53. The adapter is composed with const Jimp = createJimp({
formats: [bmp, msBmp, gif, jpeg, png, tiff],
plugins: [resize.methods],
});The six formats are what One small thing worth flagging for review: the instance type is now taken from the loaders rather than written as
|
|
@crutchcorn Any possibility of getting this out anytime soon now that the custom adapter is back? Not trying to nag open source volunteers, just curious if it's planned for anytime soon. |
Problem
@vibrant/image-nodedepends on@jimp/*0.22, which pinsfile-type@^16.5.4. The 16.x line is affected by GHSA-5v7r-6r5c-r473 (infinite loop in the ASF parser on malformed input,>=13.0.0 <21.3.1) and never received a backport, so the 16.x branch has no patched release.That means every project depending on
node-vibrantreports a moderate advisory:Critically, downstream users cannot resolve this themselves. The obvious fix, an npm
overrideforcing a patchedfile-type, breaks jimp outright:file-type21.x is ESM-only and renamedfromBuffertofileTypeFromBuffer, while jimp 0.22 calls the CJSfromBuffer. The result is a runtime failure on every image:So the only version that clears the advisory is the one jimp cannot use, and the fix has to happen here.
Solution
Move the image backend to
jimp@^1.6.1, which already depends onfile-type@^21.3.3— past the fixes for both GHSA-5v7r-6r5c-r473 and GHSA-j47w-4g3g-c36v. This also collapses three dependencies (@jimp/custom,@jimp/plugin-resize,@jimp/types) into one.Three API differences are handled:
@jimp/custom'sconfigure()no longer exists; jimp 1.x ships a preconfiguredJimpwith resize included.Jimp.readno longer accepts aBuffer; buffers go throughJimp.fromBuffer. This also removes the type assertion the old code needed to work around the missing overload.resize()takes an options object rather than positional arguments.One behavioural detail worth calling out:
ImageBase.scaleDownpasses fractional dimensions, which jimp 0.x rounded internally. jimp 1.x rounds identically, but the rounding is now explicit at the call site so the resized bitmap is provably unchanged rather than relying on an implementation detail.Verification
Output is byte-for-byte identical. I compared palettes produced before and after the change across a corpus of 202 real images (mixed JPEG and PNG), covering all six palette entries:
Also run against the built artifact rather than just source, to confirm the packaged output behaves the same.
Package checks pass locally:
pnpm run test:types:ts56— cleanpnpm run test:eslint— cleanpnpm run build— cleanpnpm run test:build(publint) — only the pre-existingpkg.repository.urlsuggestion, unrelated to this changeNote:
pnpm run buildat the workspace root fails for me before reaching any@vibrant/*package, invibrant-fixture-sample:build(exit 130). That looks environmental rather than related to this change, so I built and checked@vibrant/image-nodeand its dependency directly.Notes
NodeImagekeeps the same shape and behaviour.@jimp/*to 0.22 for the same reason.