iemejia commented on code in PR #3861:
URL: https://github.com/apache/avro/pull/3861#discussion_r3565239808


##########
lang/py/avro/io.py:
##########
@@ -214,11 +222,34 @@ def read(self, n: int) -> bytes:
         """
         if n < 0:
             raise avro.errors.InvalidAvroBinaryEncoding(f"Requested {n} bytes 
to read, expected positive integer.")
+        if n > self._MAX_UNCHECKED_READ:
+            remaining = self.bytes_remaining()
+            if remaining is not None and n > remaining:
+                raise avro.errors.InvalidAvroBinaryEncoding(f"Requested {n} 
bytes to read, but only {remaining} remain.")
         read_bytes = self.reader.read(n)
         if len(read_bytes) != n:
             raise avro.errors.InvalidAvroBinaryEncoding(f"Read 
{len(read_bytes)} bytes, expected {n} bytes")
         return read_bytes
 
+    def bytes_remaining(self) -> Optional[int]:
+        """
+        Return the number of bytes still available to read, or ``None`` when
+        that count is not known (a non-seekable reader, or one whose position
+        cannot be obtained). Used to reject a declared length or collection
+        block count that exceeds the data actually available before allocating
+        for it.
+        """
+        reader = self.reader
+        try:
+            pos = reader.tell()
+            reader.seek(0, os.SEEK_END)
+            end = reader.tell()
+            reader.seek(pos)
+        except (OSError, ValueError, AttributeError):
+            # Not seekable, or the position/size could not be determined.
+            return None
+        return end - pos

Review Comment:
   Fixed in b891ac3: bytes_remaining() now restores the original position in a 
finally block, so a failure after seeking to the end never leaves the reader at 
EOF. Added tests for the restore on both success and failure. (The isinstance 
type-validation was dropped because reader is typed IO[bytes], so tell() 
returns int and mypy flags the check as unreachable; the try/except covers the 
runtime failure paths.)



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