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


##########
lang/c++/impl/Generic.cc:
##########
@@ -25,6 +26,88 @@ using std::ostringstream;
 using std::string;
 using std::vector;
 
+// Minimum number of bytes a single value of the given schema node 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 collection check for it (so an array of nulls is not
+// falsely rejected). A depth limit breaks self-referencing (symbolic) schemas.
+static int64_t minBytesPerElement(const NodePtr &node, int depth) {
+    if (!node) {
+        return 0;
+    }
+    switch (node->type()) {
+        case AVRO_NULL:
+            return 0;
+        case AVRO_FLOAT:
+            return 4;
+        case AVRO_DOUBLE:
+            return 8;
+        case AVRO_FIXED: {
+            // fixedSize() is a size_t; clamp to int64_t so a huge fixed size
+            // cannot wrap negative.
+            size_t sz = node->fixedSize();
+            return sz > 
static_cast<size_t>(std::numeric_limits<int64_t>::max())
+                       ? std::numeric_limits<int64_t>::max()
+                       : static_cast<int64_t>(sz);
+        }
+        case AVRO_RECORD: {
+            if (depth > 64) {
+                // A cyclic or pathologically deep record. Return 1 (not 0) so 
the
+                // collection check stays enabled rather than being silently
+                // bypassed; a valid recursive value always encodes to >= 1 
byte.
+                // (The depth guard is applied only here, so zero-byte leaf 
types

Review Comment:
   Good point. Fixed in bf25d413cf: the depth guard now returns 0 (a valid 
conservative lower bound) instead of 1. A truly cyclic schema never reaches the 
guard because a self-reference is an AVRO_SYMBOLIC node handled by the default 
case (returning 1 without following the link), so recursion always terminates; 
the guard is purely a stack-overflow safety net for a genuinely deep *acyclic* 
record, where returning 1 would over-estimate and could falsely reject a valid 
array/map of null-leaf records. Added 
testReadArrayOfDeeplyNestedNullNotFalselyRejected with a ~70-level nested 
null-leaf record.



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