From 93fb43470169457a22a78e6748854fbd5f49d058 Mon Sep 17 00:00:00 2001 From: liufeng Date: Thu, 27 Aug 2026 21:02:02 +0800 Subject: [PATCH] fix: validate numBytes in CompressedVSizeColumnarIntsSupplier --- .../CompressedVSizeColumnarIntsSupplier.java | 6 +++++ ...mpressedVSizeColumnarIntsSupplierTest.java | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplier.java b/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplier.java index deddbd8bc2a1..5063e1e23073 100644 --- a/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplier.java +++ b/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplier.java @@ -69,6 +69,12 @@ private CompressedVSizeColumnarIntsSupplier( sizePer == (1 << Integer.numberOfTrailingZeros(sizePer)), "Number of entries per chunk must be a power of 2" ); + Preconditions.checkArgument( + numBytes >= 1 && numBytes <= Integer.BYTES, + "Invalid numBytes[%s] in CompressedVSizeColumnarIntsSupplier. Must be in range[1, %s]", + numBytes, + Integer.BYTES + ); this.totalSize = totalSize; this.sizePer = sizePer; diff --git a/processing/src/test/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplierTest.java b/processing/src/test/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplierTest.java index 0a56d27348f3..cb51186c388a 100644 --- a/processing/src/test/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplierTest.java +++ b/processing/src/test/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplierTest.java @@ -243,6 +243,30 @@ public void testSanityWithSerde() throws Exception assertIndexMatchesVals(); } + @Test + public void testInvalidNumBytesRejected() throws Exception + { + vals = new int[]{0, 1, 2, 3}; + CloseableUtils.closeAndWrapExceptions(columnarInts); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final CompressedVSizeColumnarIntsSupplier serialized = CompressedVSizeColumnarIntsSupplier.fromList( + IntArrayList.wrap(vals), Ints.max(vals), 4, byteOrder, compressionStrategy, closer + ); + serialized.writeTo(Channels.newChannel(baos), null); + final byte[] bytes = baos.toByteArray(); + + for (byte invalidNumBytes : new byte[]{0, 5, 100, -1}) { + final byte[] corrupted = bytes.clone(); + corrupted[1] = invalidNumBytes; + final IllegalArgumentException e = Assertions.assertThrows( + IllegalArgumentException.class, + () -> CompressedVSizeColumnarIntsSupplier.fromByteBuffer(ByteBuffer.wrap(corrupted), byteOrder, null) + ); + Assertions.assertTrue(e.getMessage().contains("numBytes"), e.getMessage()); + } + } + // This test attempts to cause a race condition with the DirectByteBuffers, it's non-deterministic in causing it, // which sucks but I can't think of a way to deterministically cause it...