diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f5b590ba..382e8b098 100644 --- a/CHANGELOG.md +++ b/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 diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index b38d3289a..dcb438587 100755 --- a/app/Controllers/configureController.php +++ b/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') . ' · '); diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php index 13330db23..cfb150ab1 100644 --- a/app/Models/DatabaseDAO.php +++ b/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; } diff --git a/app/Models/DatabaseDAOPGSQL.php b/app/Models/DatabaseDAOPGSQL.php index 7ca7799ae..75ff8be7b 100644 --- a/app/Models/DatabaseDAOPGSQL.php +++ b/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; } diff --git a/app/Models/DatabaseDAOSQLite.php b/app/Models/DatabaseDAOSQLite.php index 413e7ee09..eaa2d37a7 100644 --- a/app/Models/DatabaseDAOSQLite.php +++ b/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; } } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 99e99f463..d149cfd8b 100644 --- a/app/Models/EntryDAO.php +++ b/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()) { diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml index 1267f747c..e74630b5a 100644 --- a/app/layout/aside_configure.phtml +++ b/app/layout/aside_configure.phtml @@ -9,8 +9,8 @@
  • -
  • - +
  • +
  • diff --git a/app/layout/header.phtml b/app/layout/header.phtml index 3f7bd80e3..7603cf2e5 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -61,7 +61,7 @@ if (FreshRSS_Auth::accessNeedsAction()) {
  • -
  • +
  • diff --git a/app/views/configure/sharing.phtml b/app/views/configure/integration.phtml similarity index 100% rename from app/views/configure/sharing.phtml rename to app/views/configure/integration.phtml diff --git a/cli/_cli.php b/cli/_cli.php index dec244bc3..4e1188428 100644 --- a/cli/_cli.php +++ b/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; } diff --git a/cli/do-install.php b/cli/do-install.php index fa6bac8c8..16ac833ea 100755 --- a/cli/do-install.php +++ b/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 { diff --git a/cli/user-info.php b/cli/user-info.php index aa4db7c2f..f56bd9aa5 100755 --- a/cli/user-info.php +++ b/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); diff --git a/constants.php b/constants.php index 1f9a0f01c..e8cabb157 100644 --- a/constants.php +++ b/constants.php @@ -2,7 +2,7 @@ //NB: Do not edit; use ./constants.local.php instead. // -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/'); diff --git a/docs/en/users/07_Frequently_Asked_Questions.md b/docs/en/users/07_Frequently_Asked_Questions.md index fd3db4bea..e63c4c2c7 100644 --- a/docs/en/users/07_Frequently_Asked_Questions.md +++ b/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_ diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index 6eb4881dc..ed88d58d1 100644 --- a/lib/Minz/ModelPdo.php +++ b/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; diff --git a/lib/lib_rss.php b/lib/lib_rss.php index f4b5c68e6..137c7f2d5 100644 --- a/lib/lib_rss.php +++ b/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);