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]

Reply via email to