Skip to content

Commit c99298e

Browse files
authored
Fix attachment filename generation for URLs with query parameters (#2499)
1 parent b2495e1 commit c99298e

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fixed
3+
4+
Fix "Filename too long" errors when downloading attachments from URLs with query parameters (e.g., Instagram CDN URLs).

includes/class-attachments.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ private static function save_attachment( $attachment_data, $post_id, $author_id
446446

447447
// Prepare file array for WordPress.
448448
$file_array = array(
449-
'name' => \basename( $attachment_data['url'] ),
449+
'name' => \basename( \wp_parse_url( $attachment_data['url'], PHP_URL_PATH ) ),
450450
'tmp_name' => $tmp_file,
451451
);
452452

@@ -514,7 +514,8 @@ private static function save_file( $attachment_data, $object_id, $object_type )
514514
\wp_mkdir_p( $paths['basedir'] );
515515

516516
// Generate unique file name.
517-
$file_name = \sanitize_file_name( \basename( $attachment_data['url'] ) );
517+
$url_path = \wp_parse_url( $attachment_data['url'], PHP_URL_PATH );
518+
$file_name = \sanitize_file_name( \basename( $url_path ) );
518519
$file_path = $paths['basedir'] . '/' . $file_name;
519520

520521
// Initialize filesystem if needed.

tests/phpunit/tests/includes/class-test-attachments.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,4 +614,71 @@ public function test_inline_images_with_invalid_urls() {
614614
// Clean up.
615615
\wp_delete_post( $post_id, true );
616616
}
617+
618+
/**
619+
* Test that query parameters are stripped from attachment filenames.
620+
*
621+
* This prevents "Filename too long" errors when downloading from CDN URLs
622+
* (like Instagram) that include long query strings.
623+
*
624+
* @covers ::save_attachment
625+
*/
626+
public function test_attachment_filename_strips_query_parameters() {
627+
// Instagram-style URL with very long query parameters.
628+
$attachments = array(
629+
array(
630+
'url' => 'https://example.com/image.jpg?stp=dst-jpg_e35&nc_cat=101&ccb7-5&_nc_sid=18de74&nc_ohc=example&nc_oc=example',
631+
'mediaType' => 'image/jpeg',
632+
'name' => 'Test Image',
633+
'type' => 'Image',
634+
),
635+
);
636+
637+
$result = Attachments::import( $attachments, self::$post_id, self::$author_id );
638+
639+
$this->assertIsArray( $result );
640+
$this->assertCount( 1, $result );
641+
$this->assertIsInt( $result[0] );
642+
643+
// Verify the attachment filename is clean without query parameters.
644+
$attachment_file = get_attached_file( $result[0] );
645+
$this->assertStringEndsWith( '.jpg', $attachment_file );
646+
$this->assertStringNotContainsString( '?', $attachment_file );
647+
$this->assertStringNotContainsString( 'stp=', $attachment_file );
648+
$this->assertStringNotContainsString( 'nc_cat=', $attachment_file );
649+
}
650+
651+
/**
652+
* Test that query parameters are stripped from direct file storage filenames.
653+
*
654+
* @covers ::save_file
655+
*/
656+
public function test_file_storage_filename_strips_query_parameters() {
657+
// Create a test post.
658+
$post_id = self::factory()->post->create(
659+
array(
660+
'post_type' => 'ap_post',
661+
)
662+
);
663+
664+
// URL with query parameters.
665+
$attachments = array(
666+
array(
667+
'url' => 'https://example.com/photo.png?size=large&quality=high&cache=12345',
668+
'mediaType' => 'image/png',
669+
'name' => 'Test Photo',
670+
'type' => 'Image',
671+
),
672+
);
673+
674+
$result = Attachments::import_post_files( $attachments, $post_id );
675+
676+
$this->assertIsArray( $result );
677+
$this->assertCount( 1, $result );
678+
679+
// Verify the URL doesn't contain query parameters.
680+
$this->assertStringEndsWith( '.png', $result[0]['url'] );
681+
$this->assertStringNotContainsString( '?', $result[0]['url'] );
682+
$this->assertStringNotContainsString( 'size=', $result[0]['url'] );
683+
}
617684
}

0 commit comments

Comments
 (0)