mirror of
https://github.com/danog/tgseclib.git
synced 2024-11-27 04:34:45 +01:00
fix float to int conversions on 32-bit linux PHP < 5.3 installs
This commit is contained in:
parent
c27fd2e66f
commit
42fb96db16
@ -478,16 +478,14 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$l^= $p[$i];
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]);
|
||||
|
||||
$r^= $p[$i + 1];
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]);
|
||||
}
|
||||
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
||||
}
|
||||
@ -513,16 +511,14 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$l^= $p[$i];
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]);
|
||||
|
||||
$r^= $p[$i - 1];
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]);
|
||||
}
|
||||
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
||||
}
|
||||
@ -548,6 +544,18 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// 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:
|
||||
case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
|
||||
$safeint = '%s';
|
||||
break;
|
||||
default:
|
||||
$safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
|
||||
$safeint.= '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
@ -583,16 +591,14 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
for ($i = 0; $i < 16; $i+= 2) {
|
||||
$encrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]') . ';
|
||||
|
||||
$r^= ' . $p[$i + 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]') . ';
|
||||
';
|
||||
}
|
||||
$encrypt_block.= '
|
||||
@ -612,16 +618,14 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
for ($i = 17; $i > 2; $i-= 2) {
|
||||
$decrypt_block.= '
|
||||
$l^= ' . $p[$i] . ';
|
||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
||||
$sb_1[$l >> 16 & 0xff] ^
|
||||
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$l >> 8 & 0xff]) +
|
||||
$sb_3[$l & 0xff];
|
||||
$sb_3[$l & 0xff]') . ';
|
||||
|
||||
$r^= ' . $p[$i - 1] . ';
|
||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
||||
$sb_1[$r >> 16 & 0xff] ^
|
||||
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||
$sb_2[$r >> 8 & 0xff]) +
|
||||
$sb_3[$r & 0xff];
|
||||
$sb_3[$r & 0xff]') . ';
|
||||
';
|
||||
}
|
||||
|
||||
@ -644,4 +648,24 @@ class Crypt_Blowfish extends Crypt_Base
|
||||
}
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert float to int
|
||||
*
|
||||
* On 32-bit Linux installs running PHP < 5.3 converting floats to ints doesn't always work
|
||||
*
|
||||
* @access private
|
||||
* @param string $x
|
||||
* @return int
|
||||
*/
|
||||
function safe_intval($x)
|
||||
{
|
||||
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
|
||||
if (is_int($x) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
|
||||
return $x;
|
||||
}
|
||||
return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
|
||||
((fmod(floor($x / 0x80000000), 2) & 1) << 31);
|
||||
}
|
||||
}
|
||||
|
@ -820,7 +820,14 @@ class Crypt_Hash
|
||||
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
||||
}
|
||||
|
||||
return fmod($result, $mod);
|
||||
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||
// PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
|
||||
if (is_int($result) || version_compare(PHP_VERSION, '5.3.0') >= 0 || (PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
|
||||
return fmod($result, $mod);
|
||||
}
|
||||
|
||||
return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
|
||||
((fmod(floor($result / 0x80000000), 2) & 1) << 31);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user