• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

umputun / remark42 / 26198482866
84%
master: 85%

Build:
Build:
LAST BUILD BRANCH: refs/tags/backend/v1.16.0
DEFAULT BRANCH: master
Ran 21 May 2026 12:43AM UTC
Jobs 1
Files 51
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

21 May 2026 12:42AM UTC coverage: 84.266%. First build
26198482866

Pull #2064

github

paskal
fix(image): reject decompression-bomb dimensions before raster decode

readAndValidateImage caps the byte size of incoming images but the resize()
helper that follows still called image.Decode unconditionally, allocating
pixel memory proportional to the *declared* image dimensions. A ~100 KB
compressed PNG or GIF that declares 65535x65535 px forces image.Decode to
allocate ~17 GB of raster, OOMing the service on a single comment upload
(or on the proxy's CacheExternal path when caching a malicious upstream).

Hardening:

- maxImagePixels = 16 MP constant. Covers any realistic image (~4096x4096)
  while bounding peak allocation.
- resize() now runs image.DecodeConfig first (cheap, no pixel allocation)
  to read declared width/height before any full decode.
- Multiplication of width × height uses int64 to defeat 32-bit overflow
  (GOARCH=386, 32-bit arm): on those targets, int(cfg.Width)*int(cfg.Height)
  could wrap below maxImagePixels and bypass the cap. GIF's 16-bit logical
  screen and JPEG's 16-bit SOF dimensions both reach this if int-multiplied.
- Bytes exceeding the cap, or non-image input that fails DecodeConfig,
  return nil. prepareImage propagates the rejection as a clear error
  instead of storing the malformed/oversized data verbatim.
- The no-resize-needed path returns the validated original bytes verbatim
  so animated GIFs round-trip without being flattened to a single frame.

The DecodeConfig precheck applies even when MaxWidth/MaxHeight are 0
(resize disabled) — the dimension cap is unconditional defense-in-depth.

Two adjacent fixes surfaced by the new resize contract:

1. readAndValidateImage previously did `data[:512]` without a bounds check,
   panicking on any body shorter than 512 bytes. Now bounded with min().
2. image/webp was listed as an allowed format but no WebP decoder was
   registered, so DecodeConfig would refuse legitimate WebP uploads. Added
   `_ "golang.org/x/image/webp"` (already in go.mod via x/image/draw) so
   ... (continued)
Pull Request #2064: fix(image): reject decompression-bomb dimensions before raster decode

23 of 27 new or added lines in 1 file covered. (85.19%)

6277 of 7449 relevant lines covered (84.27%)

34.29 hits per line

Uncovered Changes

Lines Coverage ∆ File
4
84.35
backend/app/store/image/image.go
Jobs
ID Job ID Ran Files Coverage
1 26198482866.1 21 May 2026 12:43AM UTC 51
84.27
GitHub Action Run
Source Files on build 26198482866
  • Tree
  • List 51
  • Changed 0
  • Source Changed 0
  • Coverage Changed 0
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Pull Request #2064
  • Next Build on fix-image-decompression-bomb (#26199712850)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc