diff --git a/package.xml b/package.xml index f621e06b..a0e6151d 100644 --- a/package.xml +++ b/package.xml @@ -31,11 +31,11 @@ memcached or similar memory based storages for serialized data. tandre@php.net yes - 2022-10-17 + 2022-11-06 - 3.2.9 - 1.3.1 + 3.2.10 + 1.4.0 stable @@ -43,7 +43,8 @@ memcached or similar memory based storages for serialized data. BSD-3-Clause -* Fix invalid release artifact name in job to build dlls for https://github.com/igbinary/igbinary +* Add a macro that callers can use to check if igbinary will accept the header for data being unserialized. +* Fix bug preventing the unserialization of data containing representations of strings larger than 4GB. @@ -199,6 +200,7 @@ memcached or similar memory based storages for serialized data. + @@ -229,6 +231,22 @@ memcached or similar memory based storages for serialized data. igbinary + + 2022-10-17 + + + 3.2.9 + 1.3.1 + + + stable + stable + + BSD-3-Clause + +* Fix invalid release artifact name in job to build dlls for https://github.com/igbinary/igbinary + + 2022-10-16 diff --git a/src/php7/igbinary.c b/src/php7/igbinary.c index 93262db4..8e40db3e 100644 --- a/src/php7/igbinary.c +++ b/src/php7/igbinary.c @@ -2161,7 +2161,7 @@ inline static int igbinary_unserialize_header(struct igbinary_unserialize_data * version = igbinary_unserialize32(igsd); /* Support older version 1 and the current format 2 */ - if (version == IGBINARY_FORMAT_VERSION || version == 0x00000001) { + if (EXPECTED(version == IGBINARY_FORMAT_VERSION || version == 0x00000001)) { return 0; } else { igbinary_unserialize_header_emit_warning(igsd, version); @@ -2345,7 +2345,8 @@ inline static zend_string *igbinary_unserialize_string(struct igbinary_unseriali /* }}} */ /* igbinary_unserialize_extremely_long_chararray {{{ */ static ZEND_COLD zend_never_inline zend_string* igbinary_unserialize_extremely_long_chararray(struct igbinary_unserialize_data *igsd) { -#if SIZEOF_ZEND_LONG > 4 +#if SIZEOF_SIZE_T <= 4 + (void)igsd; zend_error(E_WARNING, "igbinary_unserialize_chararray: cannot unserialize 64-bit data on 32-bit platform"); return NULL; #else diff --git a/src/php7/igbinary.h b/src/php7/igbinary.h index 3e5d71cc..3877777d 100644 --- a/src/php7/igbinary.h +++ b/src/php7/igbinary.h @@ -18,7 +18,7 @@ struct zval; /** Binary protocol version of igbinary. */ #define IGBINARY_FORMAT_VERSION 0x00000002 -#define PHP_IGBINARY_VERSION "3.2.9" +#define PHP_IGBINARY_VERSION "3.2.10" /* Macros */ @@ -73,4 +73,23 @@ IGBINARY_API int igbinary_serialize_ex(uint8_t **ret, size_t *ret_len, zval *z, */ IGBINARY_API int igbinary_unserialize(const uint8_t *buf, size_t buf_len, zval *z); +static zend_always_inline int _igbinary_has_valid_header(const uint8_t *buf, size_t buf_len) { + if (buf_len < 5) { + /* Must have 4 header bytes and at least one byte of data */ + return 0; + } + /* Unserialize 32bit value the same way on big-endian and little-endian architectures. + * This compiles to a load+optional bswap when compiler optimizations are enabled. */ + const uint32_t ret = + ((uint32_t)(buf[0]) << 24) | + ((uint32_t)(buf[1]) << 16) | + ((uint32_t)(buf[2]) << 8) | + ((uint32_t)(buf[3])); + return ret == 1 || ret == 2; +} +/** This is defined as a macro and a static C function + * to allow callers to use the macro from newer igbinary versions even with older igbinary installations. */ +#define igbinary_has_valid_header(buf, buf_len) _igbinary_has_valid_header((buf), (buf_len)) + + #endif /* IGBINARY_H */ diff --git a/tests/igbinary_089.phpt b/tests/igbinary_089.phpt index 747abb99..703fd523 100644 --- a/tests/igbinary_089.phpt +++ b/tests/igbinary_089.phpt @@ -2,12 +2,14 @@ Test serializing string > 4G --INI-- memory_limit=15G +display_errors=stderr +error_reporting=E_ALL --CONFLICTS-- high_memory --SKIPIF-- --FILE-- @@ -19,9 +21,13 @@ echo bin2hex(substr($ser, 0, 20)) . "\n"; $unser = igbinary_unserialize($ser); unset($ser); var_dump($unser === str_repeat('*', 4200000000)); +$ser_invalid = hex2bin('0000000213fa56ea002a'); +var_dump(igbinary_unserialize($ser_invalid)); ?> --EXPECTF-- len=4200000009 0000000213fa56ea002a2a2a2a2a2a2a2a2a2a2a bool(true) +Warning: igbinary_unserialize_chararray: end-of-data in %sigbinary_089.php on line 10 +NULL \ No newline at end of file diff --git a/tests/igbinary_089_32bit.phpt b/tests/igbinary_089_32bit.phpt new file mode 100644 index 00000000..160a6811 --- /dev/null +++ b/tests/igbinary_089_32bit.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test unserializing invalid 64-bit string header on 32-bit platform +--INI-- +display_errors=stderr +error_reporting=E_ALL +--CONFLICTS-- +high_memory +--SKIPIF-- + 4) { print "skip requires 32-bit\n"; } +?> +--FILE-- + +--EXPECTF-- +Warning: igbinary_unserialize_chararray: %s in %sigbinary_089_32bit.php on line 3 +NULL \ No newline at end of file