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


##########
lang/ruby/lib/avro/io.rb:
##########
@@ -496,6 +541,45 @@ def skip_record(writers_schema, decoder)
       end
 
       private
+      # Minimum number of bytes a single value of the given schema can occupy 
on
+      # the wire. Used to reject an array/map block count that could not be
+      # backed by the bytes remaining. A type that can encode to zero bytes
+      # (null) returns 0, which disables the check for it (so an array of nulls
+      # is not falsely rejected).
+      def min_bytes_per_element(schema, visited = nil)
+        visited ||= {}.compare_by_identity
+        case schema.type_sym
+        when :null then 0
+        when :float then 4
+        when :double then 8
+        when :fixed then schema.size
+        when :record, :error, :request
+          return 0 if visited[schema]
+          visited[schema] = true
+          total = schema.fields.sum { |field| 
min_bytes_per_element(field.type, visited) }
+          visited.delete(schema)
+          total
+        else
+          # boolean, int, long, bytes, string, enum, union, array, map: >= 1 
byte
+          # (a union encodes at least a 1-byte branch index).
+          1
+        end
+      end
+
+      # 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 or when the reader cannot
+      # report how many bytes remain.
+      def ensure_collection_available(decoder, count, min_bytes_per_element)
+        return if count <= 0 || min_bytes_per_element <= 0
+        remaining = decoder.bytes_remaining
+        # Compare via integer division rather than multiplying, so a huge count
+        # does not create a large intermediate product.
+        if remaining && count > remaining / min_bytes_per_element
+          raise AvroError, "Collection claims #{count} elements with at least 
#{min_bytes_per_element} bytes each, but only #{remaining} bytes are available"
+        end
+      end

Review Comment:
   `ensure_collection_available` unconditionally calls 
`decoder.bytes_remaining`. Any decoder that implements the read protocol 
(`read_long`, `read_string`, etc.) but does not implement `bytes_remaining` 
will now raise `NoMethodError`, even though the intended behavior for “cannot 
report remaining size” is to skip the check. Guard this call with `respond_to?` 
(or rescue `NoMethodError`) and treat the remaining size as unknown (`nil`).



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