You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by do...@apache.org on 2026/06/15 19:13:48 UTC
(spark) branch master updated: [SPARK-57474][CORE] Validate length before allocation in `Encoders.StringArrays.decode`
This is an automated email from the ASF dual-hosted git repository.
dongjoon-hyun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 0caf79030573 [SPARK-57474][CORE] Validate length before allocation in `Encoders.StringArrays.decode`
0caf79030573 is described below
commit 0caf79030573233c6db526a4289499f8756adeaf
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Mon Jun 15 12:13:35 2026 -0700
[SPARK-57474][CORE] Validate length before allocation in `Encoders.StringArrays.decode`
### What changes were proposed in this pull request?
`Encoders.StringArrays.decode()` now validates the count prefix before allocating the array via `Objects.checkFromIndexSize(0, numStrings, buf.readableBytes() / 4)`, which requires `0 <= numStrings <= buf.readableBytes() / 4` and throws `IndexOutOfBoundsException` otherwise. The divisor `4` is the minimum on-wire size of one element, since `Strings.encode` always writes a 4-byte length prefix like the following.
https://github.com/apache/spark/blob/118026dc9b9693613aab96ae6f4a3c126c6c3fdf/common/network-common/src/main/java/org/apache/spark/network/protocol/Encoders.java#L37-L41
### Why are the changes needed?
`decode()` allocated `new String[numStrings]` from an untrusted count.
- A negative value throws an opaque `NegativeArraySizeException`.
- An oversized value can trigger `OutOfMemoryError` on a corrupt or hostile frame.
Validating first fails fast with a clear error.
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Pass the CIs with newly added test cases.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 4.8)
Closes #56521 from dongjoon-hyun/SPARK-57474.
Authored-by: Dongjoon Hyun <do...@apache.org>
Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
.../apache/spark/network/protocol/Encoders.java | 1 +
.../spark/network/protocol/EncodersSuite.java | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/common/network-common/src/main/java/org/apache/spark/network/protocol/Encoders.java b/common/network-common/src/main/java/org/apache/spark/network/protocol/Encoders.java
index d69ad7c1f9ce..a91200e825d2 100644
--- a/common/network-common/src/main/java/org/apache/spark/network/protocol/Encoders.java
+++ b/common/network-common/src/main/java/org/apache/spark/network/protocol/Encoders.java
@@ -133,6 +133,7 @@ public class Encoders {
public static String[] decode(ByteBuf buf) {
int numStrings = buf.readInt();
+ Objects.checkFromIndexSize(0, numStrings, buf.readableBytes() / 4);
String[] strings = new String[numStrings];
for (int i = 0; i < strings.length; i ++) {
strings[i] = Strings.decode(buf);
diff --git a/common/network-common/src/test/java/org/apache/spark/network/protocol/EncodersSuite.java b/common/network-common/src/test/java/org/apache/spark/network/protocol/EncodersSuite.java
index 0a07ebf17ded..24b766639210 100644
--- a/common/network-common/src/test/java/org/apache/spark/network/protocol/EncodersSuite.java
+++ b/common/network-common/src/test/java/org/apache/spark/network/protocol/EncodersSuite.java
@@ -154,4 +154,26 @@ public class EncodersSuite {
buf.writeInt(Integer.MAX_VALUE);
assertThrows(IndexOutOfBoundsException.class, () -> Encoders.LongArrays.decode(buf));
}
+
+ @Test
+ public void testStringArraysEncodeDecode() {
+ String[] arr = new String[] { "spark", "", "rocks" };
+ ByteBuf buf = Unpooled.buffer(Encoders.StringArrays.encodedLength(arr));
+ Encoders.StringArrays.encode(buf, arr);
+ assertArrayEquals(arr, Encoders.StringArrays.decode(buf));
+ }
+
+ @Test
+ public void testStringArraysDecodeShouldFailWhenLengthIsNegative() {
+ ByteBuf buf = Unpooled.buffer();
+ buf.writeInt(-1);
+ assertThrows(IndexOutOfBoundsException.class, () -> Encoders.StringArrays.decode(buf));
+ }
+
+ @Test
+ public void testStringArraysDecodeShouldFailWhenLengthExceedsReadableBytes() {
+ ByteBuf buf = Unpooled.buffer();
+ buf.writeInt(Integer.MAX_VALUE);
+ assertThrows(IndexOutOfBoundsException.class, () -> Encoders.StringArrays.decode(buf));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org