Просмотр исходного кода

Merge pull request #2655 from FreshRSS/dev

FreshRSS 1.15.2
Alexandre Alapetite 6 лет назад
Родитель
Сommit
09c088c62e

+ 12 - 0
CHANGELOG.md

@@ -1,5 +1,17 @@
 # FreshRSS changelog
 
+## 2019-11-12 FreshRSS 1.15.2
+
+* Bug fixing (regressions from 1.15.x)
+	* Fix CLI failing due to new test against empty usernames [#2644](https://github.com/FreshRSS/FreshRSS/issues/2644)
+	* Fix CLI install for SQLite [#2648](https://github.com/FreshRSS/FreshRSS/pull/2648)
+	* Fix database optimize action for MySQL/MariaDB [#2647](https://github.com/FreshRSS/FreshRSS/pull/2647)
+* Bug fixing (misc.)
+	* Sanitize Unicode UTF-8 before insertion of entries, especially needed for PostgreSQL [#2645](https://github.com/FreshRSS/FreshRSS/issues/2645)
+* Misc.
+	* Rename *sharing* action to avoid erroneous blocking by some ad-blockers [#2509](https://github.com/FreshRSS/FreshRSS/issues/2509)
+
+
 ## 2019-11-06 FreshRSS 1.15.1
 
 * Features

+ 7 - 4
app/Controllers/configureController.php

@@ -134,13 +134,16 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 	}
 
 	/**
-	 * This action handles the sharing configuration page.
+	 * This action handles the integration configuration page.
 	 *
-	 * It displays the sharing configuration page.
+	 * It displays the integration configuration page.
 	 * If this action is reached through a POST request, it stores all
 	 * configuration values then sends a notification to the user.
+	 *
+	 * Before v1.16, we used sharing instead of integration. This has
+	 * some unwanted behavior when the end-user was using an ad-blocker.
 	 */
-	public function sharingAction() {
+	public function integrationAction() {
 		if (Minz_Request::isPost()) {
 			$params = Minz_Request::fetchPOST();
 			FreshRSS_Context::$user_conf->sharing = $params['share'];
@@ -148,7 +151,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 			invalidateHttpCache();
 
 			Minz_Request::good(_t('feedback.conf.updated'),
-			                   array('c' => 'configure', 'a' => 'sharing'));
+			                   array('c' => 'configure', 'a' => 'integration'));
 		}
 
 		Minz_View::prependTitle(_t('conf.sharing.title') . ' · ');

+ 6 - 1
app/Models/DatabaseDAO.php

@@ -156,7 +156,12 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
 
 		foreach ($tables as $table) {
 			$sql = 'OPTIMIZE TABLE `_' . $table . '`';	//MySQL
-			$ok &= ($this->pdo->exec($sql) !== false);
+			$stm = $this->pdo->query($sql);
+			if ($stm == false || $stm->fetchAll(PDO::FETCH_ASSOC) === false) {
+				$ok = false;
+				$info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo();
+				Minz_Log::warning(__METHOD__ . ' error: ' . $sql . ' : ' . json_encode($info));
+			}
 		}
 		return $ok;
 	}

+ 5 - 1
app/Models/DatabaseDAOPGSQL.php

@@ -79,7 +79,11 @@ class FreshRSS_DatabaseDAOPGSQL extends FreshRSS_DatabaseDAOSQLite {
 
 		foreach ($tables as $table) {
 			$sql = 'VACUUM `_' . $table . '`';
-			$ok &= ($this->pdo->exec($sql) !== false);
+			if ($this->pdo->exec($sql) === false) {
+				$ok = false;
+				$info = $this->pdo->errorInfo();
+				Minz_Log::warning(__METHOD__ . ' error: ' . $sql . ' : ' . json_encode($info));
+			}
 		}
 		return $ok;
 	}

+ 6 - 1
app/Models/DatabaseDAOSQLite.php

@@ -66,6 +66,11 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO {
 	}
 
 	public function optimize() {
-		return $this->pdo->exec('VACUUM') !== false;
+		$ok = $this->pdo->exec('VACUUM') !== false;
+		if (!$ok) {
+			$info = $this->pdo->errorInfo();
+			Minz_Log::warning(__METHOD__ . ' error: ' . $sql . ' : ' . json_encode($info));
+		}
+		return $ok;
 	}
 }

+ 9 - 0
app/Models/EntryDAO.php

@@ -99,9 +99,12 @@ SQL;
 			$valuesTmp['guid'] = safe_ascii($valuesTmp['guid']);
 			$this->addEntryPrepared->bindParam(':guid', $valuesTmp['guid']);
 			$valuesTmp['title'] = mb_strcut($valuesTmp['title'], 0, 255, 'UTF-8');
+			$valuesTmp['title'] = safe_utf8($valuesTmp['title']);
 			$this->addEntryPrepared->bindParam(':title', $valuesTmp['title']);
 			$valuesTmp['author'] = mb_strcut($valuesTmp['author'], 0, 255, 'UTF-8');
+			$valuesTmp['author'] = safe_utf8($valuesTmp['author']);
 			$this->addEntryPrepared->bindParam(':author', $valuesTmp['author']);
+			$valuesTmp['content'] = safe_utf8($valuesTmp['content']);
 			$this->addEntryPrepared->bindParam(':content', $valuesTmp['content']);
 			$valuesTmp['link'] = substr($valuesTmp['link'], 0, 1023);
 			$valuesTmp['link'] = safe_ascii($valuesTmp['link']);
@@ -117,6 +120,7 @@ SQL;
 			$this->addEntryPrepared->bindParam(':is_favorite', $valuesTmp['is_favorite'], PDO::PARAM_INT);
 			$this->addEntryPrepared->bindParam(':id_feed', $valuesTmp['id_feed'], PDO::PARAM_INT);
 			$valuesTmp['tags'] = mb_strcut($valuesTmp['tags'], 0, 1023, 'UTF-8');
+			$valuesTmp['tags'] = safe_utf8($valuesTmp['tags']);
 			$this->addEntryPrepared->bindParam(':tags', $valuesTmp['tags']);
 
 			if ($this->hasNativeHex()) {
@@ -186,11 +190,15 @@ SQL;
 		}
 
 		$valuesTmp['guid'] = substr($valuesTmp['guid'], 0, 760);
+		$valuesTmp['guid'] = safe_ascii($valuesTmp['guid']);
 		$this->updateEntryPrepared->bindParam(':guid', $valuesTmp['guid']);
 		$valuesTmp['title'] = mb_strcut($valuesTmp['title'], 0, 255, 'UTF-8');
+		$valuesTmp['title'] = safe_utf8($valuesTmp['title']);
 		$this->updateEntryPrepared->bindParam(':title', $valuesTmp['title']);
 		$valuesTmp['author'] = mb_strcut($valuesTmp['author'], 0, 255, 'UTF-8');
+		$valuesTmp['author'] = safe_utf8($valuesTmp['author']);
 		$this->updateEntryPrepared->bindParam(':author', $valuesTmp['author']);
+		$valuesTmp['content'] = safe_utf8($valuesTmp['content']);
 		$this->updateEntryPrepared->bindParam(':content', $valuesTmp['content']);
 		$valuesTmp['link'] = substr($valuesTmp['link'], 0, 1023);
 		$valuesTmp['link'] = safe_ascii($valuesTmp['link']);
@@ -203,6 +211,7 @@ SQL;
 		}
 		$this->updateEntryPrepared->bindParam(':id_feed', $valuesTmp['id_feed'], PDO::PARAM_INT);
 		$valuesTmp['tags'] = mb_strcut($valuesTmp['tags'], 0, 1023, 'UTF-8');
+		$valuesTmp['tags'] = safe_utf8($valuesTmp['tags']);
 		$this->updateEntryPrepared->bindParam(':tags', $valuesTmp['tags']);
 
 		if ($this->hasNativeHex()) {

+ 2 - 2
app/layout/aside_configure.phtml

@@ -9,8 +9,8 @@
 	<li class="item<?= Minz_Request::actionName() === 'archiving' ? ' active' : '' ?>">
 		<a href="<?= _url('configure', 'archiving') ?>"><?= _t('gen.menu.archiving') ?></a>
 	</li>
-	<li class="item<?= Minz_Request::actionName() === 'sharing' ? ' active' : '' ?>">
-		<a href="<?= _url('configure', 'sharing') ?>"><?= _t('gen.menu.sharing') ?></a>
+	<li class="item<?= Minz_Request::actionName() === 'integration' ? ' active' : '' ?>">
+		<a href="<?= _url('configure', 'integration') ?>"><?= _t('gen.menu.sharing') ?></a>
 	</li>
 	<li class="item<?= Minz_Request::actionName() === 'shortcut' ? ' active' : '' ?>">
 		<a href="<?= _url('configure', 'shortcut') ?>"><?= _t('gen.menu.shortcuts') ?></a>

+ 1 - 1
app/layout/header.phtml

@@ -61,7 +61,7 @@ if (FreshRSS_Auth::accessNeedsAction()) {
 				<li class="item"><a href="<?= _url('configure', 'display') ?>"><?= _t('gen.menu.display') ?></a></li>
 				<li class="item"><a href="<?= _url('configure', 'reading') ?>"><?= _t('gen.menu.reading') ?></a></li>
 				<li class="item"><a href="<?= _url('configure', 'archiving') ?>"><?= _t('gen.menu.archiving') ?></a></li>
-				<li class="item"><a href="<?= _url('configure', 'sharing') ?>"><?= _t('gen.menu.sharing') ?></a></li>
+				<li class="item"><a href="<?= _url('configure', 'integration') ?>"><?= _t('gen.menu.sharing') ?></a></li>
 				<li class="item"><a href="<?= _url('configure', 'shortcut') ?>"><?= _t('gen.menu.shortcuts') ?></a></li>
 				<li class="item"><a href="<?= _url('configure', 'queries') ?>"><?= _t('gen.menu.queries') ?></a></li>
 				<li class="item"><a href="<?= _url('user', 'profile') ?>"><?= _t('gen.menu.user_profile') ?></a></li>

+ 0 - 0
app/views/configure/sharing.phtml → app/views/configure/integration.phtml


+ 1 - 1
cli/_cli.php

@@ -37,7 +37,7 @@ function cliInitUser($username) {
 	if (FreshRSS_Context::$user_conf == null) {
 		fail('FreshRSS error: invalid configuration for user: ' . $username . "\n");
 	}
-	new Minz_ModelPdo($username);
+	Minz_Session::_param('currentUser', $username);
 
 	return $username;
 }

+ 1 - 1
cli/do-install.php

@@ -89,7 +89,7 @@ if (function_exists('opcache_reset')) {
 Minz_Configuration::register('system', DATA_PATH . '/config.php', FRESHRSS_PATH . '/config.default.php');
 FreshRSS_Context::$system_conf = Minz_Configuration::get('system');
 
-Minz_Session::_param('currentUser', $config['default_user']);
+Minz_Session::_param('currentUser', '_');	//Default user
 
 $ok = false;
 try {

+ 1 - 1
cli/user-info.php

@@ -43,7 +43,7 @@ if (array_key_exists('header', $options)) {
 foreach ($users as $username) {
 	$username = cliInitUser($username);
 
-	$catDAO = FreshRSS_Factory::createCategoryDao();
+	$catDAO = FreshRSS_Factory::createCategoryDao($username);
 	$feedDAO = FreshRSS_Factory::createFeedDao($username);
 	$entryDAO = FreshRSS_Factory::createEntryDao($username);
 	$tagDAO = FreshRSS_Factory::createTagDao($username);

+ 1 - 1
constants.php

@@ -2,7 +2,7 @@
 //NB: Do not edit; use ./constants.local.php instead.
 
 //<Not customisable>
-define('FRESHRSS_VERSION', '1.15.1');
+define('FRESHRSS_VERSION', '1.15.2');
 define('FRESHRSS_WEBSITE', 'https://freshrss.org');
 define('FRESHRSS_WIKI', 'https://freshrss.github.io/FreshRSS/');
 

+ 11 - 0
docs/en/users/07_Frequently_Asked_Questions.md

@@ -52,3 +52,14 @@ Some Linux distribution like Fedora or RedHat Enterprise Linux have SELinux syst
 semanage fcontext -a -t httpd_sys_rw_content_t '/usr/share/FreshRSS/data(/.*)?'
 restorecon -Rv /usr/share/FreshRSS/data
 ```
+
+## Why do I have a blank page while trying to configure the sharing options?
+
+The `sharing` word in the URL is a trigger word for some an-blocker rules. Starting at version 1.16, `sharing` has been replaced by `integration` in the faulty URL while keeping the exact same wording through out the application.
+
+If you are using a version prior to 1.16, you can disable your ad-blocker for FreshRSS or you can add a rule to allow the `sharing` page to be accessed.
+
+Examples with _uBlock_:
+
+- Whitelist your FreshRSS instance by adding it in _uBlock > Open the dashboard > Whitelist_.
+- Authorize your FreshRSS instance to call `sharing` configuration page by adding the rule `*sharing,domain=~yourdomain.com` in _uBlock > Open the dashboard > My filters_

+ 3 - 3
lib/Minz/ModelPdo.php

@@ -28,13 +28,13 @@ class Minz_ModelPdo {
 		if ($currentUser === null) {
 			$currentUser = Minz_Session::param('currentUser');
 		}
-		if ($currentUser == '') {
-			throw new Minz_PDOConnectionException('Current user must not be empty!', '', Minz_Exception::ERROR);
-		}
 		if ($currentPdo != null) {
 			$this->pdo = $currentPdo;
 			return;
 		}
+		if ($currentUser == '') {
+			throw new Minz_PDOConnectionException('Current user must not be empty!', '', Minz_Exception::ERROR);
+		}
 		if (self::$usesSharedPdo && self::$sharedPdo != null &&
 			($currentUser == '' || $currentUser === self::$sharedCurrentUser)) {
 			$this->pdo = self::$sharedPdo;

+ 8 - 0
lib/lib_rss.php

@@ -81,6 +81,14 @@ function safe_ascii($text) {
 	return filter_var($text, FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
 }
 
+if (function_exists('mb_convert_encoding')) {
+	function safe_utf8($text) { return mb_convert_encoding($text, 'UTF-8', 'UTF-8'); }
+} elseif (function_exists('iconv')) {
+	function safe_utf8($text) { return iconv('UTF-8', 'UTF-8//IGNORE', $text); }
+} else {
+	function safe_utf8($text) { return $text; }
+}
+
 function escapeToUnicodeAlternative($text, $extended = true) {
 	$text = htmlspecialchars_decode($text, ENT_QUOTES);