Opened 4 weeks ago
Last modified 4 weeks ago
#65873 new defect (bug)
Media: enable HEIC/HEIF sequence uploads when the server lacks image editor support
| Reported by: | adamsilverstein | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Media | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests gutenberg-merge |
| Cc: | Focuses: |
Description
Claude went through the code for this one and drafted the ticket:
Follow up to #64915, which stopped WP_REST_Attachments_Controller::create_item_permissions_check() from rejecting HEIC/HEIF uploads on servers whose image editor can't process them. That change was narrowed during commit to the still formats only, so image/heic-sequence and image/heif-sequence are still rejected with rest_upload_image_type_not_supported.
Those two mime types are what an Apple Live Photo or an Android burst is. The comment in core explains the reasoning:
* The '-sequence' variants (multi-frame Live Photos) are deliberately * excluded: neither the server nor the browser fallback can process * them yet, so they should fall through to the standard unsupported * mime-type error rather than be stored unprocessable.
That was accurate when it was written. The browser half of it has since changed: https://github.com/WordPress/gutenberg/pull/79647 demuxes a sequence and decodes its first frame in the browser, uploading that still in its place, so a capable browser never reaches this check at all.
What does reach it is a browser that can't decode HEVC. Rejecting the upload there is worse than storing it. wp_check_filetype_and_ext() already collapses a sequence to its first frame, so the user still gets a usable photo - just without the motion, which is the same result they'd get uploading the file anywhere else. Today they get an error instead and no photo at all.
Worth noting that core is already set up for these files everywhere else. wp_get_mime_types() registers the heics and heifs extensions, and wp_is_heic_image_mime_type() already returns true for all four mime types. The permissions check is the one place that treats the sequence variants differently.
Proposed change
Replace the hardcoded still-only array with the existing helper, which is what #64915 originally proposed:
if ( $prevent_unsupported_uploads && ! empty( $files['file']['type'] ) && wp_is_heic_image_mime_type( $files['file']['type'] ) ) { $prevent_unsupported_uploads = false; }
Net 7 lines removed.
Testing
- Remove image editor support so the check is reachable:
add_filter( 'wp_image_editors', '__return_empty_array' ); POSTa.heicsfile (or anything sent asimage/heic-sequence) to/wp/v2/media.- Before the change the request fails with
rest_upload_image_type_not_supported. After it, the attachment is created and stores the first frame.
The existing unit test asserting the old behavior (test_upload_heic_sequence_is_not_bypassed) is removed, and the sequence mime types are folded into the data provider for test_upload_heic_bypasses_unsupported_image_type_check so one case covers all four.
PR: https://github.com/WordPress/wordpress-develop/pull/13042
Related Gutenberg work: https://github.com/WordPress/gutenberg/pull/79647
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
## What
Extends the HEIC/HEIF upload bypass added in #64915 to the multi-frame
-sequencevariants:image/heic-sequenceandimage/heif-sequence, which is what Apple Live Photos and Android bursts are.Today those are rejected with
rest_upload_image_type_not_supportedwhen the server's image editor cannot handle them, which is most servers.## Why
The original exclusion was correct when it was written - the comment says the sequence variants are skipped because "neither the server nor the browser fallback can process them yet". The browser half of that has changed: WordPress/gutenberg#79647 demuxes a sequence and decodes its first frame in the browser, uploading that still in its place, so a capable browser never reaches this check at all.
More to the point, rejecting them is inconsistent with what the rest of the pipeline does with the same bytes.
wp_check_filetype_and_ext()renames a.heicsupload to.heicand rewrites its type toimage/heic, verified against a real 120-frame sequence:So a file this permissions check turns away is one the very next step would have relabelled as an ordinary still HEIC - a mime type the same check already allows. The bytes are stored unchanged either way; only the label differs.
## Approach
Uses the existing
wp_is_heic_image_mime_type()helper, which already returns true for all four mime types, in place of the hardcoded still-only array. This is what #64915 originally proposed before it was narrowed. Net 7 lines removed from the source.## Testing instructions
add_filter( 'wp_image_editors', '__return_empty_array' );.heicsfile (or any file sent asimage/heic-sequence) throughPOST /wp/v2/media.rest_upload_image_type_not_supported; after it, the attachment is created.The existing unit test asserting the old behavior is removed, and the sequence mime types are folded into the data provider for the bypass test so one case covers all four:
## AI Use
Claude Code wrote this patch and the description. I will review and test.