msgpack / msgpack-php

msgpack.org[PHP]
BSD 3-Clause "New" or "Revised" License
773 stars 119 forks source link

uint32 numbers are incorrectly serialized on Windows #163

Open bderleta opened 2 years ago

bderleta commented 2 years ago

Seems related to issue https://github.com/msgpack/msgpack-php/issues/119, but occurs in serialization. Extension built from master branch just an hour before, but confirmed with 2.2.0RC1 and 2.1.2 PECL builds as well - all affected.

$payload = 3119646122;
$pack = msgpack_pack($payload);
print bin2hex($pack[0]) . "\r\n";
$unpack = msgpack_unpack($pack);
var_dump($unpack);

On linux builds:

ce
int(3119646122)

On windows builds (VS17 x64 TS):

d2
int(-1175321174)

msgpack_pack is producing incorrectly 0xD2 (signed int32) type specifier, so it is not an unpacker issue.

It seems it is caused by long being 4 byte, while zend_long is correctly 8 byte in size. Therefore, msgpack_pack_long accepting long argument is truncating zend_long value, then invokes msgpack_pack_real_int32 treating it as signed 32-bit value. The correct behavior is observed after replacing msgpack_pack_long by msgpack_pack_long_long in msgpack_serialize_zval:

 case IS_LONG:
            msgpack_pack_long_long(buf, zval_get_long(val_noref));
            break;
m6w6 commented 2 years ago

Thank you! Looks like a LLP64 vs LP64 issue.