This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push:
new 0edbb4ae0 fix int overflow in Conversion count and position bounds
guards (#1779)
0edbb4ae0 is described below
commit 0edbb4ae03fbe14a8204dbb866b0a17f22a4c6f1
Author: alhuda <[email protected]>
AuthorDate: Wed Sep 2 02:25:28 2026 +0530
fix int overflow in Conversion count and position bounds guards (#1779)
* fix int overflow in Conversion count and position bounds guards
* Better test method name.
---------
Co-authored-by: Gary Gregory <[email protected]>
---
.../java/org/apache/commons/lang3/Conversion.java | 56 +++++++++++-----------
.../org/apache/commons/lang3/ConversionTest.java | 45 +++++++++++++++++
2 files changed, 73 insertions(+), 28 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/Conversion.java
b/src/main/java/org/apache/commons/lang3/Conversion.java
index b91e52e76..cf43e36c3 100644
--- a/src/main/java/org/apache/commons/lang3/Conversion.java
+++ b/src/main/java/org/apache/commons/lang3/Conversion.java
@@ -160,7 +160,7 @@ public static byte binaryToByte(final boolean[] src, final
int srcPos, final byt
if (src.length == 0 && srcPos == 0 || 0 == nBools) {
return dstInit;
}
- if (nBools - 1 + dstPos >= Byte.SIZE) {
+ if ((long) nBools - 1 + dstPos >= Byte.SIZE) {
throw new IllegalArgumentException("nBools - 1 + dstPos >= 8");
}
byte out = dstInit;
@@ -307,7 +307,7 @@ public static int binaryToInt(final boolean[] src, final
int srcPos, final int d
if (src.length == 0 && srcPos == 0 || 0 == nBools) {
return dstInit;
}
- if (nBools - 1 + dstPos >= Integer.SIZE) {
+ if ((long) nBools - 1 + dstPos >= Integer.SIZE) {
throw new IllegalArgumentException("nBools - 1 + dstPos >= 32");
}
int out = dstInit;
@@ -337,7 +337,7 @@ public static long binaryToLong(final boolean[] src, final
int srcPos, final lon
if (src.length == 0 && srcPos == 0 || 0 == nBools) {
return dstInit;
}
- if (nBools - 1 + dstPos >= Long.SIZE) {
+ if ((long) nBools - 1 + dstPos >= Long.SIZE) {
throw new IllegalArgumentException("nBools - 1 + dstPos >= 64");
}
long out = dstInit;
@@ -367,7 +367,7 @@ public static short binaryToShort(final boolean[] src,
final int srcPos, final s
if (src.length == 0 && srcPos == 0 || 0 == nBools) {
return dstInit;
}
- if (nBools - 1 + dstPos >= Short.SIZE) {
+ if ((long) nBools - 1 + dstPos >= Short.SIZE) {
throw new IllegalArgumentException("nBools - 1 + dstPos >= 16");
}
short out = dstInit;
@@ -397,7 +397,7 @@ public static int byteArrayToInt(final byte[] src, final
int srcPos, final int d
if (src.length == 0 && srcPos == 0 || 0 == nBytes) {
return dstInit;
}
- if ((nBytes - 1) * Byte.SIZE + dstPos >= Integer.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + dstPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + dstPos >=
32");
}
int out = dstInit;
@@ -427,7 +427,7 @@ public static long byteArrayToLong(final byte[] src, final
int srcPos, final lon
if (src.length == 0 && srcPos == 0 || 0 == nBytes) {
return dstInit;
}
- if ((nBytes - 1) * Byte.SIZE + dstPos >= Long.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + dstPos >= Long.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + dstPos >=
64");
}
long out = dstInit;
@@ -457,7 +457,7 @@ public static short byteArrayToShort(final byte[] src,
final int srcPos, final s
if (src.length == 0 && srcPos == 0 || 0 == nBytes) {
return dstInit;
}
- if ((nBytes - 1) * Byte.SIZE + dstPos >= Short.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + dstPos >= Short.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + dstPos >=
16");
}
short out = dstInit;
@@ -503,7 +503,7 @@ public static boolean[] byteToBinary(final byte src, final
int srcPos, final boo
if (0 == nBools) {
return dst;
}
- if (nBools - 1 + srcPos >= Byte.SIZE) {
+ if ((long) nBools - 1 + srcPos >= Byte.SIZE) {
throw new IllegalArgumentException("nBools - 1 + srcPos >= 8");
}
for (int i = 0; i < nBools; i++) {
@@ -529,7 +529,7 @@ public static String byteToHex(final byte src, final int
srcPos, final String ds
if (0 == nHexs) {
return dstInit;
}
- if ((nHexs - 1) * 4 + srcPos >= Byte.SIZE) {
+ if (((long) nHexs - 1) * 4 + srcPos >= Byte.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + srcPos >=
8");
}
final StringBuilder sb = new StringBuilder(dstInit);
@@ -748,7 +748,7 @@ public static byte hexToByte(final String src, final int
srcPos, final byte dstI
if (0 == nHex) {
return dstInit;
}
- if ((nHex - 1) * 4 + dstPos >= Byte.SIZE) {
+ if (((long) nHex - 1) * 4 + dstPos >= Byte.SIZE) {
throw new IllegalArgumentException("(nHex - 1) * 4 + dstPos >= 8");
}
byte out = dstInit;
@@ -776,7 +776,7 @@ public static int hexToInt(final String src, final int
srcPos, final int dstInit
if (0 == nHex) {
return dstInit;
}
- if ((nHex - 1) * 4 + dstPos >= Integer.SIZE) {
+ if (((long) nHex - 1) * 4 + dstPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + dstPos >=
32");
}
int out = dstInit;
@@ -804,7 +804,7 @@ public static long hexToLong(final String src, final int
srcPos, final long dstI
if (0 == nHex) {
return dstInit;
}
- if ((nHex - 1) * 4 + dstPos >= Long.SIZE) {
+ if (((long) nHex - 1) * 4 + dstPos >= Long.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + dstPos >=
64");
}
long out = dstInit;
@@ -832,7 +832,7 @@ public static short hexToShort(final String src, final int
srcPos, final short d
if (0 == nHex) {
return dstInit;
}
- if ((nHex - 1) * 4 + dstPos >= Short.SIZE) {
+ if (((long) nHex - 1) * 4 + dstPos >= Short.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + dstPos >=
16");
}
short out = dstInit;
@@ -862,7 +862,7 @@ public static long intArrayToLong(final int[] src, final
int srcPos, final long
if (src.length == 0 && srcPos == 0 || 0 == nInts) {
return dstInit;
}
- if ((nInts - 1) * Integer.SIZE + dstPos >= Long.SIZE) {
+ if (((long) nInts - 1) * Integer.SIZE + dstPos >= Long.SIZE) {
throw new IllegalArgumentException("(nInts - 1) * 32 + dstPos >=
64");
}
long out = dstInit;
@@ -892,7 +892,7 @@ public static boolean[] intToBinary(final int src, final
int srcPos, final boole
if (0 == nBools) {
return dst;
}
- if (nBools - 1 + srcPos >= Integer.SIZE) {
+ if ((long) nBools - 1 + srcPos >= Integer.SIZE) {
throw new IllegalArgumentException("nBools - 1 + srcPos >= 32");
}
for (int i = 0; i < nBools; i++) {
@@ -919,7 +919,7 @@ public static byte[] intToByteArray(final int src, final
int srcPos, final byte[
if (0 == nBytes) {
return dst;
}
- if ((nBytes - 1) * Byte.SIZE + srcPos >= Integer.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + srcPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + srcPos >=
32");
}
for (int i = 0; i < nBytes; i++) {
@@ -945,7 +945,7 @@ public static String intToHex(final int src, final int
srcPos, final String dstI
if (0 == nHexs) {
return dstInit;
}
- if ((nHexs - 1) * 4 + srcPos >= Integer.SIZE) {
+ if (((long) nHexs - 1) * 4 + srcPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + srcPos >=
32");
}
final StringBuilder sb = new StringBuilder(dstInit);
@@ -1061,7 +1061,7 @@ public static short[] intToShortArray(final int src,
final int srcPos, final sho
if (0 == nShorts) {
return dst;
}
- if ((nShorts - 1) * Short.SIZE + srcPos >= Integer.SIZE) {
+ if (((long) nShorts - 1) * Short.SIZE + srcPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nShorts - 1) * 16 + srcPos >=
32");
}
for (int i = 0; i < nShorts; i++) {
@@ -1088,7 +1088,7 @@ public static boolean[] longToBinary(final long src,
final int srcPos, final boo
if (0 == nBools) {
return dst;
}
- if (nBools - 1 + srcPos >= Long.SIZE) {
+ if ((long) nBools - 1 + srcPos >= Long.SIZE) {
throw new IllegalArgumentException("nBools - 1 + srcPos >= 64");
}
for (int i = 0; i < nBools; i++) {
@@ -1115,7 +1115,7 @@ public static byte[] longToByteArray(final long src,
final int srcPos, final byt
if (0 == nBytes) {
return dst;
}
- if ((nBytes - 1) * Byte.SIZE + srcPos >= Long.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + srcPos >= Long.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + srcPos >=
64");
}
for (int i = 0; i < nBytes; i++) {
@@ -1141,7 +1141,7 @@ public static String longToHex(final long src, final int
srcPos, final String ds
if (0 == nHexs) {
return dstInit;
}
- if ((nHexs - 1) * 4 + srcPos >= Long.SIZE) {
+ if (((long) nHexs - 1) * 4 + srcPos >= Long.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + srcPos >=
64");
}
final StringBuilder sb = new StringBuilder(dstInit);
@@ -1176,7 +1176,7 @@ public static int[] longToIntArray(final long src, final
int srcPos, final int[]
if (0 == nInts) {
return dst;
}
- if ((nInts - 1) * Integer.SIZE + srcPos >= Long.SIZE) {
+ if (((long) nInts - 1) * Integer.SIZE + srcPos >= Long.SIZE) {
throw new IllegalArgumentException("(nInts - 1) * 32 + srcPos >=
64");
}
for (int i = 0; i < nInts; i++) {
@@ -1203,7 +1203,7 @@ public static short[] longToShortArray(final long src,
final int srcPos, final s
if (0 == nShorts) {
return dst;
}
- if ((nShorts - 1) * Short.SIZE + srcPos >= Long.SIZE) {
+ if (((long) nShorts - 1) * Short.SIZE + srcPos >= Long.SIZE) {
throw new IllegalArgumentException("(nShorts - 1) * 16 + srcPos >=
64");
}
for (int i = 0; i < nShorts; i++) {
@@ -1230,7 +1230,7 @@ public static int shortArrayToInt(final short[] src,
final int srcPos, final int
if (src.length == 0 && srcPos == 0 || 0 == nShorts) {
return dstInit;
}
- if ((nShorts - 1) * Short.SIZE + dstPos >= Integer.SIZE) {
+ if (((long) nShorts - 1) * Short.SIZE + dstPos >= Integer.SIZE) {
throw new IllegalArgumentException("(nShorts - 1) * 16 + dstPos >=
32");
}
int out = dstInit;
@@ -1260,7 +1260,7 @@ public static long shortArrayToLong(final short[] src,
final int srcPos, final l
if (src.length == 0 && srcPos == 0 || 0 == nShorts) {
return dstInit;
}
- if ((nShorts - 1) * Short.SIZE + dstPos >= Long.SIZE) {
+ if (((long) nShorts - 1) * Short.SIZE + dstPos >= Long.SIZE) {
throw new IllegalArgumentException("(nShorts - 1) * 16 + dstPos >=
64");
}
long out = dstInit;
@@ -1290,7 +1290,7 @@ public static boolean[] shortToBinary(final short src,
final int srcPos, final b
if (0 == nBools) {
return dst;
}
- if (nBools - 1 + srcPos >= Short.SIZE) {
+ if ((long) nBools - 1 + srcPos >= Short.SIZE) {
throw new IllegalArgumentException("nBools - 1 + srcPos >= 16");
}
assert nBools - 1 < Short.SIZE - srcPos;
@@ -1318,7 +1318,7 @@ public static byte[] shortToByteArray(final short src,
final int srcPos, final b
if (0 == nBytes) {
return dst;
}
- if ((nBytes - 1) * Byte.SIZE + srcPos >= Short.SIZE) {
+ if (((long) nBytes - 1) * Byte.SIZE + srcPos >= Short.SIZE) {
throw new IllegalArgumentException("(nBytes - 1) * 8 + srcPos >=
16");
}
for (int i = 0; i < nBytes; i++) {
@@ -1344,7 +1344,7 @@ public static String shortToHex(final short src, final
int srcPos, final String
if (0 == nHexs) {
return dstInit;
}
- if ((nHexs - 1) * 4 + srcPos >= Short.SIZE) {
+ if (((long) nHexs - 1) * 4 + srcPos >= Short.SIZE) {
throw new IllegalArgumentException("(nHexs - 1) * 4 + srcPos >=
16");
}
final StringBuilder sb = new StringBuilder(dstInit);
diff --git a/src/test/java/org/apache/commons/lang3/ConversionTest.java
b/src/test/java/org/apache/commons/lang3/ConversionTest.java
index b0b316301..9b475a9b3 100644
--- a/src/test/java/org/apache/commons/lang3/ConversionTest.java
+++ b/src/test/java/org/apache/commons/lang3/ConversionTest.java
@@ -1729,4 +1729,49 @@ void testUuidToByteArray() {
assertIllegalArgumentException(() -> Conversion.uuidToByteArray(new
UUID(
0xFFEEDDCCBBAA9988L, 0x7766554433221100L), new byte[16], 2,
17));
}
+
+ /**
+ * Each converter documents an {@link IllegalArgumentException} when the
requested count and position exceed the destination width, but the guard was
+ * evaluated in {@code int} arithmetic and silently overflowed for a large
count or position, so the documented exception never fired.
+ */
+ @Test
+ void testOverflowingCountOrPositionThrowsIllegalArgumentException() {
+ final int big = Integer.MAX_VALUE;
+ // nBools - 1 + dstPos
+ assertIllegalArgumentException(() -> Conversion.binaryToByte(new
boolean[]{true}, 0, (byte) 0, big, 2));
+ assertIllegalArgumentException(() -> Conversion.binaryToInt(new
boolean[]{true}, 0, 0, big, 2));
+ assertIllegalArgumentException(() -> Conversion.binaryToLong(new
boolean[]{true}, 0, 0L, big, 2));
+ assertIllegalArgumentException(() -> Conversion.binaryToShort(new
boolean[]{true}, 0, (short) 0, big, 2));
+ // nBools - 1 + srcPos
+ assertIllegalArgumentException(() -> Conversion.byteToBinary((byte) 1,
big, new boolean[8], 0, 2));
+ assertIllegalArgumentException(() -> Conversion.intToBinary(0, big,
new boolean[32], 0, 2));
+ assertIllegalArgumentException(() -> Conversion.longToBinary(0L, big,
new boolean[64], 0, 2));
+ assertIllegalArgumentException(() -> Conversion.shortToBinary((short)
0, big, new boolean[16], 0, 2));
+ // (nBytes - 1) * 8 + dstPos
+ assertIllegalArgumentException(() -> Conversion.byteArrayToInt(new
byte[]{1}, 0, 0, 0, big));
+ assertIllegalArgumentException(() -> Conversion.byteArrayToLong(new
byte[]{1}, 0, 0L, 0, big));
+ assertIllegalArgumentException(() -> Conversion.byteArrayToShort(new
byte[]{1}, 0, (short) 0, 0, big));
+ // (nBytes - 1) * 8 + srcPos
+ assertIllegalArgumentException(() -> Conversion.intToByteArray(0, 0,
new byte[4], 0, big));
+ assertIllegalArgumentException(() -> Conversion.longToByteArray(0L, 0,
new byte[8], 0, big));
+ assertIllegalArgumentException(() ->
Conversion.shortToByteArray((short) 0, 0, new byte[2], 0, big));
+ // (nHex - 1) * 4 + dstPos
+ assertIllegalArgumentException(() -> Conversion.hexToByte("f", 0,
(byte) 0, 0, big));
+ assertIllegalArgumentException(() -> Conversion.hexToInt("f", 0, 0, 0,
big));
+ assertIllegalArgumentException(() -> Conversion.hexToLong("f", 0, 0L,
0, big));
+ assertIllegalArgumentException(() -> Conversion.hexToShort("f", 0,
(short) 0, 0, big));
+ // (nHexs - 1) * 4 + srcPos
+ assertIllegalArgumentException(() -> Conversion.byteToHex((byte) 0, 0,
"", 0, big));
+ assertIllegalArgumentException(() -> Conversion.intToHex(0, 0, "", 0,
big));
+ assertIllegalArgumentException(() -> Conversion.longToHex(0L, 0, "",
0, big));
+ assertIllegalArgumentException(() -> Conversion.shortToHex((short) 0,
0, "", 0, big));
+ // (nInts - 1) * 32 + pos
+ assertIllegalArgumentException(() -> Conversion.intArrayToLong(new
int[]{0}, 0, 0L, 0, big));
+ assertIllegalArgumentException(() -> Conversion.longToIntArray(0L, 0,
new int[2], 0, big));
+ // (nShorts - 1) * 16 + pos
+ assertIllegalArgumentException(() -> Conversion.shortArrayToInt(new
short[]{0}, 0, 0, 0, big));
+ assertIllegalArgumentException(() -> Conversion.shortArrayToLong(new
short[]{0}, 0, 0L, 0, big));
+ assertIllegalArgumentException(() -> Conversion.intToShortArray(0, 0,
new short[2], 0, big));
+ assertIllegalArgumentException(() -> Conversion.longToShortArray(0L,
0, new short[4], 0, big));
+ }
}