From f435c2f91eaeba686d8f3bda4a6f8c41bb3e7329 Mon Sep 17 00:00:00 2001 From: pkamps Date: Tue, 10 Jul 2018 19:26:49 +0200 Subject: [PATCH] Avoid double decoding of URL (#97) * Avoid double decoding of URL eZSYS::requestURI is already decoding the URL. The eZURI class does it a 2nd time. Example of the problem. Given URL: http://dev.lovestack.mugo.ca/(foo)/bar%2Bbar Double decoded version is is /(foo)/bar bar (that's a space in between) But the correct value is /(foo)/bar+bar * Adding parameter for __construct to indicate that the URL does not need to be decoded again * Fixing ezsys to satisfy unit tests * Tabs replaced with spaces --- lib/ezutils/classes/ezsys.php | 33 ++++++++++++--------------------- lib/ezutils/classes/ezuri.php | 23 ++++++++++++++++------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/ezutils/classes/ezsys.php b/lib/ezutils/classes/ezsys.php index 33fbb8e4eb3..14158b0f7c9 100644 --- a/lib/ezutils/classes/ezsys.php +++ b/lib/ezutils/classes/ezsys.php @@ -1154,34 +1154,25 @@ public static function init( $index = 'index.php', $forceVirtualHost = null ) } } - // remove url and hash parameters - if ( isset( $requestUri[1] ) && $requestUri !== '/' ) + // extract path and query string from URL + if ( strlen( $requestUri ) && $requestUri !== '/' ) { - $uriGetPos = strpos( $requestUri, '?' ); - if ( $uriGetPos !== false ) - { - $queryString = substr( $requestUri, $uriGetPos ); - if ( $uriGetPos === 0 ) - $requestUri = ''; - else - $requestUri = substr( $requestUri, 0, $uriGetPos ); - } - - $uriHashPos = strpos( $requestUri, '#' ); - if ( $uriHashPos === 0 ) - $requestUri = ''; - elseif ( $uriHashPos !== false ) - $requestUri = substr( $requestUri, 0, $uriHashPos ); + $uriParts = parse_url( $requestUri ); + $requestUri = isset( $uriParts[ 'path' ] ) ? $uriParts[ 'path' ] : ''; + $queryString = isset( $uriParts[ 'query' ] ) ? '?' . $uriParts[ 'query' ] : ''; } - // normalize slash use and url decode url if needed - if ( $requestUri === '/' || $requestUri === '' ) + // normalize slash use + $requestUri = '/' . trim( $requestUri, '/ ' ); + + // url decode url if needed + if ( $requestUri !== '/' ) { - $requestUri = ''; + $requestUri = urldecode( $requestUri ); } else { - $requestUri = '/' . urldecode( trim( $requestUri, '/ ' ) ); + $requestUri = ''; } $instance->AccessPath = array( 'siteaccess' => array( 'name' => '', 'url' => array() ), diff --git a/lib/ezutils/classes/ezuri.php b/lib/ezutils/classes/ezuri.php index 1bb94ee18cf..0f3f59df26c 100644 --- a/lib/ezutils/classes/ezuri.php +++ b/lib/ezutils/classes/ezuri.php @@ -69,11 +69,12 @@ class eZURI * Initializes with the URI string $uri. The URI string is split on / into an array. * * @param string $uri the URI to use + * @param boolean $decode controls if the $uri needs to be decoded first * @return void */ - public function __construct( $uri ) + public function __construct( $uri, $decode = false ) { - $this->setURIString( $uri ); + $this->setURIString( $uri, true, $decode ); } /** @@ -84,9 +85,8 @@ public function __construct( $uri ) * @param string $str the string to decode * @return string decoded version of $str */ - public static function decodeIRI( $str ) + protected static function decodeIRI( $str ) { - $str = urldecode( $str ); // Decode %xx entries, we now have a utf-8 string $codec = eZTextCodec::instance( 'utf-8' ); // Make sure string is converted from utf-8 to internal encoding return $codec->convertString( $str ); } @@ -142,7 +142,7 @@ public static function codecURL( $url, $encode ) if ( $encode ) $data['path'] = eZURI::encodeIRI( $data['path'] ); // Make sure it is encoded to IRI format else - $data['path'] = eZURI::decodeIRI( $data['path'] ); // Make sure it is dencoded to internal encoding + $data['path'] = eZURI::decodeIRI( urldecode( $data['path'] ) ); // Make sure it is decoded to internal encoding } // Reconstruct the URL @@ -213,14 +213,20 @@ public static function decodeURL( $url ) * * @param string $uri * @param boolean $fullInitialize + * @param boolean $decode controls if the $uri needs to be decoded first * @return void */ - public function setURIString( $uri, $fullInitialize = true ) + public function setURIString( $uri, $fullInitialize = true, $decode = false ) { if ( strlen( $uri ) > 0 and $uri[0] == '/' ) $uri = substr( $uri, 1 ); + if( $decode ) + { + $uri = urldecode( $uri ); + } + $uri = eZURI::decodeIRI( $uri ); $this->URI = $uri; @@ -576,7 +582,10 @@ public static function instance( $uri = false ) { if ( !isset( $GLOBALS['eZURIRequestInstance'] ) ) { - $GLOBALS['eZURIRequestInstance'] = new eZURI( eZSys::requestURI() ); + // Why urlencode? Because, eZURI expects an encoded URI but eZSYS returns a non-encoded URI + $uri = eZSys::requestURI(); + + $GLOBALS['eZURIRequestInstance'] = new eZURI( $uri ); } return $GLOBALS['eZURIRequestInstance']; }