From 2bad38d89201c5c025ae9522d4e8af13e399ca58 Mon Sep 17 00:00:00 2001 From: mohammed arib Date: Thu, 23 Jul 2026 13:50:15 +0530 Subject: [PATCH] MINOR: [c] avoid signed left-shift overflow in binary varint decoder --- lang/c/src/encoding_binary.c | 22 +++++++++++----------- lang/c/tests/test_avro_data.c | 13 +++++++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lang/c/src/encoding_binary.c b/lang/c/src/encoding_binary.c index 459d5fb3db3..31c5eb9ed97 100644 --- a/lang/c/src/encoding_binary.c +++ b/lang/c/src/encoding_binary.c @@ -40,7 +40,7 @@ static int read_long(avro_reader_t reader, int64_t * l) return EILSEQ; } AVRO_READ(reader, &b, 1); - value |= (int64_t) (b & 0x7F) << (7 * offset); + value |= (uint64_t) (b & 0x7F) << (7 * offset); ++offset; } while (b & 0x80); @@ -226,9 +226,9 @@ static int read_float(avro_reader_t reader, float *f) } v; #if AVRO_PLATFORM_IS_BIG_ENDIAN AVRO_READ(reader, buf, 4); - v.i = ((int32_t) buf[0] << 0) - | ((int32_t) buf[1] << 8) - | ((int32_t) buf[2] << 16) | ((int32_t) buf[3] << 24); + v.i = ((uint32_t) buf[0] << 0) + | ((uint32_t) buf[1] << 8) + | ((uint32_t) buf[2] << 16) | ((uint32_t) buf[3] << 24); #else AVRO_READ(reader, (void *)&v.i, 4); #endif @@ -285,13 +285,13 @@ static int read_double(avro_reader_t reader, double *d) #if AVRO_PLATFORM_IS_BIG_ENDIAN AVRO_READ(reader, buf, 8); - v.l = ((int64_t) buf[0] << 0) - | ((int64_t) buf[1] << 8) - | ((int64_t) buf[2] << 16) - | ((int64_t) buf[3] << 24) - | ((int64_t) buf[4] << 32) - | ((int64_t) buf[5] << 40) - | ((int64_t) buf[6] << 48) | ((int64_t) buf[7] << 56); + v.l = ((uint64_t) buf[0] << 0) + | ((uint64_t) buf[1] << 8) + | ((uint64_t) buf[2] << 16) + | ((uint64_t) buf[3] << 24) + | ((uint64_t) buf[4] << 32) + | ((uint64_t) buf[5] << 40) + | ((uint64_t) buf[6] << 48) | ((uint64_t) buf[7] << 56); #else AVRO_READ(reader, (void *)&v.l, 8); #endif diff --git a/lang/c/tests/test_avro_data.c b/lang/c/tests/test_avro_data.c index 3a26c67e242..a194f13426b 100644 --- a/lang/c/tests/test_avro_data.c +++ b/lang/c/tests/test_avro_data.c @@ -272,6 +272,19 @@ static int test_int64(void) avro_datum_decref(double_datum); } + /* Boundary values that encode to a full-width 10-byte varint and set + * the high bit on the final byte, exercising the widest shift in the + * varint decoder. */ + static const int64_t edge_values[] = { + INT64_MAX, INT64_MIN, INT64_MAX - 1, INT64_MIN + 1, + (int64_t) 1 << 62, -((int64_t) 1 << 62) + }; + for (i = 0; i < (int) (sizeof(edge_values) / sizeof(edge_values[0])); i++) { + avro_datum_t edge_datum = avro_int64(edge_values[i]); + write_read_check(writer_schema, edge_datum, NULL, NULL, "long"); + avro_datum_decref(edge_datum); + } + avro_datum_t datum = avro_int64(10000); test_json(datum, "10000"); avro_datum_decref(datum);