Search code examples
phpserializationarchitectureinteger-overflow

PHP unserialized integer from 64-bit to 32-bit


I have been trying to unserialize on a 32-bit server an object that was serialized on a 64-bit server. I have isolated my problem to an integer in the object. Here is a small reproduction of the problem.

On a 64-bit machine:

$i = serialize('20110510134021'); //i:20110510134021;

On a 32-bit machine:

$i = unserialize('i:20110510134021;');

Gives the error

Notice: unserialize(): Error at offset 0 of 16 bytes

Now I understand that those serialization method shouldn't be used for cross system data transmition. However, we are merely trying to migrate the data to another system, not use it actively for transfers. This is a one time thing.

I would think that this might be due to integer overflow, but even on the 32-bit server I can do something like

$i = 20110510134021;
echo $i;

And it will work fine. I'm guessing PHP integer types scale to some double type or something like that. But why doesn't it do that when it unserializes?

How can I unserialize those objects? If I can't, is there any way to convert them to something else? Finally, has anyone written a deserialize method in PHP itself? Or has details on the protocol? I could use that and have a custom case for those integers.

Thanks.

Note: I do not have access to the original data, only the serialized result.


Solution

  • The max integer on 32 bit system is 4294967296; $i = 20110510134021; works because PHP converts the variable to double.

    So replace i with d

    $i = unserialize('d:20110510134021;');
    

    If you run this script, you will see the correct represenation of the variable on the system you are running (d: on 32 bit system, i: on 64 bit system):

    $int = 20110510134021;
    var_dump(serialize($int));