corrections de problèmes de liens inter articles et de display du about

This commit is contained in:
Valentin 2024-06-04 13:16:42 +02:00
parent 97231dd6bf
commit 7c640a7a14
27 changed files with 356 additions and 425 deletions

View File

@ -1,79 +0,0 @@
name: Release Builds
on:
release:
types: [published]
permissions: {}
jobs:
build:
permissions:
contents: write # for release creation (svenstaro/upload-release-action)
if: "!github.event.release.prerelease"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Extract Tag
run: echo "PACKAGE_VERSION=${{ github.ref }}" >> $GITHUB_ENV
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.3
extensions: opcache, gd
tools: composer:v2
coverage: none
env:
COMPOSER_TOKEN: ${{ secrets.GLOBAL_TOKEN }}
- name: Install Dependencies
run: |
sudo apt-get -y update -qq < /dev/null > /dev/null
sudo apt-get -y install -qq git zip < /dev/null > /dev/null
- name: Retrieval of Builder Scripts
run: |
# Real Grav URL
curl --silent -H "Authorization: token ${{ secrets.GLOBAL_TOKEN }}" -H "Accept: application/vnd.github.v3.raw" ${{ secrets.BUILD_SCRIPT_URL }} --output build-grav.sh
# Development Local URL
# curl ${{ secrets.BUILD_SCRIPT_URL }} --output build-grav.sh
- name: Grav Builder
run: |
bash ./build-grav.sh
- name: Upload packages to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ env.PACKAGE_VERSION }}
file: ./grav-dist/*.zip
overwrite: true
file_glob: true
slack:
permissions:
actions: read # to list jobs for workflow run (technote-space/workflow-conclusion-action)
name: Slack
needs: build
runs-on: ubuntu-latest
if: always()
steps:
- uses: technote-space/workflow-conclusion-action@v2
- uses: 8398a7/action-slack@v3
with:
status: failure
fields: repo,message,author,action
icon_emoji: ':octocat:'
author_name: 'Github Action Build'
text: '🚚 Automated Build Failure'
env:
GITHUB_TOKEN: ${{ secrets.GLOBAL_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: env.WORKFLOW_CONCLUSION == 'failure'

View File

@ -1,76 +0,0 @@
name: PHP Tests
on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
unit-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
php: [8.3, 8.2, 8.1, 8.0, 7.4, 7.3]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: opcache, gd
tools: composer:v2
coverage: none
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Update composer
# run: composer update
#
# - name: Validate composer.json and composer.lock
# run: composer validate
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run test suite
run: vendor/bin/codecept run
# slack:
# name: Slack
# needs: unit-tests
# runs-on: ubuntu-latest
# if: always()
# steps:
# - uses: technote-space/workflow-conclusion-action@v2
# - uses: 8398a7/action-slack@v3
# with:
# status: failure
# fields: repo,message,author,action
# icon_emoji: ':octocat:'
# author_name: 'Github Action Tests'
# text: '💥 Automated Test Failure'
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# if: env.WORKFLOW_CONCLUSION == 'failure'

View File

@ -1,48 +0,0 @@
name: Trigger Skeletons Build
on:
workflow_dispatch:
inputs:
version:
description: 'Which Grav release to use'
required: true
default: 'latest'
admin:
description: 'Create also a package with Admin'
required: true
default: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
build:
runs-on: ubuntu-latest
env:
WORKFLOW: "build-skeleton.yml"
AUTH: ":${{secrets.GLOBAL_TOKEN}}"
steps:
- uses: actions/checkout@v2
- name: Make it rain ☔️
run: |
SKELETONS=`curl -s "${{secrets.SKELETONS_JSON_LIST}}"`
echo "$SKELETONS" | jq -cr '.[]' | while read SKELETON; do
KEY=$(echo "$SKELETON" | jq -cr 'keys[0]')
VERSION=$(echo "$SKELETON" | jq -cr '.[]')
URL="https://api.github.com/repos/${KEY}/actions/workflows/${WORKFLOW}/dispatches"
curl -X POST \
-u "${AUTH}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
-sS \
${URL} \
--data '{ "ref": "develop",
"inputs": {
"tag": "'"$VERSION"'",
"version": "'"$INPUT_VERSION"'",
"admin": "'"$INPUT_ADMIN"'"
}
}' > /dev/null
echo "Dispatched Worfklow for ${KEY}@$VERSION"
done

View File

@ -1,3 +1,29 @@
# v1.7.46
## 05/15/2024
1. [](#improved)
* Better handling of external protocols in `Utils::url()` such as `mailto:`, `tel:`, etc.
* Handle `GRAV_ROOT` or `GRAV_WEBROOT` when `/` [#3667](https://github.com/getgrav/grav/pull/3667)
1. [](#bugfix)
* Fixes for multi-lang taxonomy when reinitializing the languages (e.g. LangSwitcher plugin)
* Ensure the full filepath is checked for invalid filename in `MediaUploadTrait::checkFileMetadata()`
* Fixed a bug in the `on_events` REGEX pattern of `Security::detectXss()` as it was not matching correctly.
* Fixed an issue where `read_file()` Twig function could be used nefariously in content [#GHSA-f8v5-jmfh-pr69](https://github.com/getgrav/grav/security/advisories/GHSA-f8v5-jmfh-pr69)
# v1.7.45
## 03/18/2024
1. [](#new)
* Added new Image trait for `decoding` attribute [#3796](https://github.com/getgrav/grav/pull/3796)
1. [](#bugfix)
* Fixed some multibyte issues in Inflector class [#732](https://github.com/getgrav/grav/issues/732)
* Fallback to page modified date if Page date provided is invalid and can't be parsed [getgrav/grav-plugin-admin#2394](https://github.com/getgrav/grav-plugin-admin/issues/2394)
* Fixed a path traversal vulnerability with file uploads [#GHSA-m7hx-hw6h-mqmc](https://github.com/getgrav/grav/security/advisories/GHSA-m7hx-hw6h-mqmc)
* Fixed a security issue with insecure Twig functions be processed [#GHSA-2m7x-c7px-hp58](https://github.com/getgrav/grav/security/advisories/GHSA-2m7x-c7px-hp58) [#GHSA-r6vw-8v8r-pmp4](https://github.com/getgrav/grav/security/advisories/GHSA-r6vw-8v8r-pmp4) [#GHSA-qfv4-q44r-g7rv](https://github.com/getgrav/grav/security/advisories/GHSA-qfv4-q44r-g7rv) [#GHSA-c9gp-64c4-2rrh](https://github.com/getgrav/grav/security/advisories/GHSA-c9gp-64c4-2rrh)
1. [](#improved)
* Updated composer packages
* Updated `bin/composer.phar` to latest `2.7.2`
# v1.7.44
## 01/05/2024
@ -103,6 +129,7 @@
1. [](#improved)
* Removed outdated `xcache` setting [#3615](https://github.com/getgrav/grav/pull/3615)
* Updated `robots.txt` [#3625](https://github.com/getgrav/grav/pull/3625)
* Handle the situation when GRAV_ROOT or GRAV_WEBROOT are `/` [#3625](https://github.com/getgrav/grav/pull/3667)
1. [](#bugfix)
* Fixed `force_ssl` redirect in case of undefined hostname [#3702](https://github.com/getgrav/grav/pull/3702)
* Fixed an issue with duplicate identical page paths

View File

@ -7,22 +7,31 @@ We are focusing our security updates on the following versions
| Version | Supported |
| ------- | ------------------ |
| 1.7.x | :white_check_mark: |
| 1.6.x | :warning: |
| 1.6.x | :x: |
| < 1.6 | :x: |
## :pushpin: Note on Security Severity
> NOTE: Please use the following guidlines when selecting a **Severity**. Submitted advisories that are marked **High** or **Critical** that don't meet the guidelines below will be cliosed.
* **CRITICAL** - no account required, can modify content, or run malicious code or nefarious activity without any access.
* **HIGH** - publisher level account able to run malicious code or nefarious activity, or other high level security things.
* **MODERATE** - admin level account able to run malicious code or do nefarious things. other moderate security things.
* **LOW** - super admin level account able to run malicious code or do nefarious things. other minor security things.
## :warning: Versions
Versions with :warning: will be supported for security issues, however you won't be able to update to them, you will need to manually update through the [`direct-install` command](https://learn.getgrav.org/17/admin-panel/tools).
If you cannot update to the latest stable version available because, for example, your server does not meet the minimum PHP requirements, you can manually install a previous version by downloading the package from our Releases directory (https://github.com/getgrav/grav/releases).
## Reporting a Vulnerability
## :pencil: Reporting a Vulnerability
Please contact security@getgrav.org with a detailed explanation of the security issue found. If it appears to be a legitimate issues, please submit an **advisory via GitHub Security**: https://github.com/getgrav/grav/security/advisories
>> NOTE: Please do not use 3rd party security issue reporting services, we like to keep everything in the GitHub ecosystem for easier manageability.
> NOTE: Please do not use 3rd party security issue reporting services, we like to keep everything in the GitHub ecosystem for easier manageability.
## Bug Bounties
## :bug: Bug Bounties
We do greatly appreciate your efforts to improve Grav, but unfortunately because we are a small open source project, we **do not have the resources to offer bounties** for security issues found.

Binary file not shown.

357
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1300,6 +1300,17 @@ form:
auto: Auto
lazy: Lazy
eager: Eager
images.defaults.decoding:
type: select
size: small
label: PLUGIN_ADMIN.IMAGES_DECODING
help: PLUGIN_ADMIN.IMAGES_DECODING_HELP
highlight: auto
options:
auto: Auto
sync: Sync
async: Async
images.seofriendly:
type: toggle

View File

@ -168,6 +168,7 @@ images:
retina_scale: 1 # scale to adjust auto-sizes for better handling of HiDPI resolutions
defaults:
loading: auto # Let browser pick [auto|lazy|eager]
decoding: auto # Let browser pick [auto|sync|async]
watermark:
image: 'system://images/watermark.png' # Path to a watermark image
position_y: 'center' # top|center|bottom

View File

@ -9,7 +9,7 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '1.7.44');
define('GRAV_VERSION', '1.7.46');
define('GRAV_SCHEMA', '1.7.0_2020-11-20_1');
define('GRAV_TESTING', false);
@ -26,12 +26,12 @@ if (!defined('DS')) {
// Absolute path to Grav root. This is where Grav is installed into.
if (!defined('GRAV_ROOT')) {
$path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, getenv('GRAV_ROOT') ?: getcwd()), DS);
define('GRAV_ROOT', $path);
define('GRAV_ROOT', $path ?: DS);
}
// Absolute path to Grav webroot. This is the path where your site is located in.
if (!defined('GRAV_WEBROOT')) {
$path = rtrim(getenv('GRAV_WEBROOT') ?: GRAV_ROOT, DS);
define('GRAV_WEBROOT', $path);
define('GRAV_WEBROOT', $path ?: DS);
}
// Relative path to user folder. This path needs to be located under GRAV_WEBROOT.
if (!defined('GRAV_USER_PATH')) {

View File

@ -104,6 +104,7 @@ GRAV:
VALIDATION_FAIL: '<b>Провера неуспела:</b>'
INVALID_INPUT: 'Неисправан унос у'
MISSING_REQUIRED_FIELD: 'Недостаје обавезн поље:'
XSS_ISSUES: "Потенцијална грешка у XSS-у детектована у пољу '%s' "
MONTHS_OF_THE_YEAR:
- 'Јануар'
- 'Фебруар'
@ -125,6 +126,8 @@ GRAV:
- 'Петак'
- 'Субота'
- 'Недеља'
YES: "Да"
NO: "Не"
CRON:
EVERY: сваки
EVERY_HOUR: сваки сат

View File

@ -218,7 +218,7 @@ class Backups
if ($locator->isStream($backup_root)) {
$backup_root = $locator->findResource($backup_root);
} else {
$backup_root = rtrim(GRAV_ROOT . $backup_root, '/');
$backup_root = rtrim(GRAV_ROOT . $backup_root, DS) ?: DS;
}
if (!$backup_root || !file_exists($backup_root)) {

View File

@ -161,9 +161,15 @@ class Inflector
*/
public static function titleize($word, $uppercase = '')
{
$uppercase = $uppercase === 'first' ? 'ucfirst' : 'ucwords';
$humanize_underscorize = static::humanize(static::underscorize($word));
if ($uppercase === 'first') {
$firstLetter = mb_strtoupper(mb_substr($humanize_underscorize, 0, 1, "UTF-8"), "UTF-8");
return $firstLetter . mb_substr($humanize_underscorize, 1, mb_strlen($humanize_underscorize, "UTF-8"), "UTF-8");
} else {
return mb_convert_case($humanize_underscorize, MB_CASE_TITLE, 'UTF-8');
}
return $uppercase(static::humanize(static::underscorize($word)));
}
/**
@ -180,7 +186,7 @@ class Inflector
*/
public static function camelize($word)
{
return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
return str_replace(' ', '', ucwords(preg_replace('/[^\p{L}^0-9]+/', ' ', $word)));
}
/**
@ -198,7 +204,7 @@ class Inflector
{
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word);
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1);
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '_', $regex2);
$regex3 = preg_replace('/[^\p{L}^0-9]+/u', '_', $regex2);
return strtolower($regex3);
}
@ -219,7 +225,7 @@ class Inflector
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
$regex2 = preg_replace('/([a-z])([A-Z])/', '\1-\2', $regex1);
$regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2);
$regex4 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex3);
$regex4 = preg_replace('/[^\p{L}^0-9]+/', '-', $regex3);
$regex4 = trim($regex4, '-');

View File

@ -0,0 +1,40 @@
<?php
/**
* @package Grav\Common\Media
* @author Pedro Moreno https://github.com/pmoreno-rodriguez
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Media\Traits;
use Grav\Common\Grav;
/**
* Trait ImageDecodingTrait
* @package Grav\Common\Media\Traits
*/
trait ImageDecodingTrait
{
/**
* Allows to set the decoding attribute from Markdown or Twig
*
* @param string|null $value
* @return $this
*/
public function decoding($value = null)
{
if (null === $value) {
$value = Grav::instance()['config']->get('system.images.defaults.decoding', 'auto');
}
// Validate the provided value (similar to loading)
if ($value !== null && $value !== 'auto') {
$this->attributes['decoding'] = $value;
}
return $this;
}
}

