parent
d54cd10bb4
commit
bce05c811a
|
@ -269,10 +269,9 @@ class WC_Download_Handler {
|
||||||
str_replace( 'https:', 'http:', site_url( '/', 'http' ) ) => ABSPATH,
|
str_replace( 'https:', 'http:', site_url( '/', 'http' ) ) => ABSPATH,
|
||||||
);
|
);
|
||||||
|
|
||||||
$count = 0;
|
$file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path );
|
||||||
$file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path, $count );
|
|
||||||
$parsed_file_path = wp_parse_url( $file_path );
|
$parsed_file_path = wp_parse_url( $file_path );
|
||||||
$remote_file = null === $count || 0 === $count; // Remote file only if there were no replacements.
|
$remote_file = true;
|
||||||
|
|
||||||
// Paths that begin with '//' are always remote URLs.
|
// Paths that begin with '//' are always remote URLs.
|
||||||
if ( '//' === substr( $file_path, 0, 2 ) ) {
|
if ( '//' === substr( $file_path, 0, 2 ) ) {
|
||||||
|
@ -292,7 +291,7 @@ class WC_Download_Handler {
|
||||||
$file_path = realpath( WP_CONTENT_DIR . substr( $file_path, 11 ) );
|
$file_path = realpath( WP_CONTENT_DIR . substr( $file_path, 11 ) );
|
||||||
|
|
||||||
// Check if we have an absolute path.
|
// Check if we have an absolute path.
|
||||||
} elseif ( ( ! isset( $parsed_file_path['scheme'] ) || ! in_array( $parsed_file_path['scheme'], array( 'http', 'https', 'ftp' ), true ) ) && isset( $parsed_file_path['path'] ) ) {
|
} elseif ( ( ! isset( $parsed_file_path['scheme'] ) || ! in_array( $parsed_file_path['scheme'], array( 'http', 'https', 'ftp' ), true ) ) && isset( $parsed_file_path['path'] ) && file_exists( $parsed_file_path['path'] ) ) {
|
||||||
$remote_file = false;
|
$remote_file = false;
|
||||||
$file_path = $parsed_file_path['path'];
|
$file_path = $parsed_file_path['path'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,16 +95,22 @@ class WC_Product_Download implements ArrayAccess {
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function is_allowed_filetype() {
|
public function is_allowed_filetype() {
|
||||||
$file_path = $this->get_file();
|
$file_path = $this->get_file();
|
||||||
$parsed_file_path = WC_Download_Handler::parse_file_path( $file_path );
|
|
||||||
|
|
||||||
// File types for URL-based files located on the server should get validated.
|
// File types for URL-based files located on the server should get validated.
|
||||||
$is_file_on_server = ! $parsed_file_path['remote_file'];
|
$is_file_on_server = false;
|
||||||
|
if ( false !== stripos( $file_path, network_site_url( '/', 'https' ) ) ||
|
||||||
|
false !== stripos( $file_path, network_site_url( '/', 'http' ) ) ||
|
||||||
|
false !== stripos( $file_path, site_url( '/', 'https' ) ) ||
|
||||||
|
false !== stripos( $file_path, site_url( '/', 'http' ) )
|
||||||
|
) {
|
||||||
|
$is_file_on_server = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! $is_file_on_server && 'relative' !== $this->get_type_of_file_path() ) {
|
if ( ! $is_file_on_server && 'relative' !== $this->get_type_of_file_path() ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ( ! $is_file_on_server && ! $this->get_file_extension() ) || in_array( $this->get_file_type(), $this->get_allowed_mime_types(), true );
|
return ! $this->get_file_extension() || in_array( $this->get_file_type(), $this->get_allowed_mime_types(), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,10 +177,6 @@ class WC_Product_Download implements ArrayAccess {
|
||||||
if ( preg_match( '#^//+(/[^/].+)$#i', $value, $matches ) ) {
|
if ( preg_match( '#^//+(/[^/].+)$#i', $value, $matches ) ) {
|
||||||
$value = $matches[1];
|
$value = $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
$parsed_file_path = WC_Download_Handler::parse_file_path( $value );
|
|
||||||
$value = $parsed_file_path['file_path'];
|
|
||||||
|
|
||||||
switch ( $this->get_type_of_file_path( $value ) ) {
|
switch ( $this->get_type_of_file_path( $value ) ) {
|
||||||
case 'absolute':
|
case 'absolute':
|
||||||
$this->data['file'] = esc_url_raw( $value );
|
$this->data['file'] = esc_url_raw( $value );
|
||||||
|
|
|
@ -152,7 +152,7 @@ class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
// Test download permissions.
|
// Test download permissions.
|
||||||
$prod_download = new WC_Product_Download();
|
$prod_download = new WC_Product_Download();
|
||||||
$prod_download->set_file( WC_ABSPATH . 'assets/images/help.png' );
|
$prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' );
|
||||||
$prod_download->set_id( 'download' );
|
$prod_download->set_id( 'download' );
|
||||||
|
|
||||||
$product = new WC_Product_Simple();
|
$product = new WC_Product_Simple();
|
||||||
|
@ -382,7 +382,7 @@ class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
|
||||||
$customer_id = wc_create_new_customer( 'test@example.com', 'testuser', 'testpassword' );
|
$customer_id = wc_create_new_customer( 'test@example.com', 'testuser', 'testpassword' );
|
||||||
|
|
||||||
$prod_download = new WC_Product_Download();
|
$prod_download = new WC_Product_Download();
|
||||||
$prod_download->set_file( WC_ABSPATH . 'assets/images/help.png' );
|
$prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' );
|
||||||
$prod_download->set_id( 1 );
|
$prod_download->set_id( 1 );
|
||||||
|
|
||||||
$product = new WC_Product_Simple();
|
$product = new WC_Product_Simple();
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class WC_Product_Download_Test.
|
|
||||||
*/
|
|
||||||
class WC_Product_Download_Test extends WC_Unit_Test_Case {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper utitility to get mocked object of WC_Product_Download class.
|
|
||||||
*
|
|
||||||
* @return WC_Product_Download
|
|
||||||
*/
|
|
||||||
public function get_sut_with_get_file() {
|
|
||||||
return $this->getMockBuilder( WC_Product_Download::class )
|
|
||||||
->setMethods( array( 'get_file' ) )
|
|
||||||
->getMock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test when file appears remote but is local.
|
|
||||||
*/
|
|
||||||
public function test_is_allowed_filetype_when_file_with_false_query_params() {
|
|
||||||
$download = $this->get_sut_with_get_file();
|
|
||||||
$payload = trailingslashit( site_url( '/' ) ) . 'non_exists/?/../../wp-config.php';
|
|
||||||
$download->method( 'get_file' )->willReturn( $payload );
|
|
||||||
$this->assertFalse( $download->is_allowed_filetype() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test when file appears remote, but is local and tries to appear remote by having characters to be stripped by esc_url_raw.
|
|
||||||
*/
|
|
||||||
public function test_is_allowed_filetype_when_file_with_quote_and_false_query_params() {
|
|
||||||
$download = $this->get_sut_with_get_file();
|
|
||||||
$payload = trailingslashit( site_url( '/' ) ) . '"non_exists/?/../../foo.php';
|
|
||||||
$download->method( 'get_file' )->willReturn( $payload );
|
|
||||||
$this->assertFalse( $download->is_allowed_filetype() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test when file has invalid scheme.
|
|
||||||
*/
|
|
||||||
public function test_is_allowed_filetype_when_file_with_url_escapable_scheme() {
|
|
||||||
$download = $this->get_sut_with_get_file();
|
|
||||||
$payload = trailingslashit( site_url( '/' ) );
|
|
||||||
$payload = str_replace( 'http', 'http;', $payload );
|
|
||||||
$payload = trailingslashit( $payload ) . 'wp-config.php?/../../foo'; // http;//example.com/wp-config.php?/../../foo.
|
|
||||||
$download->method( 'get_file' )->willReturn( $payload );
|
|
||||||
$this->assertFalse( $download->is_allowed_filetype() );
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue