From 522c2c120af4f93b738fcf5e5d267f43246a71c5 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Wed, 19 Oct 2022 08:06:53 -0400 Subject: [PATCH 1/4] Add a macro that callers can use to check for igbinary header --- package.xml | 22 +++++++++++++++++++--- src/php7/igbinary.c | 2 +- src/php7/igbinary.h | 21 ++++++++++++++++++++- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/package.xml b/package.xml index f621e06b..ffbd2cb9 100644 --- a/package.xml +++ b/package.xml @@ -34,8 +34,8 @@ memcached or similar memory based storages for serialized data. 2022-10-17 - 3.2.9 - 1.3.1 + 3.2.10-dev + 1.4.0 stable @@ -43,7 +43,7 @@ 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. @@ -229,6 +229,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..1213a777 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); diff --git a/src/php7/igbinary.h b/src/php7/igbinary.h index 3e5d71cc..8b9d81e9 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-dev" /* 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 */ From 3dd8e121385bc015b3a5b6a93d84a1101d6d35da Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Wed, 19 Oct 2022 09:19:47 -0400 Subject: [PATCH 2/4] Fix bug in unserializing strings > 4GB --- package.xml | 6 ++++-- src/php7/igbinary.c | 3 ++- src/php7/igbinary.h | 2 +- tests/igbinary_089.phpt | 8 +++++++- tests/igbinary_089_32bit.phpt | 21 +++++++++++++++++++++ 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 tests/igbinary_089_32bit.phpt diff --git a/package.xml b/package.xml index ffbd2cb9..6e84fa03 100644 --- a/package.xml +++ b/package.xml @@ -31,10 +31,10 @@ memcached or similar memory based storages for serialized data. tandre@php.net yes - 2022-10-17 + 2022-10-19 - 3.2.10-dev + 3.2.10 1.4.0 @@ -44,6 +44,7 @@ memcached or similar memory based storages for serialized data. BSD-3-Clause * 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. + diff --git a/src/php7/igbinary.c b/src/php7/igbinary.c index 1213a777..8e40db3e 100644 --- a/src/php7/igbinary.c +++ b/src/php7/igbinary.c @@ -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 8b9d81e9..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.10-dev" +#define PHP_IGBINARY_VERSION "3.2.10" /* Macros */ 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..3f2a7bf0 --- /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: end-of-data in %sigbinary_089_32bit.php on line 3 +NULL \ No newline at end of file From 537861dd4d3049a2f7373a92388f3bb8646e1a7e Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Wed, 19 Oct 2022 09:24:25 -0400 Subject: [PATCH 3/4] Change expectation for platforms with 32-bit size_t --- tests/igbinary_089_32bit.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/igbinary_089_32bit.phpt b/tests/igbinary_089_32bit.phpt index 3f2a7bf0..160a6811 100644 --- a/tests/igbinary_089_32bit.phpt +++ b/tests/igbinary_089_32bit.phpt @@ -17,5 +17,5 @@ var_dump(igbinary_unserialize($ser_invalid)); ?> --EXPECTF-- -Warning: igbinary_unserialize_chararray: end-of-data in %sigbinary_089_32bit.php on line 3 +Warning: igbinary_unserialize_chararray: %s in %sigbinary_089_32bit.php on line 3 NULL \ No newline at end of file From e7b2a1ba5d962350b82c36c24205b2119f95b288 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 6 Nov 2022 13:53:11 -0500 Subject: [PATCH 4/4] [skip ci] update release date --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 6e84fa03..a0e6151d 100644 --- a/package.xml +++ b/package.xml @@ -31,7 +31,7 @@ memcached or similar memory based storages for serialized data. tandre@php.net yes - 2022-10-19 + 2022-11-06 3.2.10