View File

@ -156,7 +156,7 @@ trait MediaUploadTrait
$filepath = $folder . $filename;
// Check if the filename is allowed.
if (!Utils::checkFilename($filename)) {
if (!Utils::checkFilename($filepath)) {
throw new RuntimeException(
sprintf($this->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_UPLOAD'), $filepath, $this->translate('PLUGIN_ADMIN.BAD_FILENAME'))
);

View File

@ -15,6 +15,7 @@ use Grav\Common\Media\Interfaces\ImageManipulateInterface;
use Grav\Common\Media\Interfaces\ImageMediaInterface;
use Grav\Common\Media\Interfaces\MediaLinkInterface;
use Grav\Common\Media\Traits\ImageLoadingTrait;
use Grav\Common\Media\Traits\ImageDecodingTrait;
use Grav\Common\Media\Traits\ImageMediaTrait;
use Grav\Common\Utils;
use Gregwar\Image\Image;
@ -30,6 +31,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
{
use ImageMediaTrait;
use ImageLoadingTrait;
use ImageDecodingTrait;
/**
* @var mixed|string

View File

@ -225,7 +225,7 @@ class Security
// Set the patterns we'll test against
$patterns = [
// Match any attribute starting with "on" or xmlns
'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])([\s\/]on|\sxmlns)[a-z].*=>?#iUu',
'on_events' => '#(<[^>]+[a-z\x00-\x20\"\'\/])(on[a-z]+|xmlns)\s*=[\s|\'\"].*[\s|\'\"]>#iUu',
// Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols
'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . ')(:|\&\#58)\S.*?#iUu',
@ -263,4 +263,25 @@ class Security
'invalid_protocols' => array_map('trim', $config->get('security.xss_invalid_protocols')),
];
}
public static function cleanDangerousTwig(string $string): string
{
if ($string === '') {
return $string;
}
$bad_twig = [
'twig_array_map',
'twig_array_filter',
'call_user_func',
'registerUndefinedFunctionCallback',
'undefined_functions',
'twig.getFunction',
'core.setEscaper',
'twig.safe_functions',
'read_file',
];
$string = preg_replace('/(({{\s*|{%\s*)[^}]*?(' . implode('|', $bad_twig) . ')[^}]*?(\s*}}|\s*%}))/i', '{# $1 #}', $string);
return $string;
}
}

View File

@ -10,6 +10,7 @@
namespace Grav\Common;
use Grav\Common\Config\Config;
use Grav\Common\Language\Language;
use Grav\Common\Page\Collection;
use Grav\Common\Page\Interfaces\PageInterface;
use function is_string;
@ -37,6 +38,8 @@ class Taxonomy
protected $taxonomy_map;
/** @var Grav */
protected $grav;
/** @var Language */
protected $language;
/**
* Constructor that resets the map
@ -45,8 +48,9 @@ class Taxonomy
*/
public function __construct(Grav $grav)
{
$this->taxonomy_map = [];
$this->grav = $grav;
$this->language = $grav['language'];
$this->taxonomy_map[$this->language->getLanguage()] = [];
}
/**
@ -107,7 +111,8 @@ class Taxonomy
if (!empty($key)) {
$taxonomy .= $key;
}
$this->taxonomy_map[$taxonomy][(string) $value][$page->path()] = ['slug' => $page->slug()];
$active = $this->language->getLanguage();
$this->taxonomy_map[$active][$taxonomy][(string) $value][$page->path()] = ['slug' => $page->slug()];
}
}
@ -123,14 +128,11 @@ class Taxonomy
{
$matches = [];
$results = [];
$active = $this->language->getLanguage();
foreach ((array)$taxonomies as $taxonomy => $items) {
foreach ((array)$items as $item) {
if (isset($this->taxonomy_map[$taxonomy][$item])) {
$matches[] = $this->taxonomy_map[$taxonomy][$item];
} else {
$matches[] = [];
}
$matches[] = $this->taxonomy_map[$active][$taxonomy][$item] ?? [];
}
}
@ -156,11 +158,13 @@ class Taxonomy
*/
public function taxonomy($var = null)
{
$active = $this->language->getLanguage();
if ($var) {
$this->taxonomy_map = $var;
$this->taxonomy_map[$active] = $var;
}
return $this->taxonomy_map;
return $this->taxonomy_map[$active] ?? [];
}
/**
@ -171,6 +175,7 @@ class Taxonomy
*/
public function getTaxonomyItemKeys($taxonomy)
{
return isset($this->taxonomy_map[$taxonomy]) ? array_keys($this->taxonomy_map[$taxonomy]) : [];
$active = $this->language->getLanguage();
return isset($this->taxonomy_map[$active][$taxonomy]) ? array_keys($this->taxonomy_map[$active][$taxonomy]) : [];
}
}

View File

@ -16,6 +16,7 @@ use Grav\Common\Language\Language;
use Grav\Common\Language\LanguageCodes;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Page\Pages;
use Grav\Common\Security;
use Grav\Common\Twig\Exception\TwigException;
use Grav\Common\Twig\Extension\FilesystemExtension;
use Grav\Common\Twig\Extension\GravExtension;
@ -319,6 +320,7 @@ class Twig
public function processPage(PageInterface $item, $content = null)
{
$content = $content ?? $item->content();
$content = Security::cleanDangerousTwig($content);
// override the twig header vars for local resolution
$this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
@ -392,6 +394,8 @@ class Twig
$this->grav->fireEvent('onTwigStringVariables');
$vars += $this->twig_vars;
$string = Security::cleanDangerousTwig($string);
$name = '@Var:' . $string;
$this->setTemplate($name, $string);
@ -418,7 +422,7 @@ class Twig
try {
$grav = $this->grav;
// set the page now its been processed
// set the page now it's been processed
$grav->fireEvent('onTwigSiteVariables');
/** @var Pages $pages */
@ -427,13 +431,15 @@ class Twig
/** @var PageInterface $page */
$page = $grav['page'];
$content = Security::cleanDangerousTwig($page->content());
$twig_vars = $this->twig_vars;
$twig_vars['theme'] = $grav['config']->get('theme');
$twig_vars['pages'] = $pages->root();
$twig_vars['page'] = $page;
$twig_vars['header'] = $page->header();
$twig_vars['media'] = $page->media();
$twig_vars['content'] = $page->content();
$twig_vars['content'] = $content;
// determine if params are set, if so disable twig cache
$params = $grav['uri']->params(null, true);
@ -568,4 +574,5 @@ class Twig
$this->autoescape = (bool) $state;
}
}

View File

@ -206,7 +206,7 @@ class Uri
$uri = $language->setActiveFromUri($uri);
// split the URL and params (and make sure that the path isn't seen as domain)
$bits = parse_url('http://domain.com' . $uri);
$bits = static::parseUrl('http://domain.com' . $uri);
//process fragment
if (isset($bits['fragment'])) {
@ -265,6 +265,7 @@ class Uri
return $this->paths;
}
/**
* Return route to the current URI. By default route doesn't include base path.
*
@ -742,7 +743,7 @@ class Uri
*/
public static function isExternal($url)
{
return (0 === strpos($url, 'http://') || 0 === strpos($url, 'https://') || 0 === strpos($url, '//'));
return (0 === strpos($url, 'http://') || 0 === strpos($url, 'https://') || 0 === strpos($url, '//') || 0 === strpos($url, 'mailto:') || 0 === strpos($url, 'tel:') || 0 === strpos($url, 'ftp://') || 0 === strpos($url, 'ftps://') || 0 === strpos($url, 'news:') || 0 === strpos($url, 'irc:') || 0 === strpos($url, 'gopher:') || 0 === strpos($url, 'nntp:') || 0 === strpos($url, 'feed:') || 0 === strpos($url, 'cvs:') || 0 === strpos($url, 'ssh:') || 0 === strpos($url, 'git:') || 0 === strpos($url, 'svn:') || 0 === strpos($url, 'hg:'));
}
/**
@ -954,9 +955,7 @@ class Uri
$grav = Grav::instance();
// Remove extra slash from streams, parse_url() doesn't like it.
if ($pos = strpos($url, ':///')) {
$url = substr_replace($url, '://', $pos, 4);
}
$url = preg_replace('/([^:])(\/{2,})/', '$1/', $url);
$encodedUrl = preg_replace_callback(
'%[^:/@?&=#]+%usD',

View File

@ -989,6 +989,8 @@ abstract class Utils
|| strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename
// Filename should not start or end with dot or space.
|| trim($filename, '. ') !== $filename
// Filename should not contain path traversal
|| str_replace('..', '', $filename) !== $filename
// File extension should not be part of configured dangerous extensions
|| in_array($extension, $dangerous_extensions)
);
@ -1330,7 +1332,11 @@ abstract class Utils
if ($dateformat) {
$datetime = DateTime::createFromFormat($dateformat, $date);
} else {
$datetime = new DateTime($date);
try {
$datetime = new DateTime($date);
} catch (Exception $e) {
$datetime = false;
}
}
// fallback to strtotime() if DateTime approach failed

View File

0
system/src/Twig/DeferredExtension/DeferredNode.php Executable file → Normal file
View File

View File

@ -160,7 +160,7 @@ log:
tag: grav
debugger:
enabled: false
provider: clockwork
provider: debugbar
censored: false
shutdown:
close_connection: true
@ -178,6 +178,7 @@ images:
retina_scale: '1'
defaults:
loading: auto
decoding: auto
watermark:
image: 'system://images/watermark.png'
position_y: center
@ -189,7 +190,7 @@ media:
unsupported_inline_types: null
allowed_fallback_types: null
auto_metadata_exif: false
upload_limit: 2097152
upload_limit: 2147483648
session:
enabled: true
initialize: true

View File

@ -8,13 +8,14 @@
<div class="article-header">
{% if page.parent.title == "Articles" %}
<div class="article-siblings">
{% if not page.isFirst %}
<a href="{{ page.nextSibling.url }}">{{ page.nextSibling.title }}<i class="fa-solid fa-chevron-left"></i> Article suivant</a>
{{ dump(page.parent.collection.prevSibling(page.path)) }}
{% if not page.parent.collection.isFirst(page.path) %}
<a href="{{ page.parent.collection.nextSibling(page.path).url }}"><i class="fa-solid fa-chevron-left"></i> Article suivant</a>
{% else %}
<div></div>
{% endif %}
{% if not page.isLast %}
<a href="{{ page.prevSibling.url }}">{{ page.prevSibling.title }} Article précédent <i class="fa-solid fa-chevron-right"></i></a>
{% if not page.parent.collection.isLast(page.path) %}
<a href="{{ page.parent.collection.prevSibling(page.path).url }}">Article précédent <i class="fa-solid fa-chevron-right"></i></a>
{% endif %}
</div>
{% endif %}

View File

@ -3,7 +3,7 @@
{{ page.find('/a-propos').summary|raw }}
</div>
<div id="about-hidden">
{{ page.find('/a-propos').content|slice(page.summary|length, page.content|length)|markdown(false) }}
{{ page.find('/a-propos').content|slice(page.find('/a-propos').summary|length, page.find('/a-propos').content|length)|markdown(false) }}
</div>
<div id="about-arrow">
<div></div>

View File

@ -1,5 +1,5 @@
<main>
{% for article in page.find('/articles').children.published.order('date', 'desc') %}
{% for article in page.find('/articles').collection %}
<div class="article-card">
<a href="{{ article.url }}" data-barba="link">
<div class="img-cover">