diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index c1cd98d9..25dba257 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -529,6 +529,38 @@ class Crypt_Base if ($this->use_inline_crypt !== false) { $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function'); } + + if (!defined('CRYPT_BASE_USE_SAFE_INTVAL')) { + switch (true) { + // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" + case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster + case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': + case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + define('CRYPT_BASE_USE_SAFE_INTVAL', false); + break; + case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': + switch (true) { + // PHP_VERSION_ID wasn't a constant until PHP 5.2.7 + case version_compare(PHP_VERSION, '5.3.0') < 1: + /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: + + https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd + + altho the changelogs make no mention of it, this bug was fixed with this commit: + + https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 + + affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ + case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: + case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: + define('CRYPT_BASE_USE_SAFE_INTVAL', true); + break; + default: + define('CRYPT_BASE_USE_SAFE_INTVAL', false); + } + } + } } /** @@ -2647,32 +2679,8 @@ class Crypt_Base */ function safe_intval($x) { - switch (true) { - case is_int($x): - // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding" - case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster - case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': - return $x; - case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': - switch (true) { - // PHP_VERSION_ID wasn't a constant until PHP 5.2.7 - case version_compare(PHP_VERSION, '5.3.0') < 1: - /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: - - https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd - - altho the changelogs make no mention of it, this bug was fixed with this commit: - - https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 - - affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ - case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: - case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: - break; - default: - return $x; - } + if (CRYPT_BASE_USE_SAFE_INTVAL || is_int($x)) { + return $x; } return (fmod($x, 0x80000000) & 0x7FFFFFFF) | ((fmod(floor($x / 0x80000000), 2) & 1) << 31); @@ -2686,26 +2694,12 @@ class Crypt_Base */ function safe_intval_inline() { - // on 32-bit linux systems with PHP < 5.3 float to integer conversion is bad - switch (true) { - case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: - case version_compare(PHP_VERSION, '5.3.0') >= 0 && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': - return '%s'; - break; - case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': - switch (true) { - case version_compare(PHP_VERSION, '5.3.0') < 1: - case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: - case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: - break; - default: - return '%s'; - } - default: - $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; - return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + if (CRYPT_BASE_USE_SAFE_INTVAL) { + return '%s'; } + + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; } /**