Skip to content

Commit b6864a4

Browse files
committed
Fix accepting illegal hex string when parsing
1 parent d82b46f commit b6864a4

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## v0.4.5
44

55
* add nullSafe wrapper
6+
* fix accepting illegal hex string when parsing
67

78
## v0.4.4
89

src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,24 @@ public byte[] decode(String hexString) {
9999
if (hexString.length() % 2 != 0)
100100
throw new IllegalArgumentException("invalid hex string, must be mod 2 == 0");
101101

102+
int start;
102103
if (hexString.startsWith("0x")) {
103-
hexString = hexString.substring(2, hexString.length());
104+
start = 2;
105+
} else {
106+
start = 0;
104107
}
105108

106109
int len = hexString.length();
107-
byte[] data = new byte[len / 2];
108-
for (int i = 0; i < len; i += 2) {
109-
data[i / 2] = (byte)
110-
((Character.digit(hexString.charAt(i), 16) << 4)
111-
+ Character.digit(hexString.charAt(i + 1), 16));
110+
byte[] data = new byte[(len - start) / 2];
111+
for (int i = start; i < len; i += 2) {
112+
int first4Bits = Character.digit(hexString.charAt(i), 16);
113+
int second4Bits = Character.digit(hexString.charAt(i + 1), 16);
114+
115+
if (first4Bits == -1 || second4Bits == -1) {
116+
throw new IllegalArgumentException("'" + hexString.charAt(i) + hexString.charAt(i + 1) + "' at index " + i + " is not hex formatted");
117+
}
118+
119+
data[(i - start) / 2] = (byte) ((first4Bits << 4) + second4Bits);
112120
}
113121
return data;
114122
}

src/test/java/at/favre/lib/bytes/BinaryToTextEncodingTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public void encodeHex() throws Exception {
3636
assertNotEquals(new BinaryToTextEncoding.Hex(false).encode(new byte[]{1, 2, 3}, ByteOrder.LITTLE_ENDIAN), new BinaryToTextEncoding.Hex(false).encode(new byte[]{1, 2, 3}, ByteOrder.BIG_ENDIAN));
3737
}
3838

39+
@Test(expected = IllegalArgumentException.class)
40+
public void decodeHexShouldFail() throws Exception {
41+
new BinaryToTextEncoding.Hex(false).decode("AAI=");
42+
}
43+
3944
@Test
4045
public void encodeBaseRadix() throws Exception {
4146
assertEquals("100211", new BinaryToTextEncoding.BaseRadix(16).encode(new byte[]{16, 2, 17}, ByteOrder.BIG_ENDIAN));

src/test/java/at/favre/lib/bytes/BytesParseAndEncodingTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public void setUp() throws Exception {
3838
@Test
3939
public void parseHex() throws Exception {
4040
byte[] defaultArray = new byte[]{(byte) 0xA0, (byte) 0xE1};
41+
assertArrayEquals(defaultArray, Bytes.parseHex("0xA0E1").array());
4142
assertArrayEquals(defaultArray, Bytes.parseHex("A0E1").array());
4243
assertArrayEquals(defaultArray, Bytes.parseHex("a0e1").array());
43-
assertArrayEquals(defaultArray, Bytes.parseHex("0xA0E1").array());
4444
assertArrayEquals(defaultArray, Bytes.parseHex(Bytes.parseHex("A0E1").encodeHex()).array());
4545
}
4646

0 commit comments

Comments
 (0)