ArjunD3456 opened a new pull request, #4044: URL: https://github.com/apache/avro/pull/4044
## What is the purpose of the change `read_long` in `lang/c/src/encoding_binary.c` builds a varint with `value |= (int64_t)(b & 0x7F) << (7 * offset)`. On a 10-byte varint the last byte is shifted by 63 into a signed `int64_t`, so a payload bit lands on the sign bit and the shift overflows, which is undefined behavior. The big-endian branches of `read_float` and `read_double` have the same shape, shifting a byte into bit 31 of a signed `int32_t` (`read_float`) and bit 63 of a signed `int64_t` (`read_double`). All three feed on bytes taken straight from the input stream, so any Avro datum carrying a full-width `long`, or a `float`/`double` read on a big-endian build, trips it. `-fsanitize=undefined` reports `left shift of ... cannot be represented in type 'long'` on `read_long` while decoding `INT64_MIN`/`INT64_MAX`. The C++ `BinaryDecoder::doDecodeLong` already accumulates into an unsigned `uint64_t` for this reason, so this brings the C reader in line: shift in unsigned and assign to the signed destination. Decoded values are unchanged on the platforms Avro targets. ## Verifying this change This change is already covered by existing tests: the `long`, `float`, and `double` round-trip cases in `lang/c/tests/test_avro_values.c` exercise these readers (the `long` case decodes maximal 10-byte varints), and a `-fsanitize=undefined` build of that suite is clean after the change where it previously reported the shift overflow. Behavior is unchanged for valid input. ## Documentation - Does this pull request introduce a new feature? no -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
