aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAlexandre Alapetite <alexandre@alapetite.fr>2024-09-12 11:04:49 +0200
committerGitHub <noreply@github.com>2024-09-12 11:04:49 +0200
commitfd1b5e9343b6fe92b4e5dfbbc2f01ddfcd010af9 (patch)
tree5cc4e7399212d2fdce401465e3590f2275b16c26
parentd1f1e42c2b180f34276d7ddd1a2bfeaf4e59ed05 (diff)
downloadfreshrss-fd1b5e9343b6fe92b4e5dfbbc2f01ddfcd010af9.tar.gz
freshrss-fd1b5e9343b6fe92b4e5dfbbc2f01ddfcd010af9.zip
Fix inversed encoding logic in paramArray (#6800)
* Fix inversed encoding logic in paramArray https://github.com/FreshRSS/FreshRSS/pull/6797#discussion_r1754661634 Also fix the possibility to use `<'&">` in shortcuts, and some minor encoding bugs in user queries * Forgot paramArrayString
-rw-r--r--app/Controllers/configureController.php9
-rw-r--r--app/Models/BooleanSearch.php1
-rw-r--r--app/Models/UserQuery.php2
-rw-r--r--app/views/configure/shortcut.phtml4
-rw-r--r--lib/Minz/Request.php22
-rw-r--r--p/scripts/main.js5
6 files changed, 33 insertions, 10 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index a9304376f..612129b8a 100644
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -202,7 +202,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
$this->view->list_keys = SHORTCUT_KEYS;
if (Minz_Request::isPost()) {
- $shortcuts = Minz_Request::paramArray('shortcuts');
+ $shortcuts = Minz_Request::paramArray('shortcuts', specialchars: true);
if (Minz_Request::paramBoolean('load_default_shortcuts')) {
$default = Minz_Configuration::load(FRESHRSS_PATH . '/config-user.default.php');
$shortcuts = $default['shortcuts'];
@@ -379,12 +379,13 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
$name = _t('conf.query.number', $id + 1);
}
if (!empty($params['get']) && is_string($params['get'])) {
- $queryParams['get'] = htmlspecialchars_decode($params['get'], ENT_QUOTES);
+ $queryParams['get'] = $params['get'];
}
if (!empty($params['order']) && is_string($params['order'])) {
- $queryParams['order'] = htmlspecialchars_decode($params['order'], ENT_QUOTES);
+ $queryParams['order'] = $params['order'];
}
if (!empty($params['search']) && is_string($params['search'])) {
+ // Search must be as plain text to be XML-encoded or URL-encoded depending on the situation
$queryParams['search'] = htmlspecialchars_decode($params['search'], ENT_QUOTES);
}
if (!empty($params['state']) && is_array($params['state'])) {
@@ -398,7 +399,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
$queryParams['url'] = Minz_Url::display(['params' => $queryParams]);
$queryParams['name'] = $name;
if (!empty($params['description']) && is_string($params['description'])) {
- $queryParams['description'] = htmlspecialchars_decode($params['description'], ENT_QUOTES);
+ $queryParams['description'] = $params['description'];
}
if (!empty($params['imageUrl']) && is_string($params['imageUrl'])) {
$queryParams['imageUrl'] = $params['imageUrl'];
diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php
index 88069c461..9e9dec2a2 100644
--- a/app/Models/BooleanSearch.php
+++ b/app/Models/BooleanSearch.php
@@ -402,6 +402,7 @@ class FreshRSS_BooleanSearch {
return $this->getRawInput();
}
+ /** @return string Plain text search query. Must be XML-encoded or URL-encoded depending on the situation */
public function getRawInput(): string {
return $this->raw_input;
}
diff --git a/app/Models/UserQuery.php b/app/Models/UserQuery.php
index dcd17393e..d701b6b44 100644
--- a/app/Models/UserQuery.php
+++ b/app/Models/UserQuery.php
@@ -13,6 +13,7 @@ class FreshRSS_UserQuery {
private string $get = '';
private string $get_name = '';
private string $get_type = '';
+ /** XML-encoded name */
private string $name = '';
private string $order = '';
private FreshRSS_BooleanSearch $search;
@@ -25,6 +26,7 @@ class FreshRSS_UserQuery {
private array $categories;
/** @var array<int,FreshRSS_Tag> $labels */
private array $labels;
+ /** XML-encoded description */
private string $description = '';
private string $imageUrl = '';
diff --git a/app/views/configure/shortcut.phtml b/app/views/configure/shortcut.phtml
index 78b659120..b7930f263 100644
--- a/app/views/configure/shortcut.phtml
+++ b/app/views/configure/shortcut.phtml
@@ -16,7 +16,9 @@
<?php } ?>
</datalist>
- <?php $s = FreshRSS_Context::userConf()->shortcuts; ?>
+ <?php
+ $s = array_map(static fn(string $string) => htmlspecialchars($string, ENT_COMPAT, 'UTF-8'), FreshRSS_Context::userConf()->shortcuts);
+ ?>
<?php if ([] !== $nonStandard = getNonStandardShortcuts($s)): ?>
<p class="alert alert-error">
diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php
index fcece464b..542741d4a 100644
--- a/lib/Minz/Request.php
+++ b/lib/Minz/Request.php
@@ -40,7 +40,7 @@ class Minz_Request {
* Read the URL parameter
* @param string $key Key name
* @param mixed $default default value, if no parameter is given
- * @param bool $specialchars special characters
+ * @param bool $specialchars `true` to return special characters, `false` (default) to XML-encode them
* @return mixed value of the parameter
* @deprecated use typed versions instead
*/
@@ -61,21 +61,27 @@ class Minz_Request {
return isset(self::$params[$key]);
}
- /** @return array<string|int,string|array<string,string|int|bool>> */
+ /**
+ * @param bool $specialchars `true` to return special characters, `false` (default) to XML-encode them
+ * @return array<string|int,string|array<string,string|int|bool>>
+ */
public static function paramArray(string $key, bool $specialchars = false): array {
if (empty(self::$params[$key]) || !is_array(self::$params[$key])) {
return [];
}
- return $specialchars ? Minz_Helper::htmlspecialchars_utf8(self::$params[$key]) : self::$params[$key];
+ return $specialchars ? self::$params[$key] : Minz_Helper::htmlspecialchars_utf8(self::$params[$key]);
}
- /** @return array<string> */
+ /**
+ * @param bool $specialchars `true` to return special characters, `false` (default) to XML-encode them
+ * @return array<string>
+ */
public static function paramArrayString(string $key, bool $specialchars = false): array {
if (empty(self::$params[$key]) || !is_array(self::$params[$key])) {
return [];
}
$result = array_filter(self::$params[$key], 'is_string');
- return $specialchars ? Minz_Helper::htmlspecialchars_utf8($result) : $result;
+ return $specialchars ? $result : Minz_Helper::htmlspecialchars_utf8($result);
}
public static function paramTernary(string $key): ?bool {
@@ -106,6 +112,9 @@ class Minz_Request {
return 0;
}
+ /**
+ * @param bool $specialchars `true` to return special characters, `false` (default) to XML-encode them
+ */
public static function paramStringNull(string $key, bool $specialchars = false): ?string {
if (isset(self::$params[$key])) {
$s = self::$params[$key];
@@ -120,6 +129,9 @@ class Minz_Request {
return null;
}
+ /**
+ * @param bool $specialchars `true` to return special characters, `false` (default) to XML-encode them
+ */
public static function paramString(string $key, bool $specialchars = false): string {
return self::paramStringNull($key, $specialchars) ?? '';
}
diff --git a/p/scripts/main.js b/p/scripts/main.js
index 663bfe74e..1566b38cb 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -908,6 +908,11 @@ function init_column_categories() {
function init_shortcuts() {
Object.keys(context.shortcuts).forEach(function (k) {
context.shortcuts[k] = (context.shortcuts[k] || '').toUpperCase();
+ if (context.shortcuts[k].indexOf('&') >= 0) {
+ // Decode potential HTML entities <'&">
+ const parser = new DOMParser();
+ context.shortcuts[k] = parser.parseFromString(context.shortcuts[k], 'text/html').documentElement.textContent;
+ }
});
document.addEventListener('keydown', ev => {