URL encode image/script/css/video paths.

Properly urlencode urls used in HTML attributes. This solves issues with
invalid HTML being generated when paths contain special characters.

Fixes #3395
This commit is contained in:
mark_story 2012-11-25 23:31:22 -05:00
parent b41705f59e
commit 1f35d82c81
2 changed files with 19 additions and 1 deletions

View file

@ -622,6 +622,9 @@ class HelperTest extends CakeTestCase {
$result = $this->Helper->assetUrl('style', array('ext' => '.css')); $result = $this->Helper->assetUrl('style', array('ext' => '.css'));
$this->assertEquals('style.css', $result); $this->assertEquals('style.css', $result);
$result = $this->Helper->assetUrl('dir/sub dir/my image', array('ext' => '.jpg'));
$this->assertEquals('dir/sub%20dir/my%20image.jpg', $result);
$result = $this->Helper->assetUrl('foo.jpg?one=two&three=four'); $result = $this->Helper->assetUrl('foo.jpg?one=two&three=four');
$this->assertEquals('foo.jpg?one=two&three=four', $result); $this->assertEquals('foo.jpg?one=two&three=four', $result);
} }

View file

@ -313,7 +313,7 @@ class Helper extends Object {
if (isset($plugin)) { if (isset($plugin)) {
$path = Inflector::underscore($plugin) . '/' . $path; $path = Inflector::underscore($plugin) . '/' . $path;
} }
$path = h($this->assetTimestamp($this->webroot($path))); $path = $this->_encodeUrl($this->assetTimestamp($this->webroot($path)));
if (!empty($options['fullBase'])) { if (!empty($options['fullBase'])) {
$base = $this->url('/', true); $base = $this->url('/', true);
@ -326,6 +326,21 @@ class Helper extends Object {
return $path; return $path;
} }
/**
* Encodes a URL for use in HTML attributes.
*
* @param string $url The url to encode.
* @return string The url encoded for both URL & HTML contexts.
*/
protected function _encodeUrl($url) {
$path = parse_url($url, PHP_URL_PATH);
$encoded = implode('/', array_map(
'rawurlencode',
explode('/', $path)
));
return h(str_replace($path, $encoded, $url));
}
/** /**
* Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in * Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in
* Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force' * Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force'