Quote:
Originally Posted by AboutSledge
PHP Data Type Converting Bug.
<?php
//header("Content-Type: text/plain; charset=utf-8");
$n = -6288256054;
var_dump($n);
$a = intval($n);
var_dump($a);
$b = (int) $n;
var_dump($b);
settype($n,"int");
var_dump($n);
?>
============good==========
float(-6288256054)
int(-1993288758)
int(-1993288758)
int(-1993288758)
============bad=================
float(-6288256054)
int(-2147483648)
int(-2147483648)
int(-2147483648)
|
yes..this is the problem
I have a php script running on some server for getting pagerank;
After running fine for a while, few weeks ago it died; so I said..google changed the crc..but it wasn't like that; yesterday I started to read the forums in search of answers till I found this;
I looked deep inside the code to see what's really happens
First let's say that php installed on my server is PHP Version 4.3.10;
Well the problem lies inside mix($a,$b,$c) function; it's about Arithmetic Operators which can operate only with 32bit balues; so when we perform $a ^ (zeroFill($c,13)) we must be sure we have 32bit integers;
On 32bit OS's the conversion is done well from double (64bit numbers) to long (32 bit) before xoring; but on 64 you see what's happens especially with small negative numbers ..small than MIN_INT which is (-2147483648) aka 0x80000000;
so if we have a double (-6288256054) which is small than MIN_INT on 32OS will be truncated in a way..and on 64 it will return always MIN_INT; knowing this we can detect where it runs on 64 or 32 bit OS's
;
so quiqly I write a helper to fix our double integers;
PHP Code:
function toInt32(& $x){
$z = hexdec(80000000);
$y = (int)$x;
// on 64bit OSs if $x is double, negative ,will return -$z in $y
// which means 32th bit set (the sign bit)
if($y==-$z&&$x<-$z){
$y = (int)((-1)*$x);// this is the hack, make it positive before
$y = (-1)*$y; // switch back the sign
//echo "int hack <br>";
}
$x = $y;
}
then apply this function right before xoring inside mix function...foreach line
PHP Code:
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,13)));
function mix($a,$b,$c) {
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,13)));
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<8));
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,13)));
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,12)));
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<16));
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,5)));
$a -= $b; $a -= $c; toInt32($a); $a = (int)($a ^ (zeroFill($c,3)));
$b -= $c; $b -= $a; toInt32($b); $b = (int)($b ^ ($a<<10));
$c -= $a; $c -= $b; toInt32($c); $c = (int)($c ^ (zeroFill($b,15)));
return array($a,$b,$c);
}
with this, now I have my script running again...on "supposed" 64bit host machine..(coz I don't know if this is true
)
greatz
CG
http://cgsoftlabs.ro