Merge pull request #28699 from woocommerce/fix/absolute-download-paths
Prevent local relative downloadable products to be treated as "absolute"
This commit is contained in:
commit
35d4ee4073
|
@ -52,7 +52,15 @@ class WC_Product_Download implements ArrayAccess {
|
|||
*/
|
||||
public function get_type_of_file_path( $file_path = '' ) {
|
||||
$file_path = $file_path ? $file_path : $this->get_file();
|
||||
if ( 0 === strpos( $file_path, 'http' ) || 0 === strpos( $file_path, '//' ) ) {
|
||||
$parsed_url = parse_url( $file_path );
|
||||
if (
|
||||
$parsed_url &&
|
||||
isset( $parsed_url['host'] ) && // Absolute url means that it has a host.
|
||||
( // Theoretically we could permit any scheme (like ftp as well), but that has not been the case before. So we allow none or http(s).
|
||||
! isset( $parsed_url['scheme'] ) ||
|
||||
in_array( $parsed_url['scheme'], array( 'http', 'https' ) )
|
||||
)
|
||||
) {
|
||||
return 'absolute';
|
||||
} elseif ( '[' === substr( $file_path, 0, 1 ) && ']' === substr( $file_path, -1 ) ) {
|
||||
return 'shortcode';
|
||||
|
@ -164,6 +172,11 @@ class WC_Product_Download implements ArrayAccess {
|
|||
* @param string $value File URL/Path.
|
||||
*/
|
||||
public function set_file( $value ) {
|
||||
// A `///` is recognized as an "absolute", but on the filesystem, so it bypasses the mime check in `self::is_allowed_filetype`.
|
||||
// This will strip extra prepending / to the maximum of 2.
|
||||
if ( preg_match( '#^//+(/[^/].+)$#i', $value, $matches ) ) {
|
||||
$value = $matches[1];
|
||||
}
|
||||
switch ( $this->get_type_of_file_path( $value ) ) {
|
||||
case 'absolute':
|
||||
$this->data['file'] = esc_url_raw( $value );
|
||||
|
|
|
@ -50,6 +50,8 @@ class WC_Tests_Product_Download extends WC_Unit_Test_Case {
|
|||
$this->assertEquals( 'absolute', $download->get_type_of_file_path( 'http://example.com/file.jpg' ) );
|
||||
$this->assertEquals( 'absolute', $download->get_type_of_file_path( site_url( '/wp-content/uploads/test.jpg' ) ) );
|
||||
$this->assertEquals( 'relative', $download->get_type_of_file_path( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' ) );
|
||||
$this->assertEquals( 'relative', $download->get_type_of_file_path( '//' . trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' ) );
|
||||
$this->assertEquals( 'relative', $download->get_type_of_file_path( '/////' . trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/assets/images/help.png' ) );
|
||||
$this->assertEquals( 'shortcode', $download->get_type_of_file_path( '[s3 bucket ="" file=""]' ) );
|
||||
}
|
||||
|
||||
|
@ -138,5 +140,22 @@ class WC_Tests_Product_Download extends WC_Unit_Test_Case {
|
|||
|
||||
$download->set_file( trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/woocommerce.php' );
|
||||
$this->assertEquals( false, $download->is_allowed_filetype() );
|
||||
|
||||
// For triple-slash overwriting of "local" to "absolute" - see https://github.com/woocommerce/woocommerce/pull/28699.
|
||||
$download->set_file( '//' . trailingslashit( WP_PLUGIN_DIR ) . 'woocommerce/woocommerce.php' );
|
||||
$this->assertEquals( false, $download->is_allowed_filetype() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if we are trimming prepending slashes which can confuse system and change the file type to a filesystem path.
|
||||
* @see https://github.com/woocommerce/woocommerce/pull/28699
|
||||
*
|
||||
* @since 5.0.1
|
||||
*/
|
||||
public function test_trim_extra_prepending_slashes() {
|
||||
$download = new WC_Product_Download();
|
||||
|
||||
$download->set_file( '////////test/path' );
|
||||
$this->assertEquals( '/test/path', $download->get_file() );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue