Changeset 56186
- Timestamp:
- 07/10/2023 08:31:35 PM (15 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/file.php
r56174 r56186 690 690 $temp_filename .= '-' . wp_generate_password( 6, false ); 691 691 $temp_filename .= '.tmp'; 692 $temp_filename = $dir . wp_unique_filename( $dir, $temp_filename ); 692 $temp_filename = wp_unique_filename( $dir, $temp_filename ); 693 694 /* 695 * Filesystems typically have a limit of 255 characters for a filename. 696 * 697 * If the generated unique filename exceeds this, truncate the initial 698 * filename and try again. 699 * 700 * As it's possible that the truncated filename may exist, producing a 701 * suffix of "-1" or "-10" which could exceed the limit again, truncate 702 * it to 252 instead. 703 */ 704 $characters_over_limit = strlen( $temp_filename ) - 252; 705 if ( $characters_over_limit > 0 ) { 706 $filename = substr( $filename, 0, -$characters_over_limit ); 707 return wp_tempnam( $filename, $dir ); 708 } 709 710 $temp_filename = $dir . $temp_filename; 693 711 694 712 $fp = @fopen( $temp_filename, 'x' ); -
trunk/tests/phpunit/tests/file.php
r55060 r56186 207 207 208 208 /** 209 * Tests that `wp_tempnam()` limits the filename's length to 252 characters. 210 * 211 * @ticket 35755 212 * 213 * @covers ::wp_tempnam 214 * 215 * @dataProvider data_wp_tempnam_should_limit_filename_length_to_252_characters 216 */ 217 public function test_wp_tempnam_should_limit_filename_length_to_252_characters( $filename ) { 218 $file = wp_tempnam( $filename ); 219 220 if ( file_exists( $file ) ) { 221 self::unlink( $file ); 222 } 223 224 $this->assertLessThanOrEqual( 252, strlen( basename( $file ) ) ); 225 } 226 227 /** 228 * Data provider. 229 * 230 * @return array[] 231 */ 232 public function data_wp_tempnam_should_limit_filename_length_to_252_characters() { 233 return array( 234 'the limit before adding characters for uniqueness' => array( 'filename' => str_pad( '', 241, 'filename' ) ), 235 'one more than the limit before adding characters for uniqueness' => array( 'filename' => str_pad( '', 242, 'filename' ) ), 236 '251 characters' => array( 'filename' => str_pad( '', 251, 'filename' ) ), 237 '252 characters' => array( 'filename' => str_pad( '', 252, 'filename' ) ), 238 '253 characters' => array( 'filename' => str_pad( '', 253, 'filename' ) ), 239 ); 240 } 241 242 /** 243 * Tests that `wp_tempnam()` limits the filename's length to 252 characters 244 * when there is a name conflict. 245 * 246 * @ticket 35755 247 * 248 * @covers ::wp_tempnam 249 */ 250 public function test_wp_tempnam_should_limit_filename_length_to_252_characters_with_name_conflict() { 251 // Create a conflict by removing the randomness of the generated password. 252 add_filter( 253 'random_password', 254 static function() { 255 return '123456'; 256 }, 257 10, 258 0 259 ); 260 261 // A filename at the limit. 262 $filename = str_pad( '', 252, 'filename' ); 263 264 // Create the initial file. 265 $existing_file = wp_tempnam( $filename ); 266 267 // Try creating a file with the same name. 268 $actual = wp_tempnam( basename( $existing_file ) ); 269 270 self::unlink( $existing_file ); 271 self::unlink( $actual ); 272 273 $this->assertLessThanOrEqual( 252, strlen( basename( $actual ) ) ); 274 } 275 276 /** 277 * Tests that `wp_tempnam()` limits the filename's length to 252 characters 278 * when a 'random_password' filter returns passwords longer than 6 characters. 279 * 280 * @ticket 35755 281 * 282 * @covers ::wp_tempnam 283 */ 284 public function test_wp_tempnam_should_limit_filename_length_to_252_characters_when_random_password_is_filtered() { 285 // Force random passwords to 12 characters. 286 add_filter( 287 'random_password', 288 static function() { 289 return '1a2b3c4d5e6f'; 290 }, 291 10, 292 0 293 ); 294 295 // A filename at the limit. 296 $filename = str_pad( '', 252, 'filename' ); 297 $actual = wp_tempnam( $filename ); 298 299 self::unlink( $actual ); 300 301 $this->assertLessThanOrEqual( 252, strlen( basename( $actual ) ) ); 302 } 303 304 /** 305 * Tests that `wp_tempnam()` limits the filename's length to 252 characters 306 * when a 'wp_unique_filename' filter returns a filename longer than 252 characters. 307 * 308 * @ticket 35755 309 * 310 * @covers ::wp_tempnam 311 */ 312 public function test_wp_tempnam_should_limit_filename_length_to_252_characters_when_wp_unique_filename_is_filtered() { 313 // Determine the number of additional characters added by `wp_tempnam()`. 314 $temp_dir = get_temp_dir(); 315 $additional_chars_filename = wp_unique_filename( $temp_dir, 'filename' ); 316 $additional_chars_generated = wp_tempnam( $additional_chars_filename, $temp_dir ); 317 $additional_chars_difference = strlen( basename( $additional_chars_generated ) ) - strlen( $additional_chars_filename ); 318 319 $filenames_over_limit = 0; 320 321 // Make the filter send the filename over the limit. 322 add_filter( 323 'wp_unique_filename', 324 static function( $filename ) use ( &$filenames_over_limit ) { 325 if ( strlen( $filename ) === 252 ) { 326 $filename .= '1'; 327 ++$filenames_over_limit; 328 } 329 330 return $filename; 331 }, 332 10, 333 1 334 ); 335 336 // A filename that will hit the limit when `wp_tempnam()` adds characters. 337 $filename = str_pad( '', 252 - $additional_chars_difference, 'filename' ); 338 $actual = wp_tempnam( $filename ); 339 340 self::unlink( $additional_chars_generated ); 341 self::unlink( $actual ); 342 343 $this->assertLessThanOrEqual( 252, strlen( basename( $actual ) ), 'The final filename was over the limit.' ); 344 $this->assertSame( 1, $filenames_over_limit, 'One filename should have been over the limit.' ); 345 } 346 347 /** 348 * Tests that `wp_tempnam()` limits the filename's length to 252 characters 349 * when both a 'random_password' filter and a 'wp_unique_filename' filter 350 * cause the filename to be greater than 252 characters. 351 * 352 * @ticket 35755 353 * 354 * @covers ::wp_tempnam 355 */ 356 public function test_wp_tempnam_should_limit_filename_length_to_252_characters_when_random_password_and_wp_unique_filename_are_filtered() { 357 // Force random passwords to 12 characters. 358 add_filter( 359 'random_password', 360 static function() { 361 return '1a2b3c4d5e6f'; 362 }, 363 10, 364 0 365 ); 366 367 // Determine the number of additional characters added by `wp_tempnam()`. 368 $temp_dir = get_temp_dir(); 369 $additional_chars_filename = wp_unique_filename( $temp_dir, 'filename' ); 370 $additional_chars_generated = wp_tempnam( $additional_chars_filename, $temp_dir ); 371 $additional_chars_difference = strlen( basename( $additional_chars_generated ) ) - strlen( $additional_chars_filename ); 372 373 $filenames_over_limit = 0; 374 375 // Make the filter send the filename over the limit. 376 add_filter( 377 'wp_unique_filename', 378 static function( $filename ) use ( &$filenames_over_limit ) { 379 if ( strlen( $filename ) === 252 ) { 380 $filename .= '1'; 381 ++$filenames_over_limit; 382 } 383 384 return $filename; 385 }, 386 10, 387 1 388 ); 389 390 // A filename that will hit the limit when `wp_tempnam()` adds characters. 391 $filename = str_pad( '', 252 - $additional_chars_difference, 'filename' ); 392 $actual = wp_tempnam( $filename ); 393 394 self::unlink( $additional_chars_generated ); 395 self::unlink( $actual ); 396 397 $this->assertLessThanOrEqual( 252, strlen( basename( $actual ) ), 'The final filename was over the limit.' ); 398 $this->assertSame( 1, $filenames_over_limit, 'One filename should have been over the limit.' ); 399 } 400 401 /** 209 402 * @ticket 47186 210 403 */
Note: See TracChangeset
for help on using the changeset viewer.