diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..90862ff0ee4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2005-2018, Cake Software Foundation, Inc. (https://cakefoundation.org) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 624193e46c5..00000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -CakePHP(tm) : The Rapid Development PHP Framework (https://cakephp.org) -Copyright (c) 2005-2018, Cake Software Foundation, Inc. (https://cakefoundation.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 5dc3663d57d..f452017be48 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
-
+
@@ -38,7 +38,7 @@ recommend using the [app skeleton](https://github.com/cakephp/app) as
a starting point. For existing applications you can run the following:
``` bash
-$ composer require cakephp/cakephp:"~3.5"
+$ composer require cakephp/cakephp:"~3.6"
```
## Running Tests
@@ -69,7 +69,7 @@ tests for CakePHP by doing the following:
* [Slack](https://cakesf.herokuapp.com/) - Join us on Slack.
* [#cakephp](https://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake.
-* [Forum](http://discourse.cakephp.org/) - Official CakePHP forum.
+* [Forum](https://discourse.cakephp.org/) - Official CakePHP forum.
* [GitHub Issues](https://github.com/cakephp/cakephp/issues) - Got issues? Please tell us!
* [Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps) - Want to contribute? Get involved!
diff --git a/VERSION.txt b/VERSION.txt
index 98cc05d3bfd..10007b25c52 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -16,4 +16,4 @@
// @license https://opensource.org/licenses/mit-license.php MIT License
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
-3.6.0
+3.6.1
diff --git a/src/Cache/composer.json b/src/Cache/composer.json
index 3e101a04f2d..23289aa1961 100644
--- a/src/Cache/composer.json
+++ b/src/Cache/composer.json
@@ -23,7 +23,7 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/core": "^3.0.0"
+ "cakephp/core": "^3.6.0"
},
"autoload": {
"psr-4": {
diff --git a/src/Controller/Component/AuthComponent.php b/src/Controller/Component/AuthComponent.php
index 108a2d833ce..19806db4d73 100644
--- a/src/Controller/Component/AuthComponent.php
+++ b/src/Controller/Component/AuthComponent.php
@@ -439,8 +439,8 @@ protected function _loginActionRedirectUrl()
*/
protected function _isLoginAction(Controller $controller)
{
- $url = $controller->request->getRequestTarget();
- $url = Router::normalize($url);
+ $uri = $controller->request->getUri();
+ $url = Router::normalize($uri->getPath());
$loginAction = Router::normalize($this->_config['loginAction']);
return $loginAction === $url;
diff --git a/src/Controller/Component/SecurityComponent.php b/src/Controller/Component/SecurityComponent.php
index 4ebd65f31fa..db83f249418 100644
--- a/src/Controller/Component/SecurityComponent.php
+++ b/src/Controller/Component/SecurityComponent.php
@@ -22,6 +22,7 @@
use Cake\Event\Event;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\ServerRequest;
+use Cake\Routing\Router;
use Cake\Utility\Hash;
use Cake\Utility\Security;
@@ -378,14 +379,21 @@ protected function _validToken(Controller $controller)
*/
protected function _hashParts(Controller $controller)
{
- $fieldList = $this->_fieldsList($controller->request->getData());
- $unlocked = $this->_sortedUnlocked($controller->request->getData());
+ $request = $controller->getRequest();
+
+ // Start the session to ensure we get the correct session id.
+ $session = $request->getSession();
+ $session->start();
+
+ $data = $request->getData();
+ $fieldList = $this->_fieldsList($data);
+ $unlocked = $this->_sortedUnlocked($data);
return [
- $controller->request->getRequestTarget(),
+ Router::url($request->getRequestTarget()),
serialize($fieldList),
$unlocked,
- session_id(),
+ $session->id()
];
}
diff --git a/src/Controller/Controller.php b/src/Controller/Controller.php
index ebc214bf91d..8b5b299f2df 100644
--- a/src/Controller/Controller.php
+++ b/src/Controller/Controller.php
@@ -346,7 +346,7 @@ public function __get($name)
];
if (isset($deprecated[$name])) {
$method = $deprecated[$name];
- deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->%s instead.', $name, $method));
+ deprecationWarning(sprintf('Controller::$%s is deprecated. Use $this->%s() instead.', $name, $method));
return $this->{$method}();
}
diff --git a/src/Core/BasePlugin.php b/src/Core/BasePlugin.php
index 6a20ff972c9..bb76304a807 100644
--- a/src/Core/BasePlugin.php
+++ b/src/Core/BasePlugin.php
@@ -224,7 +224,7 @@ protected function checkHook($hook)
*/
public function routes($routes)
{
- $path = $this->getConfigPath() . DS . 'routes.php';
+ $path = $this->getConfigPath() . 'routes.php';
if (file_exists($path)) {
require $path;
}
@@ -235,7 +235,7 @@ public function routes($routes)
*/
public function bootstrap(PluginApplicationInterface $app)
{
- $bootstrap = $this->getConfigPath() . DS . 'bootstrap.php';
+ $bootstrap = $this->getConfigPath() . 'bootstrap.php';
if (file_exists($bootstrap)) {
require $bootstrap;
}
diff --git a/src/Core/composer.json b/src/Core/composer.json
index 3d49da99ec8..3a485859cb7 100644
--- a/src/Core/composer.json
+++ b/src/Core/composer.json
@@ -23,7 +23,7 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/utility": "^3.0.0"
+ "cakephp/utility": "^3.6.0"
},
"suggest": {
"cakephp/event": "To use PluginApplicationInterface or plugin applications."
diff --git a/src/Core/functions.php b/src/Core/functions.php
index 35bebd1079e..d73eb06bf75 100644
--- a/src/Core/functions.php
+++ b/src/Core/functions.php
@@ -295,7 +295,9 @@ function deprecationWarning($message, $stackFrame = 1)
$frame += ['file' => '[internal]', 'line' => '??'];
$message = sprintf(
- '%s - %s, line: %s',
+ '%s - %s, line: %s' . "\n" .
+ ' You can disable deprecation warnings by setting `Error.errorLevel` to' .
+ ' `E_ALL & ~E_USER_DEPRECATED` in your config/app.php.',
$message,
$frame['file'],
$frame['line']
diff --git a/src/Database/composer.json b/src/Database/composer.json
index 37bc777ea74..3de6513568e 100644
--- a/src/Database/composer.json
+++ b/src/Database/composer.json
@@ -25,9 +25,9 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/cache": "^3.0.0",
- "cakephp/core": "^3.0.0",
- "cakephp/datasource": "^3.0.0"
+ "cakephp/cache": "^3.6.0",
+ "cakephp/core": "^3.6.0",
+ "cakephp/datasource": "^3.6.0"
},
"suggest": {
"cakephp/log": "Require this if you want to use the built-in query logger"
diff --git a/src/Datasource/QueryTrait.php b/src/Datasource/QueryTrait.php
index c0abf4410fe..c99e83ace04 100644
--- a/src/Datasource/QueryTrait.php
+++ b/src/Datasource/QueryTrait.php
@@ -17,7 +17,6 @@
use BadMethodCallException;
use Cake\Collection\Iterator\MapReduce;
use Cake\Datasource\Exception\RecordNotFoundException;
-use Cake\Datasource\ResultSetDecorator;
/**
* Contains the characteristics for an object that is attached to a repository and
@@ -380,8 +379,8 @@ public function getMapReducers()
* Registers a new formatter callback function that is to be executed when trying
* to fetch the results from the database.
*
- * Formatting callbacks will get a first parameter, a `ResultSetDecorator`, that
- * can be traversed and modified at will.
+ * Formatting callbacks will get a first parameter, an object implementing
+ * `\Cake\Collection\CollectionInterface`, that can be traversed and modified at will.
*
* Callbacks are required to return an iterator object, which will be used as
* the return value for this query's result. Formatter functions are applied
diff --git a/src/Datasource/composer.json b/src/Datasource/composer.json
index 8ff1b05810a..7846db255c9 100644
--- a/src/Datasource/composer.json
+++ b/src/Datasource/composer.json
@@ -25,7 +25,7 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/core": "^3.0.0"
+ "cakephp/core": "^3.6.0"
},
"suggest": {
"cakephp/utility": "If you decide to use EntityTrait.",
diff --git a/src/Error/ErrorHandler.php b/src/Error/ErrorHandler.php
index 7f035e23fd2..633b35f058d 100644
--- a/src/Error/ErrorHandler.php
+++ b/src/Error/ErrorHandler.php
@@ -106,8 +106,6 @@ public function __construct($options = [])
*
* Template method of BaseErrorHandler.
*
- * Only when debug > 2 will a formatted error be displayed.
- *
* @param array $error An array of error data.
* @param bool $debug Whether or not the app is in debug mode.
* @return void
diff --git a/src/Form/composer.json b/src/Form/composer.json
index ee3cddc50a3..5e1dfdc9226 100644
--- a/src/Form/composer.json
+++ b/src/Form/composer.json
@@ -22,8 +22,8 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/event": "^3.5.0",
- "cakephp/validation": "^3.5.0"
+ "cakephp/event": "^3.6.0",
+ "cakephp/validation": "^3.6.0"
},
"autoload": {
"psr-4": {
diff --git a/src/Http/ServerRequest.php b/src/Http/ServerRequest.php
index 121e02687ae..cab76391b47 100644
--- a/src/Http/ServerRequest.php
+++ b/src/Http/ServerRequest.php
@@ -230,7 +230,7 @@ class ServerRequest implements ArrayAccess, ServerRequestInterface
'query' => ['get' => 'getQuery()', 'set' => 'withQueryParams()'],
'params' => ['get' => 'getParam()', 'set' => 'withParam()'],
'cookies' => ['get' => 'getCookie()', 'set' => 'withCookieParams()'],
- 'url' => ['get' => 'getRequestTarget()', 'set' => 'withRequestTarget()'],
+ 'url' => ['get' => 'getPath()', 'set' => 'withRequestTarget()'],
'base' => ['get' => 'getAttribute("base")', 'set' => 'withAttribute("base")'],
'webroot' => ['get' => 'getAttribute("webroot")', 'set' => 'withAttribute("webroot")'],
'here' => ['get' => 'getRequestTarget()', 'set' => 'withRequestTarget()'],
@@ -2344,6 +2344,23 @@ public function getRequestTarget()
return $target;
}
+ /**
+ * Get the path of current request.
+ *
+ * @return string
+ * @since 3.6.1
+ */
+ public function getPath()
+ {
+ if ($this->requestTarget === null) {
+ return $this->uri->getPath();
+ }
+
+ list($path) = explode('?', $this->requestTarget);
+
+ return $path;
+ }
+
/**
* Array access read implementation
*
diff --git a/src/Http/Session.php b/src/Http/Session.php
index 3d2126d8f80..fb1891500df 100644
--- a/src/Http/Session.php
+++ b/src/Http/Session.php
@@ -248,13 +248,12 @@ public function __construct(array $config = [])
*/
public function engine($class = null, array $options = [])
{
- if ($class instanceof SessionHandlerInterface) {
- return $this->_engine = $class;
- }
-
if ($class === null) {
return $this->_engine;
}
+ if ($class instanceof SessionHandlerInterface) {
+ return $this->setEngine($class);
+ }
$className = App::className($class, 'Http/Session');
if (!$className) {
@@ -273,6 +272,18 @@ public function engine($class = null, array $options = [])
'The chosen SessionHandler does not implement SessionHandlerInterface, it cannot be used as an engine.'
);
}
+
+ return $this->setEngine($handler);
+ }
+
+ /**
+ * Set the engine property and update the session handler in PHP.
+ *
+ * @param \SessionHandlerInterface $handler The handler to set
+ * @return \SessionHandlerInterface
+ */
+ protected function setEngine(SessionHandlerInterface $handler)
+ {
if (!headers_sent()) {
session_set_save_handler($handler, false);
}
diff --git a/src/ORM/composer.json b/src/ORM/composer.json
index f8e207290d6..1432893969f 100644
--- a/src/ORM/composer.json
+++ b/src/ORM/composer.json
@@ -24,10 +24,10 @@
},
"require": {
"php": ">=5.6.0",
- "cakephp/collection": "^3.0.0",
+ "cakephp/collection": "^3.6.0",
"cakephp/core": "^3.6.0",
- "cakephp/datasource": "^3.1.2",
- "cakephp/database": "^3.1.4",
+ "cakephp/datasource": "^3.6.0",
+ "cakephp/database": "^3.6.0",
"cakephp/event": "^3.6.0",
"cakephp/utility": "^3.6.0",
"cakephp/validation": "^3.6.0"
diff --git a/src/Routing/Router.php b/src/Routing/Router.php
index de6a95161c3..cab3db2f875 100644
--- a/src/Routing/Router.php
+++ b/src/Routing/Router.php
@@ -633,7 +633,7 @@ public static function url($url = null, $full = false)
}
if (empty($url)) {
- $output = isset($here) ? $here : $base . '/';
+ $output = $base . (isset($here) ? $here : '/');
if ($full) {
$output = static::fullBaseUrl() . $output;
}
diff --git a/src/View/Helper/UrlHelper.php b/src/View/Helper/UrlHelper.php
index 81c3a62c2b2..72628787a35 100644
--- a/src/View/Helper/UrlHelper.php
+++ b/src/View/Helper/UrlHelper.php
@@ -161,6 +161,10 @@ public function assetUrl($path, array $options = [])
if (is_array($path)) {
return $this->build($path, !empty($options['fullBase']));
}
+ // data URIs only require HTML escaping
+ if (preg_match('/^data:[a-z]+\/[a-z]+;/', $path)) {
+ return h($path);
+ }
if (strpos($path, '://') !== false || preg_match('/^[a-z]+:/i', $path)) {
return ltrim($this->build($path), '/');
}
diff --git a/src/View/View.php b/src/View/View.php
index 0f39d044c5b..d86ae3946fc 100644
--- a/src/View/View.php
+++ b/src/View/View.php
@@ -56,6 +56,7 @@
* `plugins/SuperHot/Template/Posts/index.ctp`. If a theme template
* is not found for the current action the default app template file is used.
*
+ * @property \Cake\View\Helper\BreadCrumbsHelper $BreadCrumbs
* @property \Cake\View\Helper\FlashHelper $Flash
* @property \Cake\View\Helper\FormHelper $Form
* @property \Cake\View\Helper\HtmlHelper $Html
diff --git a/tests/TestCase/Controller/Component/AuthComponentTest.php b/tests/TestCase/Controller/Component/AuthComponentTest.php
index dd4fc855746..cd743177974 100644
--- a/tests/TestCase/Controller/Component/AuthComponentTest.php
+++ b/tests/TestCase/Controller/Component/AuthComponentTest.php
@@ -830,6 +830,36 @@ public function testNoLoginRedirectForAuthenticatedUser()
$this->assertNull($this->Controller->testUrl);
}
+ /**
+ * testNoLoginRedirectForAuthenticatedUser method
+ *
+ * @return void
+ * @triggers Controller.startup $this->Controller
+ */
+ public function testStartupLoginActionIgnoreQueryString()
+ {
+ $request = new ServerRequest([
+ 'params' => [
+ 'plugin' => null,
+ 'controller' => 'auth_test',
+ 'action' => 'login'
+ ],
+ 'query' => ['redirect' => '/admin/articles'],
+ 'url' => '/auth_test/login?redirect=%2Fadmin%2Farticles',
+ 'session' => $this->Auth->session
+ ]);
+ $this->Controller->request = $request;
+
+ $this->Auth->session->clear();
+ $this->Auth->setConfig('authenticate', ['Form']);
+ $this->Auth->setConfig('authorize', false);
+ $this->Auth->setConfig('loginAction', ['controller' => 'auth_test', 'action' => 'login']);
+
+ $event = new Event('Controller.startup', $this->Controller);
+ $return = $this->Auth->startup($event);
+ $this->assertNull($return);
+ }
+
/**
* Default to loginRedirect, if set, on authError.
*
diff --git a/tests/TestCase/Controller/Component/SecurityComponentTest.php b/tests/TestCase/Controller/Component/SecurityComponentTest.php
index d5ea4f523eb..2971f31806d 100644
--- a/tests/TestCase/Controller/Component/SecurityComponentTest.php
+++ b/tests/TestCase/Controller/Component/SecurityComponentTest.php
@@ -21,6 +21,7 @@
use Cake\Event\Event;
use Cake\Http\ServerRequest;
use Cake\Http\Session;
+use Cake\Routing\Router;
use Cake\TestSuite\TestCase;
use Cake\Utility\Security;
@@ -189,7 +190,7 @@ public function tearDown()
unset($this->Controller);
}
- public function validatePost($expectedException = null, $expectedExceptionMessage = null)
+ public function validatePost($expectedException = 'SecurityException', $expectedExceptionMessage = null)
{
try {
return $this->Controller->Security->validatePost($this->Controller);
@@ -744,6 +745,37 @@ public function testValidatePostSimple()
$this->assertTrue($result);
}
+ /**
+ * test validatePost uses full URL
+ *
+ * @return void
+ * @triggers Controller.startup $this->Controller
+ */
+ public function testValidatePostSubdirectory()
+ {
+ // set the base path.
+ $this->Controller->request = $this->Controller->request
+ ->withAttribute('base', 'subdir')
+ ->withAttributE('webroot', 'subdir/');
+ Router::pushRequest($this->Controller->request);
+
+ $event = new Event('Controller.startup', $this->Controller);
+ $this->Security->startup($event);
+
+ // Differs from testValidatePostSimple because of base url
+ $fields = 'cc9b6af3f33147235ae8f8037b0a71399a2425f2%3A';
+ $unlocked = '';
+ $debug = '';
+
+ $this->Controller->request = $this->Controller->request->withParsedBody([
+ 'Model' => ['username' => '', 'password' => ''],
+ '_Token' => compact('fields', 'unlocked', 'debug')
+ ]);
+
+ $result = $this->validatePost();
+ $this->assertTrue($result);
+ }
+
/**
* testValidatePostComplex method
*
diff --git a/tests/TestCase/Filesystem/FileTest.php b/tests/TestCase/Filesystem/FileTest.php
index 0045fa64756..743e2579fc3 100644
--- a/tests/TestCase/Filesystem/FileTest.php
+++ b/tests/TestCase/Filesystem/FileTest.php
@@ -4,7 +4,7 @@
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
+ * For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
@@ -66,7 +66,7 @@ public function tearDown()
*/
public function testBasic()
{
- $file = CORE_PATH . DS . 'LICENSE.txt';
+ $file = CORE_PATH . DS . 'LICENSE';
$this->File = new File($file, false);
@@ -78,7 +78,6 @@ public function testBasic()
$expecting = [
'dirname' => dirname($file),
'basename' => basename($file),
- 'extension' => 'txt',
'filename' => 'LICENSE',
'filesize' => filesize($file),
'mime' => 'text/plain'
@@ -93,8 +92,7 @@ function_exists('mime_content_type') &&
$this->assertEquals($expecting, $result);
$result = $this->File->ext();
- $expecting = 'txt';
- $this->assertEquals($expecting, $result);
+ $this->assertEquals('', $result);
$result = $this->File->name();
$expecting = 'LICENSE';
diff --git a/tests/TestCase/Http/ServerRequestTest.php b/tests/TestCase/Http/ServerRequestTest.php
index 51755d6b383..d33da3fd686 100644
--- a/tests/TestCase/Http/ServerRequestTest.php
+++ b/tests/TestCase/Http/ServerRequestTest.php
@@ -211,6 +211,23 @@ public function testUrlInPath()
$this->assertEquals('/jump/http://cakephp.org', $request->getRequestTarget());
}
+ /**
+ * Test getPath().
+ *
+ * @return void
+ */
+ public function testGetPath()
+ {
+ $request = new ServerRequest(['url' => '']);
+ $this->assertSame('/', $request->getPath());
+
+ $request = new ServerRequest(['url' => 'some/path?one=something&two=else']);
+ $this->assertEquals('/some/path', $request->getPath());
+
+ $request = $request->withRequestTarget('/foo/bar?x=y');
+ $this->assertEquals('/foo/bar', $request->getPath());
+ }
+
/**
* Test addParams() method
*
diff --git a/tests/TestCase/Mailer/EmailTest.php b/tests/TestCase/Mailer/EmailTest.php
index c9111d29fba..cd54ea1f323 100644
--- a/tests/TestCase/Mailer/EmailTest.php
+++ b/tests/TestCase/Mailer/EmailTest.php
@@ -879,13 +879,13 @@ public function testAttachments()
$this->Email->addAttachments([CORE_PATH . 'config' . DS . 'bootstrap.php']);
$this->Email->addAttachments([
'other.txt' => CORE_PATH . 'config' . DS . 'bootstrap.php',
- 'license' => CORE_PATH . 'LICENSE.txt'
+ 'license' => CORE_PATH . 'LICENSE'
]);
$expected = [
'basics.php' => ['file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'],
'bootstrap.php' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
'other.txt' => ['file' => CORE_PATH . 'config' . DS . 'bootstrap.php', 'mimetype' => 'text/x-php'],
- 'license' => ['file' => CORE_PATH . 'LICENSE.txt', 'mimetype' => 'text/plain']
+ 'license' => ['file' => CORE_PATH . 'LICENSE', 'mimetype' => 'text/plain']
];
$this->assertSame($expected, $this->Email->getAttachments());
$this->expectException(\InvalidArgumentException::class);
diff --git a/tests/TestCase/Routing/RouterTest.php b/tests/TestCase/Routing/RouterTest.php
index d4590d0fe14..a01b06b6287 100644
--- a/tests/TestCase/Routing/RouterTest.php
+++ b/tests/TestCase/Routing/RouterTest.php
@@ -61,7 +61,7 @@ public function tearDown()
*
* @return void
*/
- public function testbaseUrl()
+ public function testBaseUrl()
{
$this->assertRegExp('/^http(s)?:\/\//', Router::url('/', true));
$this->assertRegExp('/^http(s)?:\/\//', Router::url(null, true));
@@ -73,7 +73,7 @@ public function testbaseUrl()
*
* @return void
*/
- public function testfullBaseURL()
+ public function testFullBaseURL()
{
Router::fullBaseUrl('http://example.com');
$this->assertEquals('http://example.com/', Router::url('/', true));
@@ -571,14 +571,17 @@ public function testUrlGenerationWithBasePath()
'plugin' => null,
'controller' => 'subscribe',
],
- 'url' => '/magazine/',
+ 'url' => '/subscribe',
'base' => '/magazine',
'webroot' => '/magazine/'
]);
Router::pushRequest($request);
$result = Router::url();
- $this->assertEquals('/magazine/', $result);
+ $this->assertEquals('/magazine/subscribe', $result);
+
+ $result = Router::url([]);
+ $this->assertEquals('/magazine/subscribe', $result);
$result = Router::url('/');
$this->assertEquals('/magazine/', $result);
@@ -933,7 +936,7 @@ public function testUrlGenerationWithPrefix()
],
'webroot' => '/magazine/',
'base' => '/magazine',
- 'url' => '/magazine/admin/subscriptions/edit/1',
+ 'url' => '/admin/subscriptions/edit/1',
]);
Router::setRequestInfo($request);
diff --git a/tests/TestCase/View/Helper/HtmlHelperTest.php b/tests/TestCase/View/Helper/HtmlHelperTest.php
index b2d6ca28d94..b527d279f38 100644
--- a/tests/TestCase/View/Helper/HtmlHelperTest.php
+++ b/tests/TestCase/View/Helper/HtmlHelperTest.php
@@ -363,6 +363,31 @@ public function testImageTag()
$this->assertHtml($expected, $result);
}
+ /**
+ * Ensure that data URIs don't get base paths set.
+ *
+ * @return void
+ */
+ public function testImageDataUriBaseDir()
+ {
+ $request = $this->Html->request
+ ->withAttribute('base', 'subdir')
+ ->withAttribute('webroot', 'subdir/');
+ $this->Html->Url->request = $this->Html->request = $request;
+ Router::pushRequest($request);
+
+ $data = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4' .
+ '/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
+ $result = $this->Html->image($data);
+ $expected = ['img' => ['src' => $data, 'alt' => '']];
+ $this->assertHtml($expected, $result);
+
+ $data = 'data:image/png;base64,