#65670 closed defect (bug) (fixed)
WP_REST_Attachments_Controller::get_attachment_filesize() fatals on non-integer filesize metadata
| Reported by: | apermo | Owned by: | westonruter |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.1 |
| Component: | REST API | Version: | 7.0 |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description (last modified by )
Serving an attachment via the REST API can throw a fatal error:
TypeError: WP_REST_Attachments_Controller::get_attachment_filesize(): Return value must be of type ?int, string returned .../class-wp-rest-attachments-controller.php:2373 (get_attachment_filesize) .../class-wp-rest-attachments-controller.php:1431 (prepare_item_for_response) .../class-wp-rest-posts-controller.php:669 (get_item)
get_attachment_filesize() (introduced in 7.0.0) returns the stored filesize value from attachment metadata verbatim:
$meta = wp_get_attachment_metadata( $attachment_id ); if ( isset( $meta['filesize'] ) ) { return $meta['filesize']; }
Attachment metadata is untyped postmeta, so filesize is not guaranteed to be an integer. The file does not declare strict_types, so a numeric string is coerced and survives — but a non-numeric string violates the method's ?int return type and throws a fatal TypeError.
Real-world trigger: plugins populate filesize from remote storage API responses. For example, WP Media Folder (JoomUnited) stores the Google Drive fileSize field, which the Drive API returns as a string; Dropbox and OneDrive addons do the same from their API payloads.
The filesize REST schema declares 'type' => 'integer', so the intent is clearly an integer. Core should normalize the untyped meta value rather than fatal.
Steps to reproduce:
- Create an attachment.
- Store non-numeric metadata:
wp_update_attachment_metadata( $id, array( 'filesize' => 'corrupt' ) ); GET /wp/v2/media/<id>-> fatal TypeError.
Proposed fix: only return the stored value when numeric (cast to int), otherwise fall through to recompute the size from the file via wp_filesize(). Patch + PHPUnit coverage attached (GitHub PR).
Change History (9)
This ticket was mentioned in PR #12611 on WordPress/wordpress-develop by @apermo.
3 weeks ago
#1
- Keywords has-patch has-unit-tests added
@apermo commented on PR #12611:
3 weeks ago
#2
@westonruter would you be able to review this? It fixes a fatal TypeError in get_attachment_filesize() (new in 7.0.0) when filesize attachment metadata is stored as a non-numeric string — which happens on sites using plugins that populate it from remote storage APIs (e.g. the Google Drive fileSize string via WP Media Folder). Trac: https://core.trac.wordpress.org/ticket/65670
@apermo commented on PR #12611:
3 weeks ago
#3
@westonruter Would you be so kind to have a look at it? Thanks :)
#6
follow-up:
↓ 8
@
3 weeks ago
- Description modified (diff)
@apermo Aside: please ensure ticket descriptions get submitted in Trac WikiFormatting instead of Markdown.
#8
in reply to: ↑ 6
@
3 weeks ago
Replying to westonruter:
@apermo Aside: please ensure ticket descriptions get submitted in Trac WikiFormatting instead of Markdown.
My bad, missed out on that one, will pay closer attention next time. Thank you for the quick and great work :)
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
## Trac ticket
https://core.trac.wordpress.org/ticket/65670
## Problem
WP_REST_Attachments_Controller::get_attachment_filesize()(new in 7.0.0) returns thefilesizevalue from attachment metadata verbatim against a strict?intreturn type. Attachment metadata is untyped postmeta, so a non-numeric string value throws a fatalTypeErrorwhen the media endpoint is requested:A numeric string only survives because the file has no
strict_typesdeclaration (coercion). A non-numeric one fatals.Plugins populate
filesizefrom remote storage API responses — e.g. the Google DrivefileSizefield (returned as a string) via WP Media Folder, and the equivalent Dropbox/OneDrive addons — so this occurs on real sites.## Fix
Only return the stored value when it is numeric, cast to
int; otherwise fall through to recompute the size from the file viawp_filesize()(which always casts to int), returningnullif unavailable. This matches the'type' => 'integer'REST schema.## Testing
Two regression tests added to
tests/phpunit/tests/rest-api/rest-attachments-controller.php:filesizemeta → normalized tointin the response;filesizemeta → no fatal, falls back to the real file size.The non-numeric test reproduces the reported
TypeErroragainst unpatchedtrunk(red), and passes with the fix (green).## Disclosure
Claude (Anthropic) assisted in diagnosing the root cause and drafting the patch and tests. I reviewed the change, verified the red/green test behavior locally, and take responsibility for it.