Skip to content

Commit 929df5d

Browse files
committed
Conversion.hexTo*() methods now throw IllegalArgumentException instead
of StringIndexOutOfBoundsException Better exception messages
1 parent bf42165 commit 929df5d

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

src/main/java/org/apache/commons/lang3/Conversion.java

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -776,25 +776,25 @@ public static int hexDigitToInt(final char hexDigit) {
776776
}
777777

778778
/**
779-
* Converts a hexadecimal string into a byte using the default (little-endian, Lsb0) byte and
780-
* bit ordering.
779+
* Converts a hexadecimal string into a byte using the default (little-endian, Lsb0) byte and bit ordering.
781780
*
782-
* @param src the hexadecimal string to convert
783-
* @param srcPos the position in {@code src}, in Char unit, from where to start the
784-
* conversion
785-
* @param dstInit initial value of the destination byte
786-
* @param dstPos the position of the LSB, in bits, in the result byte
787-
* @param nHex the number of Chars to convert
788-
* @return a byte containing the selected bits
789-
* @throws IllegalArgumentException if {@code (nHex-1)*4+dstPos >= 8}
781+
* @param src the hexadecimal string to convert.
782+
* @param srcPos the position in {@code src}, in char unit, from where to start the conversion.
783+
* @param dstInit initial value of the destination byte.
784+
* @param dstPos the position of the LSB, in bits, in the result byte.
785+
* @param nHex the number of Chars to convert.
786+
* @return a byte containing the selected bits.
787+
* @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 8}.
790788
*/
791-
public static byte hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos,
792-
final int nHex) {
789+
public static byte hexToByte(final String src, final int srcPos, final byte dstInit, final int dstPos, final int nHex) {
793790
if (0 == nHex) {
794791
return dstInit;
795792
}
796793
if ((nHex - 1) * 4 + dstPos >= 8) {
797-
throw new IllegalArgumentException("(nHex-1)*4+dstPos is greater than or equal to 8");
794+
throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater than or equal to 8");
795+
}
796+
if (srcPos + nHex > src.length()) {
797+
throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d > src.length()", srcPos, nHex, src.length()));
798798
}
799799
byte out = dstInit;
800800
for (int i = 0; i < nHex; i++) {
@@ -811,20 +811,23 @@ public static byte hexToByte(final String src, final int srcPos, final byte dstI
811811
* ordering.
812812
*
813813
* @param src the hexadecimal string to convert
814-
* @param srcPos the position in {@code src}, in Char unit, from where to start the
814+
* @param srcPos the position in {@code src}, in char unit, from where to start the
815815
* conversion
816816
* @param dstInit initial value of the destination int
817817
* @param dstPos the position of the LSB, in bits, in the result int
818818
* @param nHex the number of Chars to convert
819819
* @return an int containing the selected bits
820-
* @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 32}
820+
* @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 32}
821821
*/
822822
public static int hexToInt(final String src, final int srcPos, final int dstInit, final int dstPos, final int nHex) {
823823
if (0 == nHex) {
824824
return dstInit;
825825
}
826826
if ((nHex - 1) * 4 + dstPos >= 32) {
827-
throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 32");
827+
throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 32");
828+
}
829+
if (srcPos + nHex > src.length()) {
830+
throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d > src.length()", srcPos, nHex, src.length()));
828831
}
829832
int out = dstInit;
830833
for (int i = 0; i < nHex; i++) {
@@ -841,21 +844,24 @@ public static int hexToInt(final String src, final int srcPos, final int dstInit
841844
* bit ordering.
842845
*
843846
* @param src the hexadecimal string to convert
844-
* @param srcPos the position in {@code src}, in Char unit, from where to start the
847+
* @param srcPos the position in {@code src}, in char unit, from where to start the
845848
* conversion
846849
* @param dstInit initial value of the destination long
847850
* @param dstPos the position of the LSB, in bits, in the result long
848851
* @param nHex the number of Chars to convert
849852
* @return a long containing the selected bits
850-
* @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 64}
853+
* @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 64}
851854
*/
852855
public static long hexToLong(final String src, final int srcPos, final long dstInit, final int dstPos,
853856
final int nHex) {
854857
if (0 == nHex) {
855858
return dstInit;
856859
}
857860
if ((nHex - 1) * 4 + dstPos >= 64) {
858-
throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 64");
861+
throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 64");
862+
}
863+
if (srcPos + nHex > src.length()) {
864+
throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d > src.length()", srcPos, nHex, src.length()));
859865
}
860866
long out = dstInit;
861867
for (int i = 0; i < nHex; i++) {
@@ -872,21 +878,24 @@ public static long hexToLong(final String src, final int srcPos, final long dstI
872878
* bit ordering.
873879
*
874880
* @param src the hexadecimal string to convert
875-
* @param srcPos the position in {@code src}, in Char unit, from where to start the
881+
* @param srcPos the position in {@code src}, in char unit, from where to start the
876882
* conversion
877883
* @param dstInit initial value of the destination short
878884
* @param dstPos the position of the LSB, in bits, in the result short
879885
* @param nHex the number of Chars to convert
880886
* @return a short containing the selected bits
881-
* @throws IllegalArgumentException if {@code (nHexs-1)*4+dstPos >= 16}
887+
* @throws IllegalArgumentException Thrown on invalid input like {@code (nHex - 1) * 4 + dstPos >= 16}
882888
*/
883889
public static short hexToShort(final String src, final int srcPos, final short dstInit, final int dstPos,
884890
final int nHex) {
885891
if (0 == nHex) {
886892
return dstInit;
887893
}
888894
if ((nHex - 1) * 4 + dstPos >= 16) {
889-
throw new IllegalArgumentException("(nHexs-1)*4+dstPos is greater or equal to than 16");
895+
throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos is greater or equal to than 16");
896+
}
897+
if (srcPos + nHex > src.length()) {
898+
throw new IllegalArgumentException(String.format("srcPos %,d, + nHex %,d > src.length()", srcPos, nHex, src.length()));
890899
}
891900
short out = dstInit;
892901
for (int i = 0; i < nHex; i++) {

src/test/java/org/apache/commons/lang3/ConversionTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
*/
1717
package org.apache.commons.lang3;
1818

19-
import static org.apache.commons.lang3.LangAssertions.assertIndexOutOfBoundsException;
2019
import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
20+
import static org.apache.commons.lang3.LangAssertions.assertIndexOutOfBoundsException;
2121
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2222
import static org.junit.jupiter.api.Assertions.assertEquals;
2323
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -708,6 +708,7 @@ void testHexToByte() {
708708
assertEquals((byte) 0xFD, Conversion.hexToByte(src, 1, (byte) 0, 0, 2));
709709
assertEquals((byte) 0x34, Conversion.hexToByte(src, 0, (byte) 0x34, 0, 0));
710710
assertEquals((byte) 0x84, Conversion.hexToByte(src, 17, (byte) 0x34, 4, 1));
711+
assertThrows(IllegalArgumentException.class, () -> Conversion.hexToByte(src, src.length(), (byte) 0, 0, 1));
711712
}
712713

713714
/**
@@ -722,6 +723,7 @@ void testHexToInt() {
722723
assertEquals(0x01C0F1FD, Conversion.hexToInt(src, 1, 0, 0, 8));
723724
assertEquals(0x12345679, Conversion.hexToInt(src, 0, 0x12345679, 0, 0));
724725
assertEquals(0x87645679, Conversion.hexToInt(src, 15, 0x12345679, 20, 3));
726+
assertThrows(IllegalArgumentException.class, () -> Conversion.hexToInt(src, src.length(), 0, 0, 1));
725727
}
726728

727729
/**
@@ -734,10 +736,9 @@ void testHexToLong() {
734736
assertEquals(0x000000000000000CL, Conversion.hexToLong(src, 0, 0L, 0, 1));
735737
assertEquals(0x000000001C0F1FDCL, Conversion.hexToLong(src, 0, 0L, 0, 8));
736738
assertEquals(0x0000000001C0F1FDL, Conversion.hexToLong(src, 1, 0L, 0, 8));
737-
assertEquals(
738-
0x123456798ABCDEF0L, Conversion.hexToLong(src, 0, 0x123456798ABCDEF0L, 0, 0));
739-
assertEquals(
740-
0x1234567876BCDEF0L, Conversion.hexToLong(src, 15, 0x123456798ABCDEF0L, 24, 3));
739+
assertEquals(0x123456798ABCDEF0L, Conversion.hexToLong(src, 0, 0x123456798ABCDEF0L, 0, 0));
740+
assertEquals(0x1234567876BCDEF0L, Conversion.hexToLong(src, 15, 0x123456798ABCDEF0L, 24, 3));
741+
assertThrows(IllegalArgumentException.class, () -> Conversion.hexToLong(src, src.length(), 0, 0, 1));
741742
}
742743

743744
/**
@@ -752,6 +753,7 @@ void testHexToShort() {
752753
assertEquals((short) 0xF1FD, Conversion.hexToShort(src, 1, (short) 0, 0, 4));
753754
assertEquals((short) 0x1234, Conversion.hexToShort(src, 0, (short) 0x1234, 0, 0));
754755
assertEquals((short) 0x8764, Conversion.hexToShort(src, 15, (short) 0x1234, 4, 3));
756+
assertThrows(IllegalArgumentException.class, () -> Conversion.hexToShort(src, src.length(), (short) 0, 0, 1));
755757
}
756758

757759
/**

0 commit comments

Comments
 (0)