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 40d1e4c10 fix(java): guard aligned varint unsafe read (#3772)
40d1e4c10 is described below
commit 40d1e4c109940fc023a62203911bc0a878fb3ae7
Author: Shawn Yang <[email protected]>
AuthorDate: Sun Jun 21 08:40:02 2026 +0530
fix(java): guard aligned varint unsafe read (#3772)
## Why?
## What does this PR do?
## Related issues
## AI Contribution Checklist
- [ ] Substantial AI assistance was used in this PR: `yes` / `no`
- [ ] If `yes`, I included a completed [AI Contribution
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
in this PR description and the required `AI Usage Disclosure`.
- [ ] If `yes`, my PR description includes the required `ai_review`
summary and screenshot evidence of the final clean AI review results
from both fresh reviewers on the current PR diff or current HEAD after
the latest code changes.
## Does this PR introduce any user-facing change?
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
---
java/fory-core/pom.xml | 2 ++
.../src/main/java/org/apache/fory/memory/MemoryBuffer.java | 6 ++++--
.../src/main/java25/org/apache/fory/memory/MemoryBuffer.java | 6 ++++--
.../test/java/org/apache/fory/memory/MemoryBufferTest.java | 12 ++++++++++++
.../org/apache/fory/serializer/BufferSerializersTest.java | 11 +++++++++++
5 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/java/fory-core/pom.xml b/java/fory-core/pom.xml
index d8a0784a6..735affa28 100644
--- a/java/fory-core/pom.xml
+++ b/java/fory-core/pom.xml
@@ -452,6 +452,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
+ <!-- Tests use the classpath overlay above, so target the
unnamed-module launch shape. -->
+ <argLine>${argLine}
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED</argLine>
<classesDirectory>${fory.jdk25.test.classes}</classesDirectory>
</configuration>
</plugin>
diff --git
a/java/fory-core/src/main/java/org/apache/fory/memory/MemoryBuffer.java
b/java/fory-core/src/main/java/org/apache/fory/memory/MemoryBuffer.java
index c88cf66e1..94dd96188 100644
--- a/java/fory-core/src/main/java/org/apache/fory/memory/MemoryBuffer.java
+++ b/java/fory-core/src/main/java/org/apache/fory/memory/MemoryBuffer.java
@@ -3020,8 +3020,10 @@ public final class MemoryBuffer {
return MemoryOps.readAlignedVarUInt32(this);
}
int readerIdx = readerIndex;
- // use subtract to avoid overflow
- if (readerIdx < size - 10) {
+ // Use subtraction to avoid overflow. The unrolled Unsafe path assumes the
+ // full aligned-varint scratch range is addressable; short buffers must use
+ // readByte() checks.
+ if (readerIdx > size - 10) {
return slowReadAlignedVarUInt32();
}
long pos = address + readerIdx;
diff --git
a/java/fory-core/src/main/java25/org/apache/fory/memory/MemoryBuffer.java
b/java/fory-core/src/main/java25/org/apache/fory/memory/MemoryBuffer.java
index 309d9e6e4..7fbf021ff 100644
--- a/java/fory-core/src/main/java25/org/apache/fory/memory/MemoryBuffer.java
+++ b/java/fory-core/src/main/java25/org/apache/fory/memory/MemoryBuffer.java
@@ -2965,8 +2965,10 @@ public final class MemoryBuffer {
/** Reads the 1-9 byte int part of an aligned varint. */
public int readAlignedVarUInt32() {
int readerIdx = readerIndex;
- // use subtract to avoid overflow
- if (readerIdx < size - 10) {
+ // Use subtraction to avoid overflow. The unrolled fast path assumes the
+ // full aligned-varint scratch range is inside the logical MemoryBuffer
+ // range; shorter buffers must use readByte() checks.
+ if (readerIdx > size - 10) {
return slowReadAlignedVarUInt32();
}
long pos = address + readerIdx;
diff --git
a/java/fory-core/src/test/java/org/apache/fory/memory/MemoryBufferTest.java
b/java/fory-core/src/test/java/org/apache/fory/memory/MemoryBufferTest.java
index 1054c2a01..363955523 100644
--- a/java/fory-core/src/test/java/org/apache/fory/memory/MemoryBufferTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/memory/MemoryBufferTest.java
@@ -917,6 +917,18 @@ public class MemoryBufferTest {
assertEquals(buffer.readAlignedVarUInt32(), Integer.MAX_VALUE);
}
+ @Test
+ public void testReadAlignedVarUInt32Bounds() {
+ assertThrows(
+ IndexOutOfBoundsException.class,
+ () -> MemoryBuffer.fromByteArray(new byte[] {(byte)
0xff}).readAlignedVarUInt32());
+ assertThrows(
+ IndexOutOfBoundsException.class,
+ () ->
+ MemoryBuffer.fromByteArray(new byte[] {(byte) 0xff, 0x40}, 0, 1)
+ .readAlignedVarUInt32());
+ }
+
@Test
public void testGetShortB() {
byte[] data = new byte[4];
diff --git
a/java/fory-core/src/test/java/org/apache/fory/serializer/BufferSerializersTest.java
b/java/fory-core/src/test/java/org/apache/fory/serializer/BufferSerializersTest.java
index 6d44bbf57..c8cccfeed 100644
---
a/java/fory-core/src/test/java/org/apache/fory/serializer/BufferSerializersTest.java
+++
b/java/fory-core/src/test/java/org/apache/fory/serializer/BufferSerializersTest.java
@@ -74,6 +74,17 @@ public class BufferSerializersTest extends ForyTestBase {
DeserializationException.class, () -> readSerializer(fory, serializer,
invalidOrder));
}
+ @Test
+ public void testByteBufferRejectsTruncatedSize() {
+ Fory fory = Fory.builder().withXlang(false).withCompatible(false).build();
+ Serializer<ByteBuffer> serializer =
+ new BufferSerializers.ByteBufferSerializer(fory.getTypeResolver(),
ByteBuffer.class);
+
+ MemoryBuffer truncatedSize = MemoryBuffer.fromByteArray(new byte[] {1,
(byte) 0xff});
+ org.testng.Assert.assertThrows(
+ IndexOutOfBoundsException.class, () -> readSerializer(fory,
serializer, truncatedSize));
+ }
+
@Test
public void testBufferObjectRejectsInvalidInBandSizeWithoutBinaryCap() {
Fory fory = Fory.builder().withXlang(true).withCompatible(false).build();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]