diff --git a/.travis.yml b/.travis.yml index b24a0c176..5b0ba705a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,12 +30,7 @@ env: matrix: fast_finish: true include: - # PHP 5.3 only runs on Ubuntu 12.04 (precise), not 14.04 (trusty) - - php: "5.3" - dist: precise - # PHP 5.4 & 5.5 only run on Travis in 14.04 (trusty), not 16.04 (xenial) - - php: "5.4" - dist: trusty + # PHP 5.5 only runs on Travis in 14.04 (trusty), not 16.04 (xenial) - php: "5.5" dist: trusty - php: "7.2" diff --git a/README.fr.md b/README.fr.md index d9b145fc4..ceee48f5b 100644 --- a/README.fr.md +++ b/README.fr.md @@ -43,7 +43,7 @@ FreshRSS n’est fourni avec aucune garantie. * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles) * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres) -* PHP 5.3.8+ (PHP 5.4+ recommandé, et PHP 5.5+ pour les performances, ou PHP 7+ pour d’encore meilleures performances) +* PHP 5.5+ (PHP 7+ recommandé pour de meilleures performances) * Requis : [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), et [PDO_MySQL](https://secure.php.net/pdo-mysql) ou [PDO_SQLite](https://secure.php.net/pdo-sqlite) ou [PDO_PGSQL](https://secure.php.net/pdo-pgsql) * Recommandés : [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](https://secure.php.net/intl.idn) (pour les noms de domaines internationalisés), [mbstring](https://secure.php.net/mbstring) (pour le texte Unicode), [iconv](https://secure.php.net/iconv) (pour conversion d’encodages), [ZIP](https://secure.php.net/zip) (pour import/export), [zlib](https://secure.php.net/zlib) (pour les flux compressés) * MySQL 5.5.3+ (recommandé) ou équivalent MariaDB, ou SQLite 3.7.4+, ou PostgreSQL 9.2+ @@ -219,7 +219,6 @@ Tout client supportant une API de type Fever ; Sélection : * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](https://github.com/phpquery/phpquery) * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198) -* [password_compat](https://github.com/ircmaxell/password_compat) diff --git a/README.md b/README.md index e1660a9d1..6123ae903 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ FreshRSS comes with absolutely no warranty. * Light server running Linux or Windows * It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles) * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others) -* PHP 5.3.8+ (PHP 5.4+ recommended, and PHP 5.5+ for performance, or PHP 7 for even higher performance) +* PHP 5.5+ (PHP 7+ recommended for higher performance) * Required extensions: [cURL](https://secure.php.net/curl), [DOM](https://secure.php.net/dom), [XML](https://secure.php.net/xml), [session](https://secure.php.net/session), [ctype](https://secure.php.net/ctype), and [PDO_MySQL](https://secure.php.net/pdo-mysql) or [PDO_SQLite](https://secure.php.net/pdo-sqlite) or [PDO_PGSQL](https://secure.php.net/pdo-pgsql) * Recommended extensions: [JSON](https://secure.php.net/json), [GMP](https://secure.php.net/gmp) (for API access on 32-bit platforms), [IDN](https://secure.php.net/intl.idn) (for Internationalized Domain Names), [mbstring](https://secure.php.net/mbstring) (for Unicode strings), [iconv](https://secure.php.net/iconv) (for charset conversion), [ZIP](https://secure.php.net/zip) (for import/export), [zlib](https://secure.php.net/zlib) (for compressed feeds) * MySQL 5.5.3+ (recommended) or MariaDB equivalent, or SQLite 3.7.4+, or PostgreSQL 9.2+ @@ -219,7 +219,6 @@ Supported clients are: * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](https://github.com/phpquery/phpquery) * [Services_JSON](https://pear.php.net/pepr/pepr-proposal-show.php?id=198) -* [password_compat](https://github.com/ircmaxell/password_compat) [travis-badge]:https://travis-ci.org/FreshRSS/FreshRSS.svg?branch=master [travis-link]:https://travis-ci.org/FreshRSS/FreshRSS diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index ca44b1a96..e06a26399 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -169,10 +169,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { return; } - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $s = $conf->passwordHash; $ok = password_verify($password, $s); unset($password); diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index bf9084930..c1c27a4ab 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -9,9 +9,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { const BCRYPT_COST = 9; public static function hashPassword($passwordPlain) { - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); $passwordPlain = ''; $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 6d079a01f..b7fb0e6d6 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -219,10 +219,6 @@ class FreshRSS_FormAuth { return false; } - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - return password_verify($nonce . $hash, $challenge); } @@ -283,8 +279,7 @@ class FreshRSS_FormAuth { $cookie_duration = empty($limits['cookie_duration']) ? 2592000 : $limits['cookie_duration']; $oldest = time() - $cookie_duration; foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { - // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 - $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); + $extension = $file_info->getExtension(); if ($extension === 'txt' && $file_info->getMTime() < $oldest) { @unlink($file_info->getPathname()); } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index b47cd55ad..1b2786a6a 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -191,7 +191,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if ($this->hasNativeHex()) { $this->addEntryPrepared->bindParam(':hash', $valuesTmp['hash']); } else { - $valuesTmp['hashBin'] = pack('H*', $valuesTmp['hash']); //hex2bin() is PHP5.4+ + $valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']); $this->addEntryPrepared->bindParam(':hash', $valuesTmp['hashBin']); } } @@ -273,7 +273,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { if ($this->hasNativeHex()) { $this->updateEntryPrepared->bindParam(':hash', $valuesTmp['hash']); } else { - $valuesTmp['hashBin'] = pack('H*', $valuesTmp['hash']); //hex2bin() is PHP5.4+ + $valuesTmp['hashBin'] = hex2bin($valuesTmp['hash']); $this->updateEntryPrepared->bindParam(':hash', $valuesTmp['hashBin']); } diff --git a/app/install.php b/app/install.php index 961a7c171..8e14d14c0 100644 --- a/app/install.php +++ b/app/install.php @@ -413,7 +413,7 @@ function printStep1() {
-
+
diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index 2d1fcd133..0bbfb86ec 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -1,10 +1,7 @@ = 0) { - $options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; -} +$options = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; $articles = array( 'id' => 'user/' . str_replace('/', '', $username) . '/state/org.freshrss/' . $this->type, diff --git a/app/views/update/checkInstall.phtml b/app/views/update/checkInstall.phtml index 33d78cbe7..e719e53dd 100644 --- a/app/views/update/checkInstall.phtml +++ b/app/views/update/checkInstall.phtml @@ -9,7 +9,7 @@
Required (32-bit only): GMP
Recommanded: JSON, Zlib, mbstring, iconv, ZipArchive
*For the whole modules list see [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/744a9e8cf00aef7dec0acfa5f90f0dcfa2ef8837/Docker/Dockerfile-Alpine#L7-L9)* | |
| Database | **MySQL 5.5.3+** | SQLite 3.7.4+ |
| Browser | **Firefox** | Chrome, Opera, Safari, or IE11+ |
-## Important notice
-
-FreshRSS **CAN** work with PHP 5.3.8+. To do so, we are using specific functions available in the [''password_compat'' library](https://github.com/ircmaxell/password_compat#requirements) for the form authentication.
-
# Getting the appropriate version of FreshRSS
diff --git a/docs/en/developers/01_First_steps.md b/docs/en/developers/01_First_steps.md
index adca4495b..fef27cb39 100644
--- a/docs/en/developers/01_First_steps.md
+++ b/docs/en/developers/01_First_steps.md
@@ -148,26 +148,9 @@ abstract class ClassName {}
Files must be encoded with UTF-8 character set.
-## PHP 5.3 compatibility
+## PHP compatibility
-Do not get an array item directly from a function or a method. Use a variable.
-
-```php
-// code with PHP 5.3 compatibility
-$my_variable = function_returning_an_array();
-echo $my_variable[0];
-// code without PHP 5.3 compatibility
-echo function_returning_an_array()[0];
-```
-
-Do not use short array declaration.
-
-```php
-// code with PHP 5.3 compatibility
-$variable = array();
-// code without PHP 5.3 compatibility
-$variable = [];
-```
+Ensure that your code is working with a PHP version as old as what FreshRSS officially supports.
## Miscellaneous
diff --git a/docs/en/users/06_Mobile_access.md b/docs/en/users/06_Mobile_access.md
index 13dba828d..be4d0ded2 100644
--- a/docs/en/users/06_Mobile_access.md
+++ b/docs/en/users/06_Mobile_access.md
@@ -29,7 +29,7 @@ See the [page about the Fever compatible API](06_Fever_API.md) for another possi
* If you get *Service Unavailable!*, then check from step 1 again.
* With __Apache__:
* If you get *FAIL getallheaders!*, the combination of your PHP version and your Web server does not provide access to [`getallheaders`](http://php.net/getallheaders)
- * Update to PHP 5.4+, or use PHP as module instead of CGI. Otherwise turn on Apache `mod_setenvif` (often enabled by default), or `mod_rewrite` with the following procedure:
+ * Turn on Apache `mod_setenvif` (often enabled by default), or `mod_rewrite` with the following procedure:
* Allow [`FileInfo` in `.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride): see the [server setup](../admins/02_Installation.md) again.
* Enable [`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html):
* With Debian / Ubuntu: `sudo a2enmod rewrite`
diff --git a/docs/fr/developers/01_First_steps.md b/docs/fr/developers/01_First_steps.md
index d2bf9d315..dd38bcb3f 100644
--- a/docs/fr/developers/01_First_steps.md
+++ b/docs/fr/developers/01_First_steps.md
@@ -148,26 +148,9 @@ abstract class NomDeLaClasse {}
Les fichiers doivent être encodés en UTF-8.
-## Compatibilité avec PHP 5.3
+## Compatibilité PHP
-Il ne faut pas demander l'indice d'un tableau qui est retourné par une fonction ou une méthode. Il faut passer par une variable intermédiaire.
-
-```php
-// code compatible avec PHP 5.3
-$ma_variable = fonction_qui_retourne_un_tableau();
-echo $ma_variable[0];
-// code incompatible avec PHP 5.3
-echo fonction_qui_retourne_un_tableau()[0];
-```
-
-Il ne faut pas utiliser la déclaration raccourcie des tableaux.
-
-```php
-// code compatible avec PHP 5.3
-$variable = array();
-// code incompatible avec PHP 5.3
-$variable = [];
-```
+Assurez-vous que votre code fonctionne avec une version de PHP aussi ancienne que celle que FreshRSS supporte officiellement.
## Divers
diff --git a/docs/fr/users/01_Installation.md b/docs/fr/users/01_Installation.md
index a6495d2fd..cc1f543f1 100644
--- a/docs/fr/users/01_Installation.md
+++ b/docs/fr/users/01_Installation.md
@@ -7,15 +7,11 @@ Il est toutefois de votre responsabilité de vérifier que votre hébergement pe
| Logiciel | Recommandé | Fonctionne aussi avec |
| -------- | ----------- | --------------------- |
| Serveur web | **Apache 2** | Nginx |
- | PHP | **PHP 5.5+** | PHP 5.3.8+ |
+ | PHP | **PHP 7+** | PHP 5.5+ |
| Modules PHP | Requis : libxml, cURL, PDO_MySQL, PCRE et ctype
Requis (32 bits seulement) : GMP
Recommandé : JSON, Zlib, mbstring et iconv, ZipArchive
*Pour une liste complète des modules nécessaires voir le [Dockerfile](https://github.com/FreshRSS/FreshRSS/blob/744a9e8cf00aef7dec0acfa5f90f0dcfa2ef8837/Docker/Dockerfile-Alpine#L7-L9)* | |
| Base de données | **MySQL 5.5.3+** | SQLite 3.7.4+ |
| Navigateur | **Firefox** | Chrome, Opera, Safari, or IE 11+ |
-## Note importante
-
-FreshRSS **PEUT** fonctionner sur la version de PHP 5.3.8+. En effet, nous utilisons des fonctions spécifiques pour la connexion par formulaire et notamment la [bibliothèque ''password_compat''](https://github.com/ircmaxell/password_compat#requirements).
-
# Choisir la bonne version de FreshRSS
FreshRSS possède trois versions différentes (nous parlons de branches) qui sortent à des fréquences plus ou moins rapides. Aussi prenez le temps de comprendre à quoi correspond chacune de ces versions.
diff --git a/docs/fr/users/06_Mobile_access.md b/docs/fr/users/06_Mobile_access.md
index 7bce9eea3..225c55c7c 100644
--- a/docs/fr/users/06_Mobile_access.md
+++ b/docs/fr/users/06_Mobile_access.md
@@ -29,7 +29,7 @@ Voir la [page sur l’API compatible Fever](06_Fever_API.md) pour une autre poss
* Si vous obtenez *Service Unavailable!*, retourner à l’étape 6.
* Avec __Apache__:
* Si vous obtenez *FAIL getallheaders!*, alors la combinaison de votre version de PHP et de votre serveur Web ne permet pas l’accès à [`getallheaders`](http://php.net/getallheaders)
- * Utilisez au moins PHP 5.4+, ou utilisez PHP en tant que module plutôt que CGI. Sinon, activer Apache `mod_setenvif` (souvent activé par défault), ou `mod_rewrite` avec la procédure suivante :
+ * Activer Apache `mod_setenvif` (souvent activé par défault), ou `mod_rewrite` avec la procédure suivante :
* Autoriser [`FileInfo` dans `.htaccess`](http://httpd.apache.org/docs/trunk/mod/core.html#allowoverride) : revoir [l’installation du serveur](01_Installation.md).
* Activer [`mod_rewrite`](http://httpd.apache.org/docs/trunk/mod/mod_rewrite.html) :
* Sur Debian / Ubuntu : `sudo a2enmod rewrite`
diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php
index aae3accc6..93f6b494c 100644
--- a/lib/Minz/Configuration.php
+++ b/lib/Minz/Configuration.php
@@ -198,7 +198,7 @@ class Minz_Configuration {
return false;
}
- // Clear PHP 5.5+ cache for include
+ // Clear PHP cache for include
if (function_exists('opcache_invalidate')) {
opcache_invalidate($this->config_filename);
}
diff --git a/lib/Minz/ModelArray.php b/lib/Minz/ModelArray.php
index 1ac2b313d..4938f4b1d 100644
--- a/lib/Minz/ModelArray.php
+++ b/lib/Minz/ModelArray.php
@@ -48,7 +48,7 @@ class Minz_ModelArray {
throw new Minz_PermissionDeniedException($this->filename);
}
if (function_exists('opcache_invalidate')) {
- opcache_invalidate($this->filename); //Clear PHP 5.5+ cache for include
+ opcache_invalidate($this->filename); //Clear PHP cache for include
}
return true;
}
diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php
index 733982c14..14510c983 100644
--- a/lib/Minz/ModelPdo.php
+++ b/lib/Minz/ModelPdo.php
@@ -103,7 +103,7 @@ class Minz_ModelPdo {
$this->bd->beginTransaction();
}
public function inTransaction() {
- return $this->bd->inTransaction(); //requires PHP >= 5.3.3
+ return $this->bd->inTransaction();
}
public function commit() {
$this->bd->commit();
diff --git a/lib/lib_install.php b/lib/lib_install.php
index 6e4df4e9c..6b9b33240 100644
--- a/lib/lib_install.php
+++ b/lib/lib_install.php
@@ -6,7 +6,7 @@ Minz_Configuration::register('default_system', join_path(FRESHRSS_PATH, 'config.
Minz_Configuration::register('default_user', join_path(FRESHRSS_PATH, 'config-user.default.php'));
function checkRequirements($dbType = '') {
- $php = version_compare(PHP_VERSION, '5.3.8') >= 0;
+ $php = version_compare(PHP_VERSION, '5.5.0') >= 0;
$minz = file_exists(join_path(LIB_PATH, 'Minz'));
$curl = extension_loaded('curl');
$pdo_mysql = extension_loaded('pdo_mysql');
diff --git a/lib/lib_rss.php b/lib/lib_rss.php
index c0ea23989..2706ff606 100644
--- a/lib/lib_rss.php
+++ b/lib/lib_rss.php
@@ -1,9 +1,9 @@
= 0) {
- $htmlEntitiesOnly = array_flip(array_diff(
- get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES, 'UTF-8'), //Decode HTML entities
- get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES, 'UTF-8') //Preserve XML entities
- ));
- } else {
- $htmlEntitiesOnly = array_map('utf8_encode', array_flip(array_diff(
- get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES), //Decode HTML entities
- get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES) //Preserve XML entities
- )));
- }
+ $htmlEntitiesOnly = array_flip(array_diff(
+ get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES, 'UTF-8'), //Decode HTML entities
+ get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES, 'UTF-8') //Preserve XML entities
+ ));
}
return strtr($text, $htmlEntitiesOnly);
}
@@ -428,7 +414,7 @@ function check_install_php() {
$pdo_pgsql = extension_loaded('pdo_pgsql');
$pdo_sqlite = extension_loaded('pdo_sqlite');
return array(
- 'php' => version_compare(PHP_VERSION, '5.3.8') >= 0,
+ 'php' => version_compare(PHP_VERSION, '5.5.0') >= 0,
'minz' => file_exists(LIB_PATH . '/Minz'),
'curl' => extension_loaded('curl'),
'pdo' => $pdo_mysql || $pdo_sqlite || $pdo_pgsql,
diff --git a/lib/password_compat.php b/lib/password_compat.php
deleted file mode 100644
index e8ec02885..000000000
--- a/lib/password_compat.php
+++ /dev/null
@@ -1,279 +0,0 @@
-
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
- * @copyright 2012 The Authors
- */
-
-namespace {
-
-if (!defined('PASSWORD_DEFAULT')) {
-
- define('PASSWORD_BCRYPT', 1);
- define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
-
- /**
- * Hash the password using the specified algorithm
- *
- * @param string $password The password to hash
- * @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
- * @param array $options The options for the algorithm to use
- *
- * @return string|false The hashed password, or false on error.
- */
- function password_hash($password, $algo, array $options = array()) {
- if (!function_exists('crypt')) {
- trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
- return null;
- }
- if (!is_string($password)) {
- trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
- return null;
- }
- if (!is_int($algo)) {
- trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
- return null;
- }
- $resultLength = 0;
- switch ($algo) {
- case PASSWORD_BCRYPT:
- // Note that this is a C constant, but not exposed to PHP, so we don't define it here.
- $cost = 10;
- if (isset($options['cost'])) {
- $cost = $options['cost'];
- if ($cost < 4 || $cost > 31) {
- trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
- return null;
- }
- }
- // The length of salt to generate
- $raw_salt_len = 16;
- // The length required in the final serialization
- $required_salt_len = 22;
- $hash_format = sprintf("$2y$%02d$", $cost);
- // The expected length of the final crypt() output
- $resultLength = 60;
- break;
- default:
- trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
- return null;
- }
- $salt_requires_encoding = false;
- if (isset($options['salt'])) {
- switch (gettype($options['salt'])) {
- case 'NULL':
- case 'boolean':
- case 'integer':
- case 'double':
- case 'string':
- $salt = (string) $options['salt'];
- break;
- case 'object':
- if (method_exists($options['salt'], '__tostring')) {
- $salt = (string) $options['salt'];
- break;
- }
- case 'array':
- case 'resource':
- default:
- trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
- return null;
- }
- if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
- trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
- return null;
- } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
- $salt_requires_encoding = true;
- }
- } else {
- $buffer = '';
- $buffer_valid = false;
- if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
- $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
- if ($buffer) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
- $buffer = openssl_random_pseudo_bytes($raw_salt_len);
- if ($buffer) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid && @is_readable('/dev/urandom')) {
- $f = fopen('/dev/urandom', 'r');
- $read = PasswordCompat\binary\_strlen($buffer);
- while ($read < $raw_salt_len) {
- $buffer .= fread($f, $raw_salt_len - $read);
- $read = PasswordCompat\binary\_strlen($buffer);
- }
- fclose($f);
- if ($read >= $raw_salt_len) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
- $bl = PasswordCompat\binary\_strlen($buffer);
- for ($i = 0; $i < $raw_salt_len; $i++) {
- if ($i < $bl) {
- $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
- } else {
- $buffer .= chr(mt_rand(0, 255));
- }
- }
- }
- $salt = $buffer;
- $salt_requires_encoding = true;
- }
- if ($salt_requires_encoding) {
- // encode string with the Base64 variant used by crypt
- $base64_digits =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
- $bcrypt64_digits =
- './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-
- $base64_string = base64_encode($salt);
- $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
- }
- $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
-
- $hash = $hash_format . $salt;
-
- $ret = crypt($password, $hash);
-
- if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
- return false;
- }
-
- return $ret;
- }
-
- /**
- * Get information about the password hash. Returns an array of the information
- * that was used to generate the password hash.
- *
- * array(
- * 'algo' => 1,
- * 'algoName' => 'bcrypt',
- * 'options' => array(
- * 'cost' => 10,
- * ),
- * )
- *
- * @param string $hash The password hash to extract info from
- *
- * @return array The array of information about the hash.
- */
- function password_get_info($hash) {
- $return = array(
- 'algo' => 0,
- 'algoName' => 'unknown',
- 'options' => array(),
- );
- if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
- $return['algo'] = PASSWORD_BCRYPT;
- $return['algoName'] = 'bcrypt';
- list($cost) = sscanf($hash, "$2y$%d$");
- $return['options']['cost'] = $cost;
- }
- return $return;
- }
-
- /**
- * Determine if the password hash needs to be rehashed according to the options provided
- *
- * If the answer is true, after validating the password using password_verify, rehash it.
- *
- * @param string $hash The hash to test
- * @param int $algo The algorithm used for new password hashes
- * @param array $options The options array passed to password_hash
- *
- * @return boolean True if the password needs to be rehashed.
- */
- function password_needs_rehash($hash, $algo, array $options = array()) {
- $info = password_get_info($hash);
- if ($info['algo'] != $algo) {
- return true;
- }
- switch ($algo) {
- case PASSWORD_BCRYPT:
- $cost = isset($options['cost']) ? $options['cost'] : 10;
- if ($cost != $info['options']['cost']) {
- return true;
- }
- break;
- }
- return false;
- }
-
- /**
- * Verify a password against a hash using a timing attack resistant approach
- *
- * @param string $password The password to verify
- * @param string $hash The hash to verify against
- *
- * @return boolean If the password matches the hash
- */
- function password_verify($password, $hash) {
- if (!function_exists('crypt')) {
- trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
- return false;
- }
- $ret = crypt($password, $hash);
- if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
- return false;
- }
-
- $status = 0;
- for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
- $status |= (ord($ret[$i]) ^ ord($hash[$i]));
- }
-
- return $status === 0;
- }
-}
-
-}
-
-namespace PasswordCompat\binary {
- /**
- * Count the number of bytes in a string
- *
- * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
- * In this case, strlen() will count the number of *characters* based on the internal encoding. A
- * sequence of bytes might be regarded as a single multibyte character.
- *
- * @param string $binary_string The input string
- *
- * @internal
- * @return int The number of bytes
- */
- function _strlen($binary_string) {
- if (function_exists('mb_strlen')) {
- return mb_strlen($binary_string, '8bit');
- }
- return strlen($binary_string);
- }
-
- /**
- * Get a substring based on byte limits
- *
- * @see _strlen()
- *
- * @param string $binary_string The input string
- * @param int $start
- * @param int $length
- *
- * @internal
- * @return string The substring
- */
- function _substr($binary_string, $start, $length) {
- if (function_exists('mb_substr')) {
- return mb_substr($binary_string, $start, $length, '8bit');
- }
- return substr($binary_string, $start, $length);
- }
-
-}
diff --git a/p/api/greader.php b/p/api/greader.php
index 3d628c855..4cf1b7b20 100644
--- a/p/api/greader.php
+++ b/p/api/greader.php
@@ -43,11 +43,7 @@ if (PHP_INT_SIZE < 8) { //32-bit
}
}
-if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
- define('JSON_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
-} else {
- define('JSON_OPTIONS', 0);
-}
+define('JSON_OPTIONS', JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
function headerVariable($headerName, $varName) {
$header = '';
@@ -182,10 +178,6 @@ function authorizationToUser() {
function clientLogin($email, $pass) { //http://web.archive.org/web/20130604091042/http://undoc.in/clientLogin.html
if (FreshRSS_user_Controller::checkUsername($email)) {
- if (!function_exists('password_verify')) {
- include_once(LIB_PATH . '/password_compat.php');
- }
-
FreshRSS_Context::$user_conf = get_user_configuration($email);
if (FreshRSS_Context::$user_conf == null) {
Minz_Log::warning('Invalid API user ' . $email . ': configuration cannot be found.');
diff --git a/phpcs.xml b/phpcs.xml
index c30ad54f6..8234aced8 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -10,7 +10,6 @@