From baa928531b55828f9f9e407b13628d20f57b5c7d Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Mon, 20 Nov 2023 22:45:48 +0100 Subject: [PATCH] Asset: let slugs consist only of an explicit set of allowed characters --- controllers/EditAsset.php | 2 +- models/Asset.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/controllers/EditAsset.php b/controllers/EditAsset.php index 43545f0..6937f98 100644 --- a/controllers/EditAsset.php +++ b/controllers/EditAsset.php @@ -63,7 +63,7 @@ class EditAsset extends HTMLController { $date_captured = !empty($_POST['date_captured']) ? new DateTime(str_replace('T', ' ', $_POST['date_captured'])) : null; - $slug = strtr($_POST['slug'], [' ' => '-', '--' => '-', '&' => 'and', '=>' => '', "'" => "", ":"=> "", '\\' => '-']); + $slug = Asset::cleanSlug($_POST['slug']); $asset->setKeyData(htmlspecialchars($_POST['title']), $slug, $date_captured, intval($_POST['priority'])); } diff --git a/models/Asset.php b/models/Asset.php index f880386..5779761 100644 --- a/models/Asset.php +++ b/models/Asset.php @@ -36,6 +36,16 @@ class Asset $this->date_captured = new DateTime($data['date_captured']); } + public static function cleanSlug($slug) + { + // Only alphanumerical chars, underscores and forward slashes are allowed + if (!preg_match_all('~([A-z0-9\/_]+)~', $slug, $allowedTokens, PREG_PATTERN_ORDER)) + throw new UnexpectedValueException('Slug does not make sense.'); + + // Join valid substrings together with hyphens + return implode('-', $allowedTokens[1]); + } + public static function fromId($id_asset, $return_format = 'object') { $row = Registry::get('db')->queryAssoc(' @@ -214,7 +224,7 @@ class Asset $title = $data['title'] ?? $basename; // Same with the slug. - $slug = $data['slug'] ?? sprintf('%s/%s', $preferred_subdir, $basename); + $slug = $data['slug'] ?? self::cleanSlug(sprintf('%s/%s', $preferred_subdir, $basename)); // Detected an image? if (substr($mimetype, 0, 5) == 'image')