diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index dd0a3cd2..328818c6 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -32,6 +32,7 @@ namespace phpseclib3\Math; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\InvalidArgumentException; use phpseclib3\Math\BigInteger\Engines\Engine; +use UnexpectedValueException; /** * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 @@ -144,13 +145,16 @@ class BigInteger implements \JsonSerializable ['PHP64', ['DefaultEngine']], ['PHP32', ['DefaultEngine']], ]; + foreach ($engines as $engine) { try { self::setEngine($engine[0], $engine[1]); - break; + return; } catch (\Exception $e) { } } + + throw new UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); } } diff --git a/phpseclib/Math/BigInteger/Engines/PHP.php b/phpseclib/Math/BigInteger/Engines/PHP.php index 69bd0698..b29148b9 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP.php +++ b/phpseclib/Math/BigInteger/Engines/PHP.php @@ -1236,4 +1236,18 @@ abstract class PHP extends Engine return array_reverse($vals); } + + /** + * @return bool + */ + protected static function testJITOnWindows() + { + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && !defined('PHPSECLIB_ALLOW_JIT')) { + $status = opcache_get_status(); + if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { + return true; + } + } + return false; + } } diff --git a/phpseclib/Math/BigInteger/Engines/PHP32.php b/phpseclib/Math/BigInteger/Engines/PHP32.php index 27c34acb..21c40845 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP32.php +++ b/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -103,7 +103,7 @@ class PHP32 extends PHP */ public static function isValidEngine(): bool { - return PHP_INT_SIZE >= 4; + return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); } /** diff --git a/phpseclib/Math/BigInteger/Engines/PHP64.php b/phpseclib/Math/BigInteger/Engines/PHP64.php index 43f6f0b5..7c4ee54f 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP64.php +++ b/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -104,7 +104,7 @@ class PHP64 extends PHP */ public static function isValidEngine(): bool { - return PHP_INT_SIZE >= 8; + return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); } /** diff --git a/phpseclib/bootstrap.php b/phpseclib/bootstrap.php index 53e63b8e..517106c3 100644 --- a/phpseclib/bootstrap.php +++ b/phpseclib/bootstrap.php @@ -10,12 +10,13 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -// see https://github.com/php/php-src/issues/11917 -if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && !defined('PHPSECLIB_ALLOW_JIT')) { - $status = opcache_get_status(); - if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { +if (extension_loaded('mbstring')) { + // 2 - MB_OVERLOAD_STRING + // mbstring.func_overload is deprecated in php 7.2 and removed in php 8.0. + if (version_compare(PHP_VERSION, '8.0.0') < 0 && ini_get('mbstring.func_overload') & 2) { throw new UnexpectedValueException( - 'JIT on Windows is not currently supported' + 'Overloading of string functions using mbstring.func_overload ' . + 'is not supported by phpseclib.' ); } }