From eb70065e0f1da0f0c701cae206211936531384e4 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Wed, 10 Dec 2025 22:51:32 +0100 Subject: [PATCH] Search/Fixup * improve handling of invalid unicode sequences in urls (%xx). Page no longer breaks entirely, just misses the search term as the faulty string gets silently dropped. * don't perform searches if you don't have valid terms to search for --- endpoints/search/search.php | 22 +++++++++++-------- includes/components/pagetemplate.class.php | 2 +- .../response/baseresponse.class.php | 6 ++--- static/js/basic.js | 6 ++++- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/endpoints/search/search.php b/endpoints/search/search.php index 5a134613..4fbe5ec8 100644 --- a/endpoints/search/search.php +++ b/endpoints/search/search.php @@ -62,19 +62,23 @@ class SearchBaseResponse extends TemplateResponse implements ICache $canRedirect = true; $redirectTo = ''; - foreach ($this->searchObj->perform() as $lvData) + + if ($this->searchObj->canPerform()) { - if ($lvData[1] == 'npc' || $lvData[1] == 'object') - $this->addDataLoader('zones'); + foreach ($this->searchObj->perform() as $lvData) + { + if ($lvData[1] == 'npc' || $lvData[1] == 'object') + $this->addDataLoader('zones'); - $this->lvTabs->addListviewTab(new Listview(...$lvData)); + $this->lvTabs->addListviewTab(new Listview(...$lvData)); - // we already have a target > can't have more targets > no redirects - if (($canRedirect && $redirectTo) || count($lvData[0]['data']) > 1) - $canRedirect = false; + // we already have a target > can't have more targets > no redirects + if (($canRedirect && $redirectTo) || count($lvData[0]['data']) > 1) + $canRedirect = false; - if ($canRedirect) // note - we are very lucky that in case of searches $template is identical to the typeString - $redirectTo = '?'.$lvData[1].'='.key($lvData[0]['data']); + if ($canRedirect) // note - we are very lucky that in case of searches $template is identical to the typeString + $redirectTo = '?'.$lvData[1].'='.key($lvData[0]['data']); + } } $this->extendGlobalData($this->searchObj->getJSGlobals()); diff --git a/includes/components/pagetemplate.class.php b/includes/components/pagetemplate.class.php index 5bc172a8..a688114a 100644 --- a/includes/components/pagetemplate.class.php +++ b/includes/components/pagetemplate.class.php @@ -216,7 +216,7 @@ class PageTemplate if (is_string($var) && $this->$var) $var = $this->$var; - return preg_replace('/script\s*\>/i', 'scr"+"ipt>', Util::toJSON($var, $jsonFlags)); + return preg_replace('/script\s*\>/i', 'scr"+"ipt>', Util::toJSON($var, $jsonFlags) ?: "{}"); } private function escHTML(string $var) : string|array diff --git a/includes/components/response/baseresponse.class.php b/includes/components/response/baseresponse.class.php index 7e32969d..0dd10276 100644 --- a/includes/components/response/baseresponse.class.php +++ b/includes/components/response/baseresponse.class.php @@ -456,8 +456,8 @@ trait TrProfilerList abstract class BaseResponse { - protected const PATTERN_TEXT_LINE = '/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Cn}]/ui'; - protected const PATTERN_TEXT_BLOB = '/[\x00-\x09\x0B-\x1F\p{Cf}\p{Co}\p{Cs}\p{Cn}]/ui'; + protected const PATTERN_TEXT_LINE = '/[\p{Cc}\p{Cf}\p{Co}\p{Cs}\p{Cn}]/i'; + protected const PATTERN_TEXT_BLOB = '/[\x00-\x09\x0B-\x1F\p{Cf}\p{Co}\p{Cs}\p{Cn}]/i'; protected static array $sql = []; // debug: sql stats container @@ -638,7 +638,7 @@ abstract class BaseResponse protected static function checkTextLine(string $val) : string { // trim non-printable chars - return preg_replace(self::PATTERN_TEXT_LINE, '', trim(urldecode($val))); + return preg_replace(self::PATTERN_TEXT_LINE, '', trim($val)); } protected static function checkTextBlob(string $val) : string diff --git a/static/js/basic.js b/static/js/basic.js index 05d30daf..35d9ee3e 100644 --- a/static/js/basic.js +++ b/static/js/basic.js @@ -981,7 +981,11 @@ $WH.g_getQueryString = function() { }; $WH.g_parseQueryString = function(str) { - str = decodeURIComponent(str); + // aowow - set to catch invalid unicode escapes (%ff) + // str = decodeURIComponent(str); + try { str = decodeURIComponent(str); } + catch (e) { return {}; } + var words = str.split('&'); var params = {};