View Single Post
Old 04-26-2006, 09:16 PM  
CGSoftLabs
Junior Member
CGSoftLabs began at the beginning.
 
Posts: 1
Karma: 10
Join Date: Apr 2006
Wink

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 -= $ctoInt32($a); $a = (int)($a ^ (zeroFill($c,13)));

function 
mix($a,$b,$c) {
  
$a -= $b$a -= $ctoInt32($a); $a = (int)($a ^ (zeroFill($c,13)));
  
$b -= $c$b -= $atoInt32($b); $b = (int)($b ^ ($a<<8));
  
$c -= $a$c -= $btoInt32($c); $c = (int)($c ^ (zeroFill($b,13)));
  
$a -= $b$a -= $ctoInt32($a); $a = (int)($a ^ (zeroFill($c,12)));
  
$b -= $c$b -= $atoInt32($b); $b = (int)($b ^ ($a<<16));
  
$c -= $a$c -= $btoInt32($c); $c = (int)($c ^ (zeroFill($b,5)));
  
$a -= $b$a -= $ctoInt32($a); $a = (int)($a ^ (zeroFill($c,3)));
  
$b -= $c$b -= $atoInt32($b); $b = (int)($b ^ ($a<<10));
  
$c -= $a$c -= $btoInt32($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

Last edited by CGSoftLabs; 05-09-2006 at 05:59 AM.
CGSoftLabs is offline   Reply With Quote