This is an automated email from the ASF dual-hosted git repository.
FrankChen021 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 195d1e1b847 fix: validate blockSize and numBlocks in
CompressedBlockReader (#20243)
195d1e1b847 is described below
commit 195d1e1b847d25737f01d61fcee6613155e971f6
Author: dfengliu <[email protected]>
AuthorDate: Fri Sep 4 10:28:55 2026 +0800
fix: validate blockSize and numBlocks in CompressedBlockReader (#20243)
* fix: validate blockSize and numBlocks in CompressedBlockReader
* fix checkstyle: end file with newline, keep call args on single line
* fix: pass numBlocks to format string to satisfy Error Prone
LenientFormatStringValidation
---
.../druid/segment/data/CompressedBlockReader.java | 7 ++
.../segment/data/CompressedBlockReaderTest.java | 106 +++++++++++++++++++++
2 files changed, 113 insertions(+)
diff --git
a/processing/src/main/java/org/apache/druid/segment/data/CompressedBlockReader.java
b/processing/src/main/java/org/apache/druid/segment/data/CompressedBlockReader.java
index 78138a5aa53..76e9e00e10b 100644
---
a/processing/src/main/java/org/apache/druid/segment/data/CompressedBlockReader.java
+++
b/processing/src/main/java/org/apache/druid/segment/data/CompressedBlockReader.java
@@ -72,7 +72,14 @@ public final class CompressedBlockReader implements Closeable
blockSize <= CompressedPools.BUFFER_SIZE,
"Maximum block size must be less than " + CompressedPools.BUFFER_SIZE
);
+ Preconditions.checkArgument(blockSize > 0, "Block size[%s] must be
positive", blockSize);
final int numBlocks = buffer.getInt();
+ Preconditions.checkArgument(numBlocks > 0, "Number of blocks[%s] must be
positive", numBlocks);
+ Preconditions.checkArgument(
+ (long) numBlocks * Integer.BYTES <= buffer.remaining(),
+ "Number of blocks[%s] exceeds the available buffer",
+ numBlocks
+ );
final int offsetsSize = numBlocks * Integer.BYTES;
// buffer is at start of ending offsets
final ByteBuffer offsets =
buffer.asReadOnlyBuffer().order(compressionOrder);
diff --git
a/processing/src/test/java/org/apache/druid/segment/data/CompressedBlockReaderTest.java
b/processing/src/test/java/org/apache/druid/segment/data/CompressedBlockReaderTest.java
new file mode 100644
index 00000000000..b247ccfdaad
--- /dev/null
+++
b/processing/src/test/java/org/apache/druid/segment/data/CompressedBlockReaderTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.druid.segment.data;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class CompressedBlockReaderTest
+{
+ private static ByteBuffer header(int blockSize, int numBlocks)
+ {
+ final ByteBuffer buffer =
ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+ buffer.put(CompressedBlockReader.VERSION);
+ buffer.put(CompressionStrategy.UNCOMPRESSED.getId());
+ buffer.putInt(blockSize);
+ buffer.putInt(numBlocks);
+ buffer.flip();
+ return buffer;
+ }
+
+ @Test
+ public void testNumBlocksZeroRejected()
+ {
+ final IllegalArgumentException e = Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> CompressedBlockReader.fromByteBuffer(
+ header(64, 0), ByteOrder.nativeOrder(), ByteOrder.nativeOrder(),
false
+ )
+ );
+ Assertions.assertTrue(e.getMessage().contains("Number of blocks[0] must be
positive"), e.getMessage());
+ }
+
+ @Test
+ public void testNumBlocksNegativeRejected()
+ {
+ final IllegalArgumentException e = Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> CompressedBlockReader.fromByteBuffer(
+ header(64, -5), ByteOrder.nativeOrder(), ByteOrder.nativeOrder(),
false
+ )
+ );
+ Assertions.assertTrue(e.getMessage().contains("Number of blocks[-5] must
be positive"), e.getMessage());
+ }
+
+ @Test
+ public void testBlockSizeZeroRejected()
+ {
+ final IllegalArgumentException e = Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> CompressedBlockReader.fromByteBuffer(
+ header(0, 1), ByteOrder.nativeOrder(), ByteOrder.nativeOrder(),
false
+ )
+ );
+ Assertions.assertTrue(e.getMessage().contains("Block size[0] must be
positive"), e.getMessage());
+ }
+
+ @Test
+ public void testNumBlocksBeyondBufferRejected()
+ {
+ final IllegalArgumentException e = Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () -> CompressedBlockReader.fromByteBuffer(
+ header(64, 32), ByteOrder.nativeOrder(), ByteOrder.nativeOrder(),
false
+ )
+ );
+ Assertions.assertTrue(e.getMessage().contains("exceeds the available
buffer"), e.getMessage());
+ }
+
+ @Test
+ public void testValidHeaderAccepted()
+ {
+ final ByteBuffer buffer =
ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+ buffer.put(CompressedBlockReader.VERSION);
+ buffer.put(CompressionStrategy.UNCOMPRESSED.getId());
+ buffer.putInt(64); // blockSize
+ buffer.putInt(2); // numBlocks
+ buffer.putInt(4); // offsets
+ buffer.putInt(8);
+ buffer.putInt(0); // compressed bytes
+ buffer.putInt(0);
+ buffer.flip();
+
+ CompressedBlockReader.fromByteBuffer(buffer, ByteOrder.nativeOrder(),
ByteOrder.nativeOrder(), false);
+ Assertions.assertTrue(true);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]