Skip to content

Commit 50cfd14

Browse files
[IO-825] Add byte array size validation for methods in EndianUtils (#521)
* [IO-825] Add byte array size validation for methods in EndianUtils Signed-off-by: Arthur Chan <arthur.chan@adalogics.com> * Javadoc and format tweaks * Use final --------- Signed-off-by: Arthur Chan <arthur.chan@adalogics.com> Co-authored-by: Gary Gregory <garydgregory@users.noreply.github.com>
1 parent f33582a commit 50cfd14

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

src/main/java/org/apache/commons/io/EndianUtils.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@
4141
*/
4242
public class EndianUtils {
4343

44+
/**
45+
* Validates if the provided byte array have enough data.
46+
* @param data the input byte array
47+
* @param offset the input offset
48+
* @param byteNeeded the needed number of bytes
49+
* @throws IllegalArgumentException if the byte array does not have enough data
50+
*/
51+
private static void validateByteArrayOffset(final byte[] data, final int offset, final int byteNeeded) {
52+
if (data.length < offset + byteNeeded) {
53+
throw new IllegalArgumentException("Data only has " + data.length + "bytes, needed " + (offset + byteNeeded) + "bytes.");
54+
}
55+
}
56+
4457
/**
4558
* Reads the next byte from the input stream.
4659
* @param input the stream
@@ -107,6 +120,7 @@ public static float readSwappedFloat(final InputStream input) throws IOException
107120
* @return the value read
108121
*/
109122
public static int readSwappedInteger(final byte[] data, final int offset) {
123+
validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE);
110124
return ((data[offset + 0] & 0xff) << 0) +
111125
((data[offset + 1] & 0xff) << 8) +
112126
((data[offset + 2] & 0xff) << 16) +
@@ -136,6 +150,7 @@ public static int readSwappedInteger(final InputStream input) throws IOException
136150
* @return the value read
137151
*/
138152
public static long readSwappedLong(final byte[] data, final int offset) {
153+
validateByteArrayOffset(data, offset, Long.SIZE / Byte.SIZE);
139154
final long low = readSwappedInteger(data, offset);
140155
final long high = readSwappedInteger(data, offset + 4);
141156
return (high << 32) + (0xffffffffL & low);
@@ -164,6 +179,7 @@ public static long readSwappedLong(final InputStream input) throws IOException {
164179
* @return the value read
165180
*/
166181
public static short readSwappedShort(final byte[] data, final int offset) {
182+
validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE);
167183
return (short) (((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8));
168184
}
169185

@@ -187,6 +203,7 @@ public static short readSwappedShort(final InputStream input) throws IOException
187203
* @return the value read
188204
*/
189205
public static long readSwappedUnsignedInteger(final byte[] data, final int offset) {
206+
validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE);
190207
final long low = ((data[offset + 0] & 0xff) << 0) +
191208
((data[offset + 1] & 0xff) << 8) +
192209
((data[offset + 2] & 0xff) << 16);
@@ -220,6 +237,7 @@ public static long readSwappedUnsignedInteger(final InputStream input) throws IO
220237
* @return the value read
221238
*/
222239
public static int readSwappedUnsignedShort(final byte[] data, final int offset) {
240+
validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE);
223241
return ((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8);
224242
}
225243

@@ -347,6 +365,7 @@ public static void writeSwappedFloat(final OutputStream output, final float valu
347365
* @param value value to write
348366
*/
349367
public static void writeSwappedInteger(final byte[] data, final int offset, final int value) {
368+
validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE);
350369
data[offset + 0] = (byte) (value >> 0 & 0xff);
351370
data[offset + 1] = (byte) (value >> 8 & 0xff);
352371
data[offset + 2] = (byte) (value >> 16 & 0xff);
@@ -375,6 +394,7 @@ public static void writeSwappedInteger(final OutputStream output, final int valu
375394
* @param value value to write
376395
*/
377396
public static void writeSwappedLong(final byte[] data, final int offset, final long value) {
397+
validateByteArrayOffset(data, offset, Long.SIZE / Byte.SIZE);
378398
data[offset + 0] = (byte) (value >> 0 & 0xff);
379399
data[offset + 1] = (byte) (value >> 8 & 0xff);
380400
data[offset + 2] = (byte) (value >> 16 & 0xff);
@@ -411,6 +431,7 @@ public static void writeSwappedLong(final OutputStream output, final long value)
411431
* @param value value to write
412432
*/
413433
public static void writeSwappedShort(final byte[] data, final int offset, final short value) {
434+
validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE);
414435
data[offset + 0] = (byte) (value >> 0 & 0xff);
415436
data[offset + 1] = (byte) (value >> 8 & 0xff);
416437
}

src/test/java/org/apache/commons/io/EndianUtilsTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,18 @@ public void testWriteSwappedShort() throws IOException {
308308
assertEquals( 0x01, bytes[1] );
309309
}
310310

311+
@Test
312+
public void testInvalidOffset() throws IOException {
313+
final byte[] bytes = new byte[0];
314+
315+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedInteger(bytes, 0));
316+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedLong(bytes, 0));
317+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedShort(bytes, 0));
318+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedInteger(bytes, 0));
319+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedShort(bytes, 0));
320+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedInteger(bytes, 0, 0));
321+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedLong(bytes, 0, 0l));
322+
assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedShort(bytes, 0, (short) 0));
323+
}
324+
311325
}

0 commit comments

Comments
 (0)