From 9d9994e111b240782cac7f9758e2be6777fd48f6 Mon Sep 17 00:00:00 2001 From: Eduard Tudenhoefner Date: Thu, 2 Jul 2026 09:07:30 +0200 Subject: [PATCH] Throw IAE when dealing with odd-length/invalid hex string in Parquet CLI --- .../org/apache/parquet/cli/BaseCommand.java | 13 +++++++++--- .../apache/parquet/cli/BaseCommandTest.java | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/parquet-cli/src/main/java/org/apache/parquet/cli/BaseCommand.java b/parquet-cli/src/main/java/org/apache/parquet/cli/BaseCommand.java index 0c8841b05c..9e12102e02 100644 --- a/parquet-cli/src/main/java/org/apache/parquet/cli/BaseCommand.java +++ b/parquet-cli/src/main/java/org/apache/parquet/cli/BaseCommand.java @@ -20,6 +20,7 @@ package org.apache.parquet.cli; import com.beust.jcommander.internal.Lists; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.io.CharStreams; import com.google.common.io.Resources; @@ -428,16 +429,22 @@ private void parseAndSetColumnKeys(String columnKeysStr, ConfigurableKeyRetrieve } } - private byte[] hexToBytes(String hex) { - + @VisibleForTesting + byte[] hexToBytes(String hex) { + String originalHex = hex; if (hex.startsWith("0x") || hex.startsWith("0X")) { hex = hex.substring(2); } int len = hex.length(); + Preconditions.checkArgument(len % 2 == 0, "Invalid hex string: %s", originalHex); + byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16)); + int high = Character.digit(hex.charAt(i), 16); + int low = Character.digit(hex.charAt(i + 1), 16); + Preconditions.checkArgument(high >= 0 && low >= 0, "Invalid hex string: %s", originalHex); + data[i / 2] = (byte) ((high << 4) + low); } return data; } diff --git a/parquet-cli/src/test/java/org/apache/parquet/cli/BaseCommandTest.java b/parquet-cli/src/test/java/org/apache/parquet/cli/BaseCommandTest.java index 1f441c3348..e74a410bc3 100644 --- a/parquet-cli/src/test/java/org/apache/parquet/cli/BaseCommandTest.java +++ b/parquet-cli/src/test/java/org/apache/parquet/cli/BaseCommandTest.java @@ -62,6 +62,27 @@ public void qualifiedURIResourceURITest() throws IOException { Assert.assertEquals("/a", uri.getPath()); } + @Test + public void hexToBytes() { + Assert.assertArrayEquals(new byte[] {0x10}, this.command.hexToBytes("0x10")); + Assert.assertArrayEquals(new byte[] {0x05, 0x06}, this.command.hexToBytes("0x0506")); + Assert.assertArrayEquals(new byte[] {0x05, 0x06}, this.command.hexToBytes("0506")); + Assert.assertArrayEquals(new byte[] {0x01, 0x02, 0x03}, this.command.hexToBytes("0x010203")); + } + + @Test + public void hexToBytesRejectsInvalidHexString() { + IllegalArgumentException ex = + Assert.assertThrows(IllegalArgumentException.class, () -> this.command.hexToBytes("0x011")); + Assert.assertEquals("Invalid hex string: 0x011", ex.getMessage()); + + ex = Assert.assertThrows(IllegalArgumentException.class, () -> this.command.hexToBytes("0xABZZ")); + Assert.assertEquals("Invalid hex string: 0xABZZ", ex.getMessage()); + + ex = Assert.assertThrows(IllegalArgumentException.class, () -> this.command.hexToBytes("0xabgg")); + Assert.assertEquals("Invalid hex string: 0xabgg", ex.getMessage()); + } + // For Windows @Test public void qualifiedPathTestForWindows() throws IOException {