This was closed as a duplicate in March 2026 and no bound was ever added. Re-checked against 18.7.0 and master ({{952e591eb3d}}):
* {{git log --grep=XWIKI-24117}} over {{xwiki-platform}} returns *no commit*. * {{grep -rniE 'maxPixel|maxWidth|maxHeight|MAX_IMAGE|getMaximum|semaphore|Executors|permits'}} over all of {{xwiki-platform-image/}} (tests excluded) returns *zero* hits. {{ImageIO.setUseCache}} / {{deregisterServiceProvider}} / {{ImageReadParam}} / {{setSourceSubsampling}} return zero hits across {{xwiki-platform-core}} + {{xwiki-commons}}. * The ??resize pool?? discussed in the only comment on this ticket does not exist in the tree.
The reason to reopen the question is that the same stack is reachable *deliberately*, at a cost the reporter's scenario does not suggest.
{{ImagePlugin.shrinkImage()}} calls {{imageProcessor.readImage(stream)}} before it computes the target dimensions ([ImagePlugin.java#L314-L326|https://github.com/xwiki/xwiki-platform/blob/master/xwiki-platform-core/xwiki-platform-image/xwiki-platform-image-processing/xwiki-platform-image-processing-plugin/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java#L314-L326]), so {{?width=}} never bounds the allocation, and {{ThumbnailatorImageProcessor.readImage()}} then forces a full-size {{TYPE_INT_ARGB}} copy ({{w*h*4}}) via {{.imageType(ThumbnailParameter.DEFAULT_IMAGE_TYPE)}} regardless of the source's bit depth ([ThumbnailatorImageProcessor.java#L53-L66|https://github.com/xwiki/xwiki-platform/blob/master/xwiki-platform-core/xwiki-platform-image/xwiki-platform-image-processing/xwiki-platform-image-processing-api/src/main/java/com/xpn/xwiki/internal/plugin/image/ThumbnailatorImageProcessor.java#L53-L66]). A 1-bit greyscale PNG is therefore amplified 32x on top of its compression ratio.
Measured on 18.7.0 (Tomcat, {{-Xmx4096m}}), single sequential *unauthenticated* requests:
This ticket's scenario needed *320 x 11.9 MB = ~3.8 GB* of uploads to reach OOM. The crafted equivalent needs *7,852 bytes*, uploaded once with EDIT right, and every detonation afterwards is a ~120-byte unauthenticated GET. Because {{width}} is part of the thumbnail cache key ({{ImagePlugin.java:286}}) and the shipped capacity is 30, varying {{?width=}} makes every request a fresh full decode.
Two consequences for this ticket's framing:
# The concurrency reading is right but the volume is not a defence. 17 parallel requests for that one 7,852-byte attachment demand 4 GiB — the reference Docker image's whole heap. Tomcat's default {{maxThreads}} is 200. # {{downloadAttachment}} catches {{Exception}} ({{ImagePlugin.java:223}}), not {{Error}}, so the resulting {{OutOfMemoryError}} is not swallowed.
Not executed, established from the format and the arithmetic: a 32768x32768 1-bit greyscale PNG is *130,555 bytes* and demands *exactly 4.00 GiB*, i.e. a single-request OOM against the reference deployment.
The ARGB multiplier is recent — it was introduced by {{c9263100a26}} (XWIKI-23514, 2025-09-16, first released *17.9.0*); before that {{readImage}} preserved the source's own image type via {{getBestImageTypeFor()}}. The decode-before-bound ordering itself predates the 2011 repository reorganisation.
A separate security ticket is being filed for the deliberate case ({{PR:L}} upload / unauthenticated detonation, CVSS 4.0 7.1). This comment is only to record that XWIKI-24117 was closed as a *duplicate* rather than fixed, that no allocation or pixel bound exists anywhere in the module today, and that the duplicate target (a resize pool) was never implemented.
h3. Credit Assisted-by: Claude Supervised-by: Clément Christiaens ([https://github.com/ciaens])
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.