Copilot commented on code in PR #3861:
URL: https://github.com/apache/avro/pull/3861#discussion_r3565066650
##########
lang/py/avro/io.py:
##########
@@ -780,6 +841,22 @@ def read_enum(self, writers_schema:
avro.schema.EnumSchema, readers_schema: avro
def skip_enum(self, writers_schema: avro.schema.EnumSchema, decoder:
BinaryDecoder) -> None:
return decoder.skip_int()
+ @staticmethod
+ def _ensure_collection_available(decoder: BinaryDecoder, count: int,
min_bytes_per_element: int) -> None:
+ """
+ Reject a collection (array or map) block whose declared element count
+ could not be backed by the bytes actually remaining, before iterating.
+ Skipped when the per-element minimum is zero (e.g. an array of nulls)
or
+ when the reader cannot report how many bytes remain.
+ """
+ if count <= 0 or min_bytes_per_element <= 0:
+ return
+ remaining = decoder.bytes_remaining()
+ if remaining is not None and count * min_bytes_per_element > remaining:
+ raise avro.errors.InvalidAvroBinaryEncoding(
+ f"Collection claims {count} elements with at least
{min_bytes_per_element} bytes each, but only {remaining} bytes are available."
+ )
Review Comment:
`count * min_bytes_per_element` can create a very large intermediate integer
when `count` is attacker-controlled (Avro long is unbounded in Python). You can
avoid the potentially expensive multiplication by comparing via integer
division instead, while keeping the same semantics for positive values.
--
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]