Opened 22 months ago
#60349 new defect (bug)
Rest API media upload utf8 urlencoded filename not decoded on server
| Reported by: |
|
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.