Media: Account for Windows when normalizing file paths.

Previously, Windows paths in the `path_is_absolute` function resulted in incorrect URIs. This patch adjusts for forward slashes and adds tests for the `get_attached_file` function.
Props Whissi, SergeyBiryukov, desrosj, stevenlinx, birgire, davidbaumwald, costdev, peterwilsoncc, audrasjb, hellofromTonya, johnbillion.
Fixes #36308.



git-svn-id: https://develop.svn.wordpress.org/trunk@53934 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Anthony Burchell 2022-08-23 19:57:17 +00:00
parent edd85686c4
commit b351a2f058
4 changed files with 87 additions and 2 deletions

View File

@ -2083,6 +2083,7 @@ function wp_mkdir_p( $target ) {
* For example, '/foo/bar', or 'c:\windows'.
*
* @since 2.5.0
* @since 6.1.0 Allows normalized Windows paths (forward slashes).
*
* @param string $path File path.
* @return bool True if path is absolute, false is not absolute.
@ -2113,6 +2114,11 @@ function path_is_absolute( $path ) {
return true;
}
// Normalized Windows paths for local filesystem and network shares (forward slashes).
if ( preg_match( '#(^[a-zA-Z]+:/|^//[\w!@\#\$%\^\(\)\-\'{}\.~]{1,15})#', $path ) ) {
return true;
}
// A path starting with / or \ is absolute; anything else is relative.
return ( '/' === $path[0] || '\\' === $path[0] );
}

View File

@ -724,10 +724,11 @@ function get_attached_file( $attachment_id, $unfiltered = false ) {
$file = get_post_meta( $attachment_id, '_wp_attached_file', true );
// If the file is relative, prepend upload dir.
if ( $file && 0 !== strpos( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) {
if ( $file ) {
$uploads = wp_get_upload_dir();
if ( false === $uploads['error'] ) {
$file = $uploads['basedir'] . "/$file";
$file = path_join( $uploads['basedir'], $file );
}
}

View File

@ -105,6 +105,13 @@ class Tests_Functions extends WP_UnitTestCase {
'C:\\',
'C:\\WINDOWS',
'\\\\sambashare\\foo',
'c:/',
'c://',
'//',
'c:/FOO',
'//FOO',
'C:/WWW/Sites/demo/htdocs/wordpress/wp-content/uploads/2016/03/example.jpg',
'//ComputerName/ShareName/SubfolderName/example.txt',
);
foreach ( $absolute_paths as $path ) {
$this->assertTrue( path_is_absolute( $path ), "path_is_absolute('$path') should return true" );
@ -119,10 +126,14 @@ class Tests_Functions extends WP_UnitTestCase {
'../foo',
'../',
'../foo.bar',
'foo.bar',
'foo/bar',
'foo',
'FOO',
'..\\WINDOWS',
'..//WINDOWS',
'c:',
'C:',
);
foreach ( $relative_paths as $path ) {
$this->assertFalse( path_is_absolute( $path ), "path_is_absolute('$path') should return false" );

View File

@ -0,0 +1,67 @@
<?php
/**
* @group post
* @covers ::get_attached_file
*/
class Tests_Post_GetAttachedFile extends WP_UnitTestCase {
/**
* Post
*
* @var WP_Post
*/
protected static $post;
/**
* Create shared fixtures.
*/
public static function set_up_before_class() {
self::$post = self::factory()->post->create_and_get(
array(
'post_title' => 'example-page',
'post_type' => 'post',
)
);
}
/**
* @ticket 36308
*
* @dataProvider data_get_attached_file_with_windows_paths
*
* @param string $file The file path to attach to the post.
* @param string $expected The expected attached file path.
* @param string $message The message when an assertion fails.
*/
public function test_get_attached_file_with_windows_paths( $file, $expected, $message ) {
$attachment = self::factory()->attachment->create_and_get(
array(
'post_parent' => self::$post->ID,
'file' => $file,
)
);
$this->assertSame( $expected, get_attached_file( $attachment->ID ), $message );
}
/**
* Data provider with Windows paths.
*
* @return array
*/
public function data_get_attached_file_with_windows_paths() {
return array(
'a local path' => array(
'file' => 'C:/WWW/Sites/demo/htdocs/wordpress/wp-content/uploads/2016/03/example.jpg',
'expected' => 'C:/WWW/Sites/demo/htdocs/wordpress/wp-content/uploads/2016/03/example.jpg',
'message' => 'Windows local filesystem paths should be equal',
),
'a network share path' => array(
'file' => '//ComputerName/ShareName/SubfolderName/example.txt',
'expected' => '//ComputerName/ShareName/SubfolderName/example.txt',
'message' => 'Network share paths should be equal',
),
);
}
}