Add dimension validation to sideload endpoint#74903
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Flaky tests detected in 8b8aa9a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24863531627
|
1fb78d7 to
89e2a02
Compare
Validates uploaded image dimensions against expected size constraints in the wp/v2/media/<id>/sideload endpoint. This prevents users from uploading incorrectly-sized images for a specified image size. Validation rules: - 'original' size: must match original attachment dimensions exactly - 'full' and 'scaled' sizes: requires positive dimensions only - Regular sizes: dimensions must not exceed registered size maximums (with 1px tolerance for rounding differences) Also updates existing tests to use appropriately-sized images and adds two new test cases for dimension validation. Co-Authored-By: Claude Opus 4.6 <[email protected]>
a537683 to
beff757
Compare
Links Gutenberg PR #74903 (dimension validation for sideload endpoint) to its corresponding WordPress Core PR. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove the file_exists check from filter_wp_unique_filename so sideloaded sub-sizes can replace existing files. The attachment name check is sufficient to prevent unintended overwrites. Also consolidate the positive-dimension check and fix translators comment argument order.
|
@andrewserong another one to review when you have a chance, no hurry though! |
ramonjd
left a comment
There was a problem hiding this comment.
LGTM. Just left some non blocking questions. This is still an experiment, right?
I uploaded a large image and told the sideload endpoint it was a thumbnail:
curl -u "admin:Ysn5 AMiG 6N2k cEAK guz8 KqoZ" \
-X POST "http://localhost:8888/wp-json/wp/v2/media/243/sideload?image_size=thumbnail" \
-H "Content-Disposition: attachment; filename=196-150x150.jpg" \
-H "Content-Type: image/jpeg" \
--data-binary @./196.jpg
->>>
{"code":"rest_upload_dimension_mismatch","message":"Uploaded image width (3008) exceeds maximum for \"thumbnail\" size (150).","data":{"status":400}}%
On trunk the response was 200.
Also tested happy path:
curl -u "admin:Ysn5 AMiG 6N2k cEAK guz8 KqoZ" \
-X POST "http://localhost:8888/wp-json/wp/v2/media/244/sideload?image_size=thumbnail" \
-H "Content-Disposition: attachment; filename=test-image-1-100x100.jpg-150x150.jpg" \
-H "Content-Type: image/jpeg" \
--data-binary @./test-image-1-100x100.jpg
Address review feedback: return a WP_Error when wp_getimagesize() returns false (corrupted file, unsupported format) instead of silently proceeding with zero dimensions. This also simplifies the downstream code since $size is now guaranteed to be a valid array.
"thumbnail" here might just mean "sub size", let me test with a large image to see if I get the expected -scaled image. |
Layer dimension validation on top of trunk's sub_size_data return pattern: read dimensions once up front, run validate_image_dimensions (now accepting string|array image_size), then build the flat sub-size payload the finalize endpoint expects. Keep PR and trunk test coverage side by side.
Two tests had stale assertions after the switch to 'thumbnail' size (still expecting 'medium'), and two newer trunk tests used canola.jpg (640x480) in their sideload body, which now fails dimension validation against medium (300x300) and thumbnail (150x150). Use test-image.jpg (50x50) to fit within constraints.
opened #78037 which i want to land fist before testing and merging this. |
…ision Reflect four client-side media PRs merged after these docs were last revised, keeping the architecture and how-to guides in sync with current behavior: - #76707: document the disabled libvips operation cache (Cache.max(0)) and the 50-operation worker recycling that bound WASM linear-memory growth, plus the globalThis.__vipsDebug hook for capturing the suppressed vips output. - #74903: document the sideload endpoint's image-dimension validation and its 400 error responses (rest_upload_dimension_mismatch and friends). - #78359: note that the finalize endpoint returns the refreshed attachment, which the editor uses to keep the block URL (and front-end srcset) in sync. - #78038: clarify that sub-size filenames derive from the original basename and only the scaled full-size copy carries the -scaled suffix.


Summary
Adds validation to ensure uploaded image dimensions match expected dimensions for the specified image size in the
wp/v2/media/<id>/sideloadendpoint.Fixes #74360
Problem
Previously, the sideload endpoint accepted any image regardless of its dimensions. A user could upload a 1000x1000 image claiming it's a "thumbnail" (150x150), and the code would accept it without validation.
Solution
Added a
validate_image_dimensions()method that checks uploaded dimensions against expected size constraints:The validation runs after the file is uploaded but before metadata is updated. If validation fails, the uploaded file is cleaned up and a
WP_Erroris returned.Test plan
🤖 Generated with Claude Code