Skip to content

Commit e203e82

Browse files
committed
Bugzilla Bug 28455: Hex converts illegal characters to 255.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/codec/trunk@130359 13f79535-47bb-0310-9956-ffa450edef68
1 parent 94c6cc1 commit e203e82

2 files changed

Lines changed: 64 additions & 25 deletions

File tree

src/java/org/apache/commons/codec/binary/Hex.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@
2424
/**
2525
* Hex encoder and decoder.
2626
*
27+
* @since 1.1
2728
* @author Apache Software Foundation
28-
* @version $Id: Hex.java,v 1.12 2004/02/29 04:08:31 tobrien Exp $
29+
* @version $Id: Hex.java,v 1.13 2004/04/18 18:22:33 ggregory Exp $
2930
*/
3031
public class Hex implements BinaryEncoder, BinaryDecoder {
3132

3233
/**
3334
* Used building output as Hex
3435
*/
35-
private static char[] digits = {
36+
private static final char[] DIGITS = {
3637
'0', '1', '2', '3', '4', '5', '6', '7',
3738
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
3839
};
@@ -47,36 +48,54 @@ public class Hex implements BinaryEncoder, BinaryDecoder {
4748
* @param data An array of characters containing hexidecimal digits
4849
* @return A byte array containing binary data decoded from
4950
* the supplied char array.
50-
* @throws DecoderException Thrown if an odd number of characters is supplied
51-
* to this function
51+
* @throws DecoderException Thrown if an odd number or illegal of characters
52+
* is supplied
5253
*/
5354
public static byte[] decodeHex(char[] data) throws DecoderException {
5455

55-
int l = data.length;
56+
int len = data.length;
5657

57-
if ((l & 0x01) != 0) {
58-
throw new DecoderException("Odd number of characters.");
59-
}
58+
if ((len & 0x01) != 0) {
59+
throw new DecoderException("Odd number of characters.");
60+
}
6061

61-
byte[] out = new byte[l >> 1];
62+
byte[] out = new byte[len >> 1];
6263

63-
// two characters form the hex value.
64-
for (int i = 0, j = 0; j < l; i++) {
65-
int f = Character.digit(data[j++], 16) << 4;
66-
f = f | Character.digit(data[j++], 16);
67-
out[i] = (byte) (f & 0xFF);
68-
}
64+
// two characters form the hex value.
65+
for (int i = 0, j = 0; j < len; i++) {
66+
int f = toDigit(data[j], j) << 4;
67+
j++;
68+
f = f | toDigit(data[j], j);
69+
j++;
70+
out[i] = (byte) (f & 0xFF);
71+
}
6972

70-
return out;
73+
return out;
7174
}
7275

7376
/**
74-
* Converts an array of bytes into an array of characters representing the
75-
* hexidecimal values of each byte in order. The returned array will be
76-
* double the length of the passed array, as it takes two characters to
77-
* represent any given byte.
78-
*
79-
* @param data a byte[] to convert to Hex characters
77+
* Converts a hexadecimal character to an integer.
78+
*
79+
* @param ch A character to convert to an integer digit
80+
* @param index The index of the character in the source
81+
* @return An integer
82+
* @throws DecoderException Thrown if ch is an illegal hex character
83+
*/
84+
protected static int toDigit(char ch, int index) throws DecoderException {
85+
int digit = Character.digit(ch, 16);
86+
if (digit == -1) {
87+
throw new DecoderException("Illegal hexadecimal charcter " + ch + " at index " + index);
88+
}
89+
return digit;
90+
}
91+
92+
/**
93+
* Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order.
94+
* The returned array will be double the length of the passed array, as it takes two characters to represent any
95+
* given byte.
96+
*
97+
* @param data
98+
* a byte[] to convert to Hex characters
8099
* @return A char[] containing hexidecimal characters
81100
*/
82101
public static char[] encodeHex(byte[] data) {
@@ -87,8 +106,8 @@ public static char[] encodeHex(byte[] data) {
87106

88107
// two characters form the hex value.
89108
for (int i = 0, j = 0; i < l; i++) {
90-
out[j++] = digits[(0xF0 & data[i]) >>> 4 ];
91-
out[j++] = digits[ 0x0F & data[i] ];
109+
out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ];
110+
out[j++] = DIGITS[ 0x0F & data[i] ];
92111
}
93112

94113
return out;

src/test/org/apache/commons/codec/binary/HexTest.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* Tests {@link org.apache.commons.codec.binary.Hex}.
2828
*
2929
* @author Apache Software Foundation
30-
* @version $Id: HexTest.java,v 1.9 2004/03/17 19:28:37 ggregory Exp $
30+
* @version $Id: HexTest.java,v 1.10 2004/04/18 18:22:33 ggregory Exp $
3131
*/
3232

3333
public class HexTest extends TestCase {
@@ -46,6 +46,26 @@ public void testDecodeArrayOddCharacters() {
4646
}
4747
}
4848

49+
public void testDecodeBadCharacterPos0() {
50+
try {
51+
new Hex().decode("q0");
52+
fail("An exception wasn't thrown when trying to decode an illegal character");
53+
}
54+
catch (DecoderException e) {
55+
// Expected exception
56+
}
57+
}
58+
59+
public void testDecodeBadCharacterPos1() {
60+
try {
61+
new Hex().decode("0q");
62+
fail("An exception wasn't thrown when trying to decode an illegal character");
63+
}
64+
catch (DecoderException e) {
65+
// Expected exception
66+
}
67+
}
68+
4969
public void testDecodeClassCastException() {
5070
try {
5171
new Hex().decode(new int[] { 65 });

0 commit comments

Comments
 (0)