From 6bdfdfd43609a7a7edb2625d0bcd8bda33681a12 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 20 Apr 2014 01:51:30 +0530 Subject: [PATCH 1/5] Optimize view paths caching for plugins. Closes #2047 --- lib/Cake/Test/Case/Utility/DebuggerTest.php | 1 + lib/Cake/View/View.php | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/DebuggerTest.php b/lib/Cake/Test/Case/Utility/DebuggerTest.php index 63cc39e41..0b02337df 100644 --- a/lib/Cake/Test/Case/Utility/DebuggerTest.php +++ b/lib/Cake/Test/Case/Utility/DebuggerTest.php @@ -362,6 +362,7 @@ TEXT; ) [protected] _scripts => array() [protected] _paths => array() + [protected] _pathsForPlugin => array() [protected] _parents => array() [protected] _current => null [protected] _currentType => '' diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 6ccefbe72..ca838f42e 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -251,6 +251,13 @@ class View extends Object { */ protected $_paths = array(); +/** + * Holds an array of plugin paths. + * + * @var array + */ + protected $_pathsForPlugin = array(); + /** * The names of views and their parents used with View::extend(); * @@ -1112,8 +1119,13 @@ class View extends Object { * @return array paths */ protected function _paths($plugin = null, $cached = true) { - if ($plugin === null && $cached === true && !empty($this->_paths)) { - return $this->_paths; + if ($cached === true) { + if ($plugin === null && !empty($this->_paths)) { + return $this->_paths; + } + if ($plugin !== null && isset($this->_pathsForPlugin[$plugin])) { + return $this->_pathsForPlugin[$plugin]; + } } $paths = array(); $viewPaths = App::path('View'); @@ -1145,7 +1157,7 @@ class View extends Object { } $paths = array_merge($paths, $corePaths); if ($plugin !== null) { - return $paths; + return $this->_pathsForPlugin[$plugin] = $paths; } return $this->_paths = $paths; } From ead494eec117749f294d290e092c551eac00d7fd Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 22 Apr 2014 19:50:18 +0530 Subject: [PATCH 2/5] Allow setting only default layout without specifying template in email config. Closes #3336 --- lib/Cake/Network/Email/CakeEmail.php | 13 ++++++------ .../Test/Case/Network/Email/CakeEmailTest.php | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index 7e38d42ab..8f640ecc8 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -1224,15 +1224,14 @@ class CakeEmail { $this->setHeaders($config['headers']); unset($config['headers']); } + if (array_key_exists('template', $config)) { - $layout = false; - if (array_key_exists('layout', $config)) { - $layout = $config['layout']; - unset($config['layout']); - } - $this->template($config['template'], $layout); - unset($config['template']); + $this->_template = $config['template']; } + if (array_key_exists('layout', $config)) { + $this->_layout = $config['layout']; + } + $this->transportClass()->config($config); } diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 9cb3ca321..e5865fe13 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1807,6 +1807,26 @@ class CakeEmailTest extends CakeTestCase { $this->assertTrue((bool)strpos($result['headers'], 'To: ')); } +/** + * testConfigArrayWithLayoutWithoutTemplate method + * + * @return void + */ + public function testConfigArrayWithLayoutWithoutTemplate() { + $configs = array( + 'from' => array('some@example.com' => 'My website'), + 'to' => 'test@example.com', + 'subject' => 'Test mail subject', + 'transport' => 'Debug', + 'layout' => 'custom' + ); + $this->CakeEmail = new CakeEmail($configs); + + $result = $this->CakeEmail->template(); + $this->assertEquals('', $result['template']); + $this->assertEquals($configs['layout'], $result['layout']); + } + /** * testConstructWithConfigString method * From 01e95945ce053c8468bb5c001de14917038e93aa Mon Sep 17 00:00:00 2001 From: Stefan Dickmann Date: Tue, 22 Apr 2014 21:48:22 +0200 Subject: [PATCH 3/5] update composer.json --- composer.json | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 59646d5e4..35e4052ab 100644 --- a/composer.json +++ b/composer.json @@ -1,31 +1,31 @@ { - "name": "cakephp/cakephp", - "description": "The CakePHP framework", - "type": "library", - "keywords": ["framework"], - "homepage": "http://cakephp.org", - "license": "MIT", - "authors": [ - { - "name": "CakePHP Community", - "homepage": "https://github.com/cakephp/cakephp/graphs/contributors" - } - ], - "support": { - "issues": "https://github.com/cakephp/cakephp/issues", - "forum": "http://stackoverflow.com/tags/cakephp", - "irc": "irc://irc.freenode.org/cakephp", - "source": "https://github.com/cakephp/cakephp" - }, - "require": { - "php": ">=5.2.8", - "ext-mcrypt": "*" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*", - "cakephp/debug_kit" : "2.2.*" - }, - "bin": [ - "lib/Cake/Console/cake" - ] + "name": "cakephp/cakephp", + "description": "The CakePHP framework", + "type": "library", + "keywords": ["framework"], + "homepage": "http://cakephp.org", + "license": "MIT", + "authors": [ + { + "name": "CakePHP Community", + "homepage": "https://github.com/cakephp/cakephp/graphs/contributors" + } + ], + "support": { + "issues": "https://github.com/cakephp/cakephp/issues", + "forum": "http://stackoverflow.com/tags/cakephp", + "irc": "irc://irc.freenode.org/cakephp", + "source": "https://github.com/cakephp/cakephp" + }, + "require": { + "php": ">=5.2.8", + "ext-mcrypt": "*" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "cakephp/debug_kit" : "2.2.*" + }, + "bin": [ + "lib/Cake/Console/cake" + ] } From 2333c3d535353e1ba5529ccaf9bb4316a85e99ea Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 23 Apr 2014 22:15:10 -0400 Subject: [PATCH 4/5] Update docs for file(). Mention that relative paths will be prepended with APP. Refs #3370 --- lib/Cake/Network/CakeResponse.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 3ed93bcbd..bb57265e2 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -1247,7 +1247,8 @@ class CakeResponse { * - name: Alternate download name * - download: If `true` sets download header and forces file to be downloaded rather than displayed in browser * - * @param string $path Path to file + * @param string $path Path to file. If the path is not an absolute path that resolves + * to a file, `APP` will be prepended to the path. * @param array $options Options See above. * @return void * @throws NotFoundException From 6f68049bf507783c5f278eccbd0c807a0ecc45c3 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 23 Apr 2014 22:20:14 -0400 Subject: [PATCH 5/5] Reject file paths containing `..`. Paths containing `..` are generally up to no good. Throw an exception, as developers can use realpath() if they really need to get relative paths. Fixes #3370 --- lib/Cake/Network/CakeResponse.php | 7 +++++++ lib/Cake/Test/Case/Network/CakeResponseTest.php | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index bb57265e2..d5f2dc869 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -1259,6 +1259,13 @@ class CakeResponse { 'download' => null ); + if (strpos($path, '..') !== false) { + throw new NotFoundException(__d( + 'cake_dev', + 'The requested file contains `..` and will not be read.' + )); + } + if (!is_file($path)) { $path = APP . $path; } diff --git a/lib/Cake/Test/Case/Network/CakeResponseTest.php b/lib/Cake/Test/Case/Network/CakeResponseTest.php index 16326ea4d..c9fb23a14 100644 --- a/lib/Cake/Test/Case/Network/CakeResponseTest.php +++ b/lib/Cake/Test/Case/Network/CakeResponseTest.php @@ -1075,6 +1075,17 @@ class CakeResponseTest extends CakeTestCase { $response->file('/some/missing/folder/file.jpg'); } +/** + * test file with .. + * + * @expectedException NotFoundException + * @return void + */ + public function testFileWithPathTraversal() { + $response = new CakeResponse(); + $response->file('my/../cat.gif'); + } + /** * testFile method *