Opened 8 months ago
#60349 new defect (bug)
Rest API media upload utf8 urlencoded filename not decoded on server
Reported by: | ypjzjn | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.4.2 |
Component: | REST API | Keywords: | has-patch |
Focuses: | Cc: |
Description
Files uploaded with the rest api media endpoint, containing utf8 characters in the filename, does not get urldecoded if the filename is urlencoded.
Example:
Content-Disposition: attachment; filename=\"My-nice-filename.jpg\"
The file is correctly called My-nice-filename.jpg on the server.
Content-Disposition: attachment; filename=\"%D1%82%D0%B0%D1%82%D0%B0%D1%82%D0%B0.jpg\"
File named татата.jpg ends incorrectly up as D182D0B0D182D0B0D182D0B0.jpg on the server.
Under is a POC patch allowing urlencoded filenames to be urldecoded on the server.
Content-Disposition: attachment; filename*=UTF-8''%D1%82%D0%B0%D1%82%D0%B0%D1%82%D0%B0.jpg
The file is correctly named татата.jpg on the server.
A number of http clients, example winhttp, doesn't support utf8 characters in the headers, and the files end up with wrong names on the server.
--- class-wp-rest-attachments-controller.php.orig 2024-01-25 13:43:43.898485027 +0100 +++ class-wp-rest-attachments-controller.php 2024-01-25 13:44:02.206740466 +0100 @@ -1139,16 +1139,26 @@ $attributes[ trim( $key ) ] = trim( $value ); } - if ( empty( $attributes['filename'] ) ) { - continue; - } + if ( ! empty( $attributes['filename'] ) ) { + $filename = trim( $attributes['filename'] ); - $filename = trim( $attributes['filename'] ); + // Unquote quoted filename, but after trimming. + if ( str_starts_with( $filename, '"' ) && str_ends_with( $filename, '"' ) ) { + $filename = substr( $filename, 1, -1 ); + } + } else if ( ! empty( $attributes['filename*'] ) ) { + + if ( str_contains( $attributes['filename*'], '\'\'') ) { + list( $key, $value ) = explode( '\'\'', $attributes['filename*'], 2); + // key is encoding + $filename = trim( urldecode( $value ) ); + } else { + continue; + } + } else { + continue; + } - // Unquote quoted filename, but after trimming. - if ( str_starts_with( $filename, '"' ) && str_ends_with( $filename, '"' ) ) { - $filename = substr( $filename, 1, -1 ); - } } return $filename;
Note: See
TracTickets for help on using
tickets.