This is an automated email from the ASF dual-hosted git repository. iemejia pushed a commit to branch avro-cpp-issue in repository https://gitbox.apache.org/repos/asf/avro.git
commit e8b6f7459e2080eb4be7f69098cc6c7df810e0f6 Author: Ismaël Mejía <[email protected]> AuthorDate: Sat Jul 11 10:17:39 2026 +0200 AVRO-4275: Fix incomplete INT64_MIN overflow guard in block_count negation Replace the flawed -(block_count + 1) + 1 idiom (which still overflows on the final + 1 when block_count == INT64_MIN) with an explicit INT64_MIN guard followed by simple negation, in both read_array_value() and read_map_value(). Also fix the block_size in the map test vector from 7 to 6 to match the actual byte count of the encoded entries. Assisted-by: GitHub Copilot:claude-opus-4.6 --- lang/c/src/value-read.c | 20 ++++++++------------ lang/c/tests/test_avro_4275.c | 4 ++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lang/c/src/value-read.c b/lang/c/src/value-read.c index 68ffc5795c..b7bc2f7e44 100644 --- a/lang/c/src/value-read.c +++ b/lang/c/src/value-read.c @@ -53,15 +53,13 @@ read_array_value(avro_reader_t reader, avro_value_t *dest) while (block_count != 0) { if (block_count < 0) { - /* Safe negation: avoid undefined behavior when - * block_count == INT64_MIN, since -INT64_MIN is not - * representable in int64_t (CWE-190). Use the - * -(x+1)+1 idiom to negate without overflow. */ - block_count = -(block_count + 1) + 1; - if (block_count <= 0) { + /* Reject INT64_MIN: its negation is not + * representable in int64_t (CWE-190). */ + if (block_count == INT64_MIN) { avro_set_error("Invalid array block count"); return EINVAL; } + block_count = -block_count; check_prefix(rval, avro_binary_encoding. read_long(reader, &block_size), "Cannot read array block size: "); @@ -97,15 +95,13 @@ read_map_value(avro_reader_t reader, avro_value_t *dest) while (block_count != 0) { if (block_count < 0) { - /* Safe negation: avoid undefined behavior when - * block_count == INT64_MIN, since -INT64_MIN is not - * representable in int64_t (CWE-190). Use the - * -(x+1)+1 idiom to negate without overflow. */ - block_count = -(block_count + 1) + 1; - if (block_count <= 0) { + /* Reject INT64_MIN: its negation is not + * representable in int64_t (CWE-190). */ + if (block_count == INT64_MIN) { avro_set_error("Invalid map block count"); return EINVAL; } + block_count = -block_count; check_prefix(rval, avro_binary_encoding. read_long(reader, &block_size), "Cannot read map block size: "); diff --git a/lang/c/tests/test_avro_4275.c b/lang/c/tests/test_avro_4275.c index 5a15cabee6..ca93caf6c2 100644 --- a/lang/c/tests/test_avro_4275.c +++ b/lang/c/tests/test_avro_4275.c @@ -63,14 +63,14 @@ static const char valid_neg_block_array[] = { * * Layout: * 03 = varint 3 = zigzag(-2) => block_count = -2 - * 0E = varint 14 = zigzag(7) => block_size = 7 bytes + * 0C = varint 12 = zigzag(6) => block_size = 6 bytes * 02 61 14 = key "a" (len=1, 'a'), value int 10 * 02 62 28 = key "b" (len=1, 'b'), value int 20 * 00 = terminator */ static const char valid_neg_block_map[] = { '\x03', /* block_count = -2 */ - '\x0E', /* block_size = 7 */ + '\x0C', /* block_size = 6 */ '\x02', '\x61', '\x14', /* key "a", value 10 */ '\x02', '\x62', '\x28', /* key "b", value 20 */ '\x00' /* terminator */
