Copilot commented on code in PR #3842:
URL: https://github.com/apache/avro/pull/3842#discussion_r3563756500


##########
lang/c/src/consume-binary.c:
##########
@@ -101,7 +105,11 @@ read_map(avro_reader_t reader, const avro_encoding_t * enc,
 
        while (block_count != 0) {
                if (block_count < 0) {
-                       block_count = block_count * -1;
+                       if (block_count == INT64_MIN) {
+                               avro_set_error("Invalid map block count");
+                               return EINVAL;
+                       }

Review Comment:
   `read_map()` invokes `map_start_block` with the raw `block_count` before 
validating it, so an `INT64_MIN` block count can reach consumer callbacks 
despite the later negation guard. Reject `INT64_MIN` immediately after reading 
`block_count` (before the first `map_start_block` call). The same early-guard 
pattern should also be applied to the subsequent `map_start_block` call after 
reading the next block count.



##########
lang/c/src/consume-binary.c:
##########
@@ -58,7 +58,11 @@ read_array(avro_reader_t reader, const avro_encoding_t * enc,
 
        while (block_count != 0) {
                if (block_count < 0) {
-                       block_count = block_count * -1;
+                       if (block_count == INT64_MIN) {
+                               avro_set_error("Invalid array block count");
+                               return EINVAL;

Review Comment:
   In `read_array()`, the `INT64_MIN` validation happens only when processing 
the block (inside the loop), but `array_start_block` is called with the raw 
`block_count` before that validation. This lets an `INT64_MIN` block count 
reach consumer callbacks prior to rejection, undermining the intended 
CWE-190/UB mitigation. Reject `INT64_MIN` immediately after reading 
`block_count` and before the first `array_start_block` call.



##########
lang/c/src/consume-binary.c:
##########
@@ -58,7 +58,11 @@ read_array(avro_reader_t reader, const avro_encoding_t * enc,
 
        while (block_count != 0) {
                if (block_count < 0) {
-                       block_count = block_count * -1;
+                       if (block_count == INT64_MIN) {
+                               avro_set_error("Invalid array block count");
+                               return EINVAL;
+                       }
+                       block_count = -block_count;

Review Comment:
   `read_array()` calls `array_start_block` for subsequent blocks (after 
reading the next `block_count`) without validating `INT64_MIN` first, so a 
malformed stream can still deliver `INT64_MIN` to consumer callbacks. Add the 
same `INT64_MIN` guard immediately after the `read_long()` at the end of the 
loop, before invoking `array_start_block`.



##########
lang/c/src/consume-binary.c:
##########
@@ -101,7 +105,11 @@ read_map(avro_reader_t reader, const avro_encoding_t * enc,
 
        while (block_count != 0) {
                if (block_count < 0) {
-                       block_count = block_count * -1;
+                       if (block_count == INT64_MIN) {
+                               avro_set_error("Invalid map block count");
+                               return EINVAL;
+                       }
+                       block_count = -block_count;

Review Comment:
   `read_map()` still calls `map_start_block` after reading the *next* 
`block_count` (near the end of the loop) without checking for `INT64_MIN` 
first. Even with the negation guard here, a malformed stream can supply 
`INT64_MIN` as a subsequent block count and reach consumer callbacks before 
rejection; the same early `INT64_MIN` check should be added immediately after 
that `read_long()` as well.



-- 
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