This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 598e82f5f fix(format): pass row body size, not full payload size, to 
BinaryRow.pointTo (#3715)
598e82f5f is described below

commit 598e82f5fac0fdfb3871659a5646e0be82f660cc
Author: Steven Schlansker <[email protected]>
AuthorDate: Sun May 31 04:21:18 2026 -0700

    fix(format): pass row body size, not full payload size, to 
BinaryRow.pointTo (#3715)
    
    ## Why?
    
    Minor fixes
    - Latent bug in BinaryRowEncoder exposes 8 bytes beyond end of intended
    buffer to BinaryRow
    - Add reminder documentation for byte[] encoder forms why embedded size
    is ignored. Tripped up both me and Claude
    - Clean up docstring. Identified during AI review of forthcoming feature
    branches
    
    ## AI Contribution Checklist
    
    - [x] Substantial AI assistance was used in this PR: `yes` / `no`
    
    AI Usage Disclosure
    - substantial_ai_assistance: yes
    - scope: all
    - affected_files_or_subsystems: Java row format
    - ai_review: :heavy_check_mark:
    - ai_review_artifacts:
    
    > ● Done. Three commits amended on fory-docs-encoders-cleanup: tightened
    comments, tightened test, tightened commit messages, no functional
    changes since the previous fix was already correct. Force-push when
    you're ready.
    
    - human_verification: :heavy_check_mark:
    - performance_verification: N/A
    - provenance_license_confirmation: :heavy_check_mark:
    
    ## Does this PR introduce any user-facing change?
    
    No
    
    ---------
    
    Co-authored-by: Claude (on behalf of Steven Schlansker) 
<[email protected]>
---
 .../fory/format/encoder/BinaryArrayEncoder.java    |  1 +
 .../fory/format/encoder/BinaryMapEncoder.java      |  1 +
 .../fory/format/encoder/BinaryRowEncoder.java      |  6 +-
 .../org/apache/fory/format/encoder/Encoders.java   |  6 +-
 .../encoder/BinaryRowEncoderPointToTest.java       | 72 ++++++++++++++++++++++
 5 files changed, 79 insertions(+), 7 deletions(-)

diff --git 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryArrayEncoder.java
 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryArrayEncoder.java
index f40a968aa..d1b2b9184 100644
--- 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryArrayEncoder.java
+++ 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryArrayEncoder.java
@@ -62,6 +62,7 @@ class BinaryArrayEncoder<T> implements ArrayEncoder<T> {
 
   @Override
   public T decode(final byte[] bytes) {
+    // byte[] overloads ignore sizeEmbedded: encode writes no size prefix, 
decode uses bytes.length.
     return decode(MemoryUtils.wrap(bytes), bytes.length);
   }
 
diff --git 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryMapEncoder.java
 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryMapEncoder.java
index 925bdc332..90ba96dc5 100644
--- 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryMapEncoder.java
+++ 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryMapEncoder.java
@@ -85,6 +85,7 @@ class BinaryMapEncoder<M> implements MapEncoder<M> {
 
   @Override
   public M decode(final byte[] bytes) {
+    // byte[] overloads ignore sizeEmbedded: encode writes no size prefix, 
decode uses bytes.length.
     return decode(MemoryUtils.wrap(bytes), bytes.length);
   }
 
diff --git 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryRowEncoder.java
 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryRowEncoder.java
index b21bff49e..296ee546f 100644
--- 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryRowEncoder.java
+++ 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/BinaryRowEncoder.java
@@ -81,14 +81,16 @@ class BinaryRowEncoder<T> implements RowEncoder<T> {
                   + "Please check writer schema.",
               schema, schemaHash, peerSchemaHash));
     }
+    final int rowSize = size - 8;
     final BinaryRow row = codecFactory.newRow(schema);
-    row.pointTo(buffer, buffer.readerIndex(), size);
-    buffer.increaseReaderIndex(size - 8);
+    row.pointTo(buffer, buffer.readerIndex(), rowSize);
+    buffer.increaseReaderIndex(rowSize);
     return fromRow(row);
   }
 
   @Override
   public T decode(final byte[] bytes) {
+    // byte[] overloads ignore sizeEmbedded: encode writes no size prefix, 
decode uses bytes.length.
     return decode(MemoryUtils.wrap(bytes), bytes.length);
   }
 
diff --git 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/Encoders.java 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/Encoders.java
index 13403c15f..4a8c45021 100644
--- 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/Encoders.java
+++ 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/Encoders.java
@@ -43,11 +43,7 @@ import org.apache.fory.type.TypeResolutionContext;
 import org.apache.fory.type.TypeUtils;
 import org.apache.fory.util.Preconditions;
 
-/**
- * Factory to create {@link Encoder}.
- *
- * <p>, ganrunsheng
- */
+/** Factory to create {@link Encoder}. */
 public class Encoders {
   private static final Logger LOG = LoggerFactory.getLogger(Encoders.class);
 
diff --git 
a/java/fory-format/src/test/java/org/apache/fory/format/encoder/BinaryRowEncoderPointToTest.java
 
b/java/fory-format/src/test/java/org/apache/fory/format/encoder/BinaryRowEncoderPointToTest.java
new file mode 100644
index 000000000..ff31773c2
--- /dev/null
+++ 
b/java/fory-format/src/test/java/org/apache/fory/format/encoder/BinaryRowEncoderPointToTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fory.format.encoder;
+
+import lombok.Data;
+import org.apache.fory.format.row.binary.BinaryRow;
+import org.apache.fory.format.row.binary.writer.BinaryRowWriter;
+import org.apache.fory.format.type.Schema;
+import org.apache.fory.format.type.TypeInference;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * BinaryRowEncoder.decode must record the row body size on BinaryRow, not the 
full payload size
+ * including the leading 8-byte schema hash.
+ */
+public class BinaryRowEncoderPointToTest {
+
+  @Data
+  public static class Tiny {
+    private int x;
+  }
+
+  @Test
+  public void decodedRowSizeMatchesRowBody() {
+    Schema schema = TypeInference.inferSchema(Tiny.class);
+    RowEncoder<Tiny> real = Encoders.bean(Tiny.class);
+    Tiny in = new Tiny();
+    in.setX(42);
+    byte[] payload = real.encode(in);
+
+    BinaryRow[] captured = new BinaryRow[1];
+    GeneratedRowEncoder captor =
+        new GeneratedRowEncoder() {
+          @Override
+          public BinaryRow toRow(Object obj) {
+            return real.toRow((Tiny) obj);
+          }
+
+          @Override
+          public Object fromRow(BinaryRow row) {
+            captured[0] = row;
+            return null;
+          }
+        };
+
+    BinaryRowEncoder<Tiny> encoder =
+        new BinaryRowEncoder<>(
+            schema, DefaultCodecFormat.INSTANCE, captor, new 
BinaryRowWriter(schema), false);
+    encoder.decode(payload);
+
+    Assert.assertNotNull(captured[0], "decode must hand the row to fromRow");
+    Assert.assertEquals(captured[0].getSizeInBytes(), payload.length - 8);
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to