mirror of
https://github.com/getgrav/grav.git
synced 2025-02-20 19:56:53 +01:00
Merge branch 'develop' of github.com:getgrav/grav into develop
This commit is contained in:
commit
7b7235297e
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -1,3 +1,17 @@
|
|||
# v1.7.31
|
||||
## mm/dd/2022
|
||||
|
||||
1. [](#new)
|
||||
* Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533)
|
||||
* Added XSS check for uploaded SVG files before they get stored
|
||||
* Fixed phpstan issues (All level 2, Framework level 5)
|
||||
2. [](#bugfix)
|
||||
* Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504)
|
||||
* Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542)
|
||||
* Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540)
|
||||
* Fixed entity sanitization for XSS detection
|
||||
* Fixed avatar save location when `account://` stream points to custom directory
|
||||
|
||||
# v1.7.30
|
||||
## 02/07/2022
|
||||
|
||||
|
|
|
|||
8
bin/gpm
8
bin/gpm
|
|
@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
|||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
|
|
|
|||
8
bin/grav
8
bin/grav
|
|
@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
|||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
|
|||
|
||||
$autoload = require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@
|
|||
"scripts": {
|
||||
"api-17": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.17.md",
|
||||
"post-create-project-cmd": "bin/grav install",
|
||||
"phpstan": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/phpstan.neon --memory-limit=720M system/src",
|
||||
"phpstan-framework": "vendor/bin/phpstan analyse -l 4 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer",
|
||||
"phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon --memory-limit=720M system/src",
|
||||
"phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer",
|
||||
"phpstan-plugins": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/plugins.neon --memory-limit=400M user/plugins",
|
||||
"test": "vendor/bin/codecept run unit",
|
||||
"test-windows": "vendor\\bin\\codecept run unit"
|
||||
|
|
|
|||
96
composer.lock
generated
96
composer.lock
generated
|
|
@ -840,22 +840,21 @@
|
|||
},
|
||||
{
|
||||
"name": "itsgoingd/clockwork",
|
||||
"version": "v5.1.4",
|
||||
"version": "v5.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/itsgoingd/clockwork.git",
|
||||
"reference": "7252aa771b77ac8678b44290fd7ec7577435cce6"
|
||||
"reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/7252aa771b77ac8678b44290fd7ec7577435cce6",
|
||||
"reference": "7252aa771b77ac8678b44290fd7ec7577435cce6",
|
||||
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/6a7b3942224fa53cf3704d9adba636e1f3dfeb9a",
|
||||
"reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=5.6",
|
||||
"psr/log": "1.* || ^2.0"
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
|
@ -897,7 +896,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/itsgoingd/clockwork/issues",
|
||||
"source": "https://github.com/itsgoingd/clockwork/tree/v5.1.4"
|
||||
"source": "https://github.com/itsgoingd/clockwork/tree/v5.1.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -905,7 +904,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-30T12:36:18+00:00"
|
||||
"time": "2022-02-13T22:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/climate",
|
||||
|
|
@ -1105,25 +1104,26 @@
|
|||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.17.3",
|
||||
"version": "v1.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||
"reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c"
|
||||
"reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/e8ac3499af0ea5b440908e06cc0abe5898008b3c",
|
||||
"reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c",
|
||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
|
||||
"reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1|^8",
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/var-dumper": "^2.6|^3|^4|^5"
|
||||
"symfony/var-dumper": "^2.6|^3|^4|^5|^6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.4.2"
|
||||
"phpunit/phpunit": "^7.5.20 || ^9.4.2",
|
||||
"twig/twig": "^1.38|^2.7|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"kriswallsmith/assetic": "The best way to manage assets",
|
||||
|
|
@ -1164,9 +1164,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maximebf/php-debugbar/issues",
|
||||
"source": "https://github.com/maximebf/php-debugbar/tree/v1.17.3"
|
||||
"source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0"
|
||||
},
|
||||
"time": "2021-10-19T12:33:27+00:00"
|
||||
"time": "2021-12-27T18:49:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "miljar/php-exif",
|
||||
|
|
@ -2730,12 +2730,12 @@
|
|||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
|
@ -4019,12 +4019,12 @@
|
|||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
],
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
|
@ -4356,16 +4356,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phar-io/version",
|
||||
"version": "3.1.1",
|
||||
"version": "3.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/version.git",
|
||||
"reference": "15a90844ad40f127afd244c0cad228de2a80052a"
|
||||
"reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a",
|
||||
"reference": "15a90844ad40f127afd244c0cad228de2a80052a",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
|
||||
"reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4401,9 +4401,9 @@
|
|||
"description": "Library for handling version information and constraints",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/version/issues",
|
||||
"source": "https://github.com/phar-io/version/tree/3.1.1"
|
||||
"source": "https://github.com/phar-io/version/tree/3.2.1"
|
||||
},
|
||||
"time": "2022-02-07T21:56:48+00:00"
|
||||
"time": "2022-02-21T01:04:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
|
|
@ -4748,16 +4748,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.10",
|
||||
"version": "9.2.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "d5850aaf931743067f4bfc1ae4cbd06468400687"
|
||||
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687",
|
||||
"reference": "d5850aaf931743067f4bfc1ae4cbd06468400687",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f",
|
||||
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4813,7 +4813,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -4821,7 +4821,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-05T09:12:13+00:00"
|
||||
"time": "2022-02-18T12:46:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
|
@ -5066,16 +5066,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.13",
|
||||
"version": "9.5.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "597cb647654ede35e43b137926dfdfef0fb11743"
|
||||
"reference": "1883687169c017d6ae37c58883ca3994cfc34189"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743",
|
||||
"reference": "597cb647654ede35e43b137926dfdfef0fb11743",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189",
|
||||
"reference": "1883687169c017d6ae37c58883ca3994cfc34189",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5153,7 +5153,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -5165,7 +5165,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-24T07:33:35+00:00"
|
||||
"time": "2022-02-18T12:54:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
|
|
@ -5725,16 +5725,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
"version": "5.0.3",
|
||||
"version": "5.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||
"reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49"
|
||||
"reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49",
|
||||
"reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
|
||||
"reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5777,7 +5777,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3"
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -5785,7 +5785,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-11T13:31:12+00:00"
|
||||
"time": "2022-02-14T08:28:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/lines-of-code",
|
||||
|
|
|
|||
28
index.php
28
index.php
|
|
@ -20,16 +20,6 @@ if (PHP_SAPI === 'cli-server') {
|
|||
}
|
||||
}
|
||||
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
$autoload = __DIR__ . '/vendor/autoload.php';
|
||||
if (!is_file($autoload)) {
|
||||
|
|
@ -39,23 +29,23 @@ if (!is_file($autoload)) {
|
|||
// Register the auto-loader.
|
||||
$loader = require $autoload;
|
||||
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
// Get the Grav instance
|
||||
$grav = Grav::instance(
|
||||
array(
|
||||
'loader' => $loader
|
||||
)
|
||||
);
|
||||
$grav = Grav::instance(array('loader' => $loader));
|
||||
|
||||
// Process the page
|
||||
try {
|
||||
$grav->process();
|
||||
} catch (\Error $e) {
|
||||
$grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
|
||||
throw $e;
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Error|\Exception $e) {
|
||||
$grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
|
||||
throw $e;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ form:
|
|||
avatar:
|
||||
type: file
|
||||
size: large
|
||||
destination: 'user://accounts/avatars'
|
||||
destination: 'account://avatars'
|
||||
multiple: false
|
||||
random_name: true
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use Grav\Common\Assets\Traits\TestingAssetsTrait;
|
|||
use Grav\Common\Config\Config;
|
||||
use Grav\Framework\Object\PropertyObject;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use function array_slice;
|
||||
use function call_user_func_array;
|
||||
use function count;
|
||||
use function func_get_args;
|
||||
use function is_array;
|
||||
|
||||
|
|
@ -174,6 +174,10 @@ class Assets extends PropertyObject
|
|||
*/
|
||||
public function add($asset)
|
||||
{
|
||||
if (!$asset) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
// More than one asset
|
||||
|
|
@ -198,7 +202,8 @@ class Assets extends PropertyObject
|
|||
call_user_func_array([$this, 'add'], $args);
|
||||
} else {
|
||||
// Get extension
|
||||
$extension = Utils::pathinfo(parse_url($asset, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
$path = parse_url($asset, PHP_URL_PATH);
|
||||
$extension = $path ? Utils::pathinfo($path, PATHINFO_EXTENSION) : '';
|
||||
|
||||
// JavaScript or CSS
|
||||
if ($extension !== '') {
|
||||
|
|
@ -525,8 +530,8 @@ class Assets extends PropertyObject
|
|||
/**
|
||||
* Build the Javascript Modules tags
|
||||
*
|
||||
* @param $group
|
||||
* @param $attributes
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function jsModule($group = 'head', $attributes = [])
|
||||
|
|
@ -534,6 +539,11 @@ class Assets extends PropertyObject
|
|||
return $this->render(self::JS_MODULE, $group, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function all($group = 'head', $attributes = [])
|
||||
{
|
||||
$output = $this->css($group, $attributes, false);
|
||||
|
|
@ -543,11 +553,19 @@ class Assets extends PropertyObject
|
|||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string $type
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidType($type)
|
||||
{
|
||||
return in_array($type, [self::CSS_TYPE, self::JS_TYPE, self::JS_MODULE_TYPE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string $type
|
||||
* @return string
|
||||
*/
|
||||
protected function getBaseType($type)
|
||||
{
|
||||
switch ($type) {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class BlockAssets
|
|||
|
||||
/**
|
||||
* @param Assets $assets
|
||||
* @param array $groups
|
||||
* @param array $list
|
||||
* @return void
|
||||
*/
|
||||
protected static function registerFrameworks(Assets $assets, array $list): void
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class Backups
|
|||
*/
|
||||
public function getBackupDownloadUrl($backup, $base_url)
|
||||
{
|
||||
$param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':');
|
||||
$param_sep = Grav::instance()['config']->get('system.param_sep', ':');
|
||||
$download = urlencode(base64_encode(Utils::basename($backup)));
|
||||
$url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim(
|
||||
$base_url,
|
||||
|
|
|
|||
|
|
@ -606,8 +606,10 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
|||
}
|
||||
}
|
||||
|
||||
/** @var PageCollection|PageIndex $children */
|
||||
$children = $page->children();
|
||||
/** @var PageIndex $children */
|
||||
$children = $page->children()->getIndex();
|
||||
$children = $children->getIndex();
|
||||
$selectedChildren = $children->filterBy($filters, true);
|
||||
|
||||
/** @var Header $header */
|
||||
|
|
@ -686,6 +688,8 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
|||
$extras = array_filter($extras, static function ($v) {
|
||||
return $v !== null;
|
||||
});
|
||||
|
||||
/** @var PageIndex $tmp */
|
||||
$tmp = $child->children()->getIndex();
|
||||
$child_count = $tmp->count();
|
||||
$count = $filters ? $tmp->filterBy($filters, true)->count() : null;
|
||||
|
|
|
|||
|
|
@ -625,7 +625,14 @@ class PageObject extends FlexPageObject
|
|||
|
||||
// If current filter does not match, we still may have match as a parent.
|
||||
if ($matches === false) {
|
||||
return $recursive && $this->children()->getIndex()->filterBy($filters, true)->count() > 0;
|
||||
if (!$recursive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var PageIndex $index */
|
||||
$index = $this->children()->getIndex();
|
||||
|
||||
return $index->filterBy($filters, true)->count() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ class UserObject extends FlexObject implements UserInterface, Countable
|
|||
// Check for shared media
|
||||
if (!$folder && !$this->getFlexDirectory()->getMediaFolder()) {
|
||||
$this->_loadMedia = false;
|
||||
$folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'user://accounts/avatars';
|
||||
$folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'account://avatars';
|
||||
}
|
||||
|
||||
return $folder;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ use function call_user_func_array;
|
|||
use function function_exists;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_callable;
|
||||
use function is_int;
|
||||
use function is_string;
|
||||
|
|
@ -729,14 +730,17 @@ class Grav extends Container
|
|||
*/
|
||||
public function fallbackUrl($path)
|
||||
{
|
||||
$path_parts = Utils::pathinfo($path);
|
||||
if (!is_array($path_parts)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this['config'];
|
||||
|
||||
$path_parts = Utils::pathinfo($path);
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $this['pages'];
|
||||
$page = $pages->find($path_parts['dirname'], true);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ use Grav\Common\Data\Data;
|
|||
* Class implements media object interface.
|
||||
*
|
||||
* @property string $type
|
||||
* @property string $filename
|
||||
* @property string $filepath
|
||||
*/
|
||||
interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObjectInterface, ArrayAccess
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ trait MediaPlayerTrait
|
|||
public function controls($status = true)
|
||||
{
|
||||
if ($status) {
|
||||
$this->attributes['controls'] = true;
|
||||
$this->attributes['controls'] = 'controls';
|
||||
} else {
|
||||
unset($this->attributes['controls']);
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ trait MediaPlayerTrait
|
|||
public function loop($status = false)
|
||||
{
|
||||
if ($status) {
|
||||
$this->attributes['loop'] = true;
|
||||
$this->attributes['loop'] = 'loop';
|
||||
} else {
|
||||
unset($this->attributes['loop']);
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ trait MediaPlayerTrait
|
|||
public function autoplay($status = false)
|
||||
{
|
||||
if ($status) {
|
||||
$this->attributes['autoplay'] = true;
|
||||
$this->attributes['autoplay'] = 'autoplay';
|
||||
} else {
|
||||
unset($this->attributes['autoplay']);
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ trait MediaPlayerTrait
|
|||
public function muted($status = false)
|
||||
{
|
||||
if ($status) {
|
||||
$this->attributes['muted'] = true;
|
||||
$this->attributes['muted'] = 'muted';
|
||||
} else {
|
||||
unset($this->attributes['muted']);
|
||||
}
|
||||
|
|
@ -108,6 +108,6 @@ trait MediaPlayerTrait
|
|||
*/
|
||||
public function resetPlayer()
|
||||
{
|
||||
$this->attributes['controls'] = true;
|
||||
$this->attributes['controls'] = 'controls';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ trait MediaUploadTrait
|
|||
'size' => $uploadedFile->getSize(),
|
||||
];
|
||||
|
||||
if ($uploadedFile instanceof FormFlashFile) {
|
||||
$uploadedFile->checkXss();
|
||||
}
|
||||
|
||||
return $this->checkFileMetadata($metadata, $filename, $settings);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ trait VideoMediaTrait
|
|||
public function playsinline($status = false)
|
||||
{
|
||||
if ($status) {
|
||||
$this->attributes['playsinline'] = true;
|
||||
$this->attributes['playsinline'] = 'playsinline';
|
||||
} else {
|
||||
unset($this->attributes['playsinline']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,8 +159,9 @@ class MediumFactory
|
|||
return new ImageMedium($items, $blueprint);
|
||||
case 'thumbnail':
|
||||
return new ThumbnailImageMedium($items, $blueprint);
|
||||
case 'animated':
|
||||
case 'vector':
|
||||
return new VectorImageMedium($items, $blueprint);
|
||||
case 'animated':
|
||||
return new StaticImageMedium($items, $blueprint);
|
||||
case 'video':
|
||||
return new VideoMedium($items, $blueprint);
|
||||
|
|
|
|||
68
system/src/Grav/Common/Page/Medium/VectorImageMedium.php
Normal file
68
system/src/Grav/Common/Page/Medium/VectorImageMedium.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Common\Page
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
|
||||
|
||||
/**
|
||||
* Class StaticImageMedium
|
||||
* @package Grav\Common\Page\Medium
|
||||
*/
|
||||
class VectorImageMedium extends StaticImageMedium
|
||||
{
|
||||
/**
|
||||
* Construct.
|
||||
*
|
||||
* @param array $items
|
||||
* @param Blueprint|null $blueprint
|
||||
*/
|
||||
public function __construct($items = [], Blueprint $blueprint = null)
|
||||
{
|
||||
parent::__construct($items, $blueprint);
|
||||
|
||||
// If we already have the image size, we do not need to do anything else.
|
||||
$width = $this->get('width');
|
||||
$height = $this->get('height');
|
||||
if ($width && $height) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that getting image size is supported.
|
||||
if ($this->mime !== 'image/svg+xml' || !\extension_loaded('simplexml')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that the image exists.
|
||||
$path = $this->get('filepath');
|
||||
if (!$path || !file_exists($path) || !filesize($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$xml = simplexml_load_string(file_get_contents($path));
|
||||
$attr = $xml ? $xml->attributes() : null;
|
||||
if (!$attr instanceof \SimpleXMLElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the size from svg image.
|
||||
if ($attr->width && $attr->height) {
|
||||
$width = (string)$attr->width;
|
||||
$height = (string)$attr->height;
|
||||
} elseif ($attr->viewBox && \count($size = explode(' ', (string)$attr->viewBox)) === 4) {
|
||||
[,$width,$height,] = $size;
|
||||
}
|
||||
|
||||
if ($width && $height) {
|
||||
$this->def('width', (int)$width);
|
||||
$this->def('height', (int)$height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -736,7 +736,13 @@ class Pages
|
|||
break;
|
||||
case 'siblings':
|
||||
$parent = $page->parent();
|
||||
$collection = $parent ? $parent->children()->remove($page->path()) : new Collection();
|
||||
if ($parent) {
|
||||
/** @var Collection $collection */
|
||||
$collection = $parent->children();
|
||||
$collection = $collection->remove($page->path());
|
||||
} else {
|
||||
$collection = new Collection();
|
||||
}
|
||||
break;
|
||||
case 'descendants':
|
||||
$collection = $this->all($page)->remove($page->path())->pages();
|
||||
|
|
@ -1041,9 +1047,14 @@ class Pages
|
|||
$this->grav->redirectLangSafe($page->redirect());
|
||||
}
|
||||
|
||||
if (!$routable && ($child = $page->children()->visible()->routable()->published()->first()) !== null) {
|
||||
// Redirect to the first visible child as current page isn't routable.
|
||||
$this->grav->redirectLangSafe($child->route());
|
||||
if (!$routable) {
|
||||
/** @var Collection $children */
|
||||
$children = $page->children()->visible()->routable()->published();
|
||||
$child = $children->first();
|
||||
if ($child !== null) {
|
||||
// Redirect to the first visible child as current page isn't routable.
|
||||
$this->grav->redirectLangSafe($child->route());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,22 @@ use function is_string;
|
|||
*/
|
||||
class Security
|
||||
{
|
||||
/**
|
||||
* @param string $filepath
|
||||
* @param array|null $options
|
||||
* @return string|null
|
||||
*/
|
||||
public static function detectXssFromSvgFile(string $filepath, array $options = null): ?string
|
||||
{
|
||||
if (file_exists($filepath) && Grav::instance()['config']->get('security.sanitize_svg')) {
|
||||
$content = file_get_contents($filepath);
|
||||
|
||||
return static::detectXss($content, $options);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize SVG string for XSS code
|
||||
*
|
||||
|
|
@ -200,7 +216,7 @@ class Security
|
|||
}, $string);
|
||||
|
||||
// Clean up entities
|
||||
$string = preg_replace('!(�+[0-9]+)!u', '$1;', $string);
|
||||
$string = preg_replace('!(&#[0-9]+);?!u', '$1;', $string);
|
||||
|
||||
// Decode entities
|
||||
$string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace Grav\Common\Twig;
|
|||
|
||||
use Twig\Environment;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Loader\ExistsLoaderInterface;
|
||||
use Twig\Loader\LoaderInterface;
|
||||
use Twig\Template;
|
||||
use Twig\TemplateWrapper;
|
||||
|
||||
|
|
@ -41,8 +43,12 @@ class TwigEnvironment extends Environment
|
|||
}
|
||||
|
||||
// Optimization: Avoid throwing an exception when it would be ignored anyway.
|
||||
if (1 !== $count && !$this->getLoader()->exists($name)) {
|
||||
continue;
|
||||
if (1 !== $count) {
|
||||
/** @var LoaderInterface|ExistsLoaderInterface $loader */
|
||||
$loader = $this->getLoader();
|
||||
if (!$loader->exists($name)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Throws LoaderError: Unable to find template "%s".
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ class User extends Data implements UserInterface
|
|||
*/
|
||||
public function getMediaFolder()
|
||||
{
|
||||
return $this->blueprints()->fields()['avatar']['destination'] ?? 'user://accounts/avatars';
|
||||
return $this->blueprints()->fields()['avatar']['destination'] ?? 'account://avatars';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -994,7 +994,7 @@ abstract class Utils
|
|||
* @param int|null $flags
|
||||
* @return array|string
|
||||
*/
|
||||
public static function pathinfo(string $path, int $flags = null)
|
||||
public static function pathinfo($path, int $flags = null)
|
||||
{
|
||||
$path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path));
|
||||
|
||||
|
|
@ -1020,7 +1020,7 @@ abstract class Utils
|
|||
* @param string $suffix
|
||||
* @return string
|
||||
*/
|
||||
public static function basename(string $path, string $suffix = ''): string
|
||||
public static function basename($path, string $suffix = ''): string
|
||||
{
|
||||
return rawurldecode(basename(str_replace(['%2F', '%5C'], '/', rawurlencode($path)), $suffix));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace Grav\Framework\Form;
|
||||
|
||||
use Grav\Common\Security;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Psr7\Stream;
|
||||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
|
|
@ -182,6 +184,21 @@ class FormFlashFile implements UploadedFileInterface, JsonSerializable
|
|||
return $this->upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function checkXss(): void
|
||||
{
|
||||
$tmpFile = $this->getTmpFile();
|
||||
$mime = $this->getClientMediaType();
|
||||
if (Utils::contains($mime, 'svg', false)) {
|
||||
$response = Security::detectXssFromSvgFile($tmpFile);
|
||||
if ($response) {
|
||||
throw new RuntimeException(sprintf('SVG file XSS check failed on %s', $response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user