Przeglądaj źródła

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
Alexandre Alapetite 1 rok temu
rodzic
commit
fd1b5e9343

+ 5 - 4
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'];

+ 1 - 0
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;
 	}

+ 2 - 0
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 = '';
 

+ 3 - 1
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">

+ 17 - 5
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) ?? '';
 	}

+ 5 - 0
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 => {