This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-codec.git
commit 2311c5e58e6922825d7ecb53ef596b7a8c156bf1 Author: aherbert <aherb...@apache.org> AuthorDate: Thu Nov 28 12:41:45 2019 +0000 [CODEC-259] Hex: consume all ByteBuffer.remaining() bytes. --- .../java/org/apache/commons/codec/binary/Hex.java | 37 +++++++++++-- .../org/apache/commons/codec/binary/HexTest.java | 63 +++++++++++++++++----- 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/apache/commons/codec/binary/Hex.java b/src/main/java/org/apache/commons/codec/binary/Hex.java index 22fc5b7..dfbd64e 100644 --- a/src/main/java/org/apache/commons/codec/binary/Hex.java +++ b/src/main/java/org/apache/commons/codec/binary/Hex.java @@ -125,6 +125,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * returned array will be double the length of the passed array, as it takes two characters to represent any given * byte. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param data a byte buffer to convert to Hex characters * @return A char[] containing lower-case hexadecimal characters * @since 1.11 @@ -152,6 +155,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * returned array will be double the length of the passed array, as it takes two characters to represent any given * byte. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param data a byte buffer to convert to Hex characters * @param toLowerCase <code>true</code> converts to lowercase, <code>false</code> to uppercase * @return A char[] containing hexadecimal characters in the selected case @@ -188,6 +194,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * returned array will be double the length of the passed array, as it takes two characters to represent any given * byte. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param byteBuffer a byte buffer to convert to Hex characters * @param toDigits the output alphabet (must be at least 16 characters) * @return A char[] containing the appropriate characters from the alphabet For best results, this should be either @@ -227,6 +236,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * Converts a byte buffer into a String representing the hexadecimal values of each byte in order. The returned * String will be double the length of the passed array, as it takes two characters to represent any given byte. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param data a byte buffer to convert to Hex characters * @return A String containing lower-case hexadecimal characters * @since 1.11 @@ -239,6 +251,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * Converts a byte buffer into a String representing the hexadecimal values of each byte in order. The returned * String will be double the length of the passed array, as it takes two characters to represent any given byte. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param data a byte buffer to convert to Hex characters * @param toLowerCase <code>true</code> converts to lowercase, <code>false</code> to uppercase * @return A String containing lower-case hexadecimal characters @@ -248,13 +263,20 @@ public class Hex implements BinaryEncoder, BinaryDecoder { return new String(encodeHex(data, toLowerCase)); } + /** + * Convert the byte buffer to a a byte array. All bytes identified by + * {@link ByteBuffer#remaining()} will be used. + * + * @param byteBuffer the byte buffer + * @return the byte[] + */ private static byte[] toByteArray(final ByteBuffer byteBuffer) { final int remaining = byteBuffer.remaining(); // Use the underlying buffer if possible if (byteBuffer.hasArray()) { final byte[] byteArray = byteBuffer.array(); if (remaining == byteArray.length) { - //byteBuffer.position(remaining); + byteBuffer.position(remaining); return byteArray; } } @@ -332,6 +354,9 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * The returned array will be half the length of the passed array, as it takes two characters to represent any given * byte. An exception is thrown if the passed char array has an odd number of elements. * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> + * * @param buffer An array of character bytes containing hexadecimal digits * @return A byte array containing binary data decoded from the supplied byte array (representing characters). * @throws DecoderException Thrown if an odd number of characters is supplied to this function @@ -393,10 +418,12 @@ public class Hex implements BinaryEncoder, BinaryDecoder { * Converts byte buffer into an array of bytes for the characters representing the hexadecimal values of each byte * in order. The returned array will be double the length of the passed array, as it takes two characters to * represent any given byte. - * <p> - * The conversion from hexadecimal characters to the returned bytes is performed with the charset named by - * {@link #getCharset()}. - * </p> + * + * <p>The conversion from hexadecimal characters to the returned bytes is performed with the charset named by + * {@link #getCharset()}.</p> + * + * <p>All bytes identified by {@link ByteBuffer#remaining()} will be used; after this method + * the value {@link ByteBuffer#remaining() remaining()} will be zero.</p> * * @param array a byte buffer to convert to Hex characters * @return A byte[] containing the bytes of the lower-case hexadecimal characters diff --git a/src/test/java/org/apache/commons/codec/binary/HexTest.java b/src/test/java/org/apache/commons/codec/binary/HexTest.java index 34f97a4..8b64110 100644 --- a/src/test/java/org/apache/commons/codec/binary/HexTest.java +++ b/src/test/java/org/apache/commons/codec/binary/HexTest.java @@ -249,6 +249,7 @@ public class HexTest { // Effectively set remaining == 0 => empty bb.flip(); assertTrue(Arrays.equals(new byte[0], new Hex().decode(bb))); + assertEquals(0, bb.remaining()); } @Test @@ -258,16 +259,19 @@ public class HexTest { @Test public void testDecodeByteBufferOddCharacters() { - checkDecodeHexByteBufferOddCharacters(ByteBuffer.wrap(new byte[] { 65 })); + final ByteBuffer bb = allocate(1); + bb.put((byte) 65); + bb.flip(); + checkDecodeHexByteBufferOddCharacters(bb); } @Test public void testDecodeByteBufferWithLimitOddCharacters() { - final ByteBuffer buffer = allocate(10); - buffer.put(1, (byte) 65); - buffer.position(1); - buffer.limit(2); - checkDecodeHexByteBufferOddCharacters(buffer); + final ByteBuffer bb = allocate(10); + bb.put(1, (byte) 65); + bb.position(1); + bb.limit(2); + checkDecodeHexByteBufferOddCharacters(bb); } @Test @@ -334,6 +338,7 @@ public class HexTest { bb.position(i * 2); bb.limit(i * 2 + 4); assertEquals(new String(Arrays.copyOfRange(expected, i, i + 2)), new String(new Hex().decode(bb))); + assertEquals(0, bb.remaining()); } } @@ -358,6 +363,7 @@ public class HexTest { // Effectively set remaining == 0 => empty bb.flip(); assertTrue(Arrays.equals(new byte[0], new Hex().encode(bb))); + assertEquals(0, bb.remaining()); } @Test @@ -457,12 +463,20 @@ public class HexTest { final ByteBuffer b = StringUtils.getByteBufferUtf8("Hello World"); final String expected = "48656c6c6f20576f726c64"; char[] actual; + // Default lower-case actual = Hex.encodeHex(b); assertEquals(expected, new String(actual)); + assertEquals(0, b.remaining()); + // lower-case + b.flip(); actual = Hex.encodeHex(b, true); assertEquals(expected, new String(actual)); + assertEquals(0, b.remaining()); + // upper-case + b.flip(); actual = Hex.encodeHex(b, false); - assertFalse(expected.equals(new String(actual))); + assertEquals(expected.toUpperCase(), new String(actual)); + assertEquals(0, b.remaining()); } @Test @@ -470,12 +484,20 @@ public class HexTest { final ByteBuffer b = StringUtils.getByteBufferUtf8("Hello World"); final String expected = "48656C6C6F20576F726C64"; char[] actual; + // Default lower-case actual = Hex.encodeHex(b); - assertFalse(expected.equals(new String(actual))); + assertEquals(expected.toLowerCase(), new String(actual)); + assertEquals(0, b.remaining()); + // lower-case + b.flip(); actual = Hex.encodeHex(b, true); - assertFalse(expected.equals(new String(actual))); + assertEquals(expected.toLowerCase(), new String(actual)); + assertEquals(0, b.remaining()); + // upper-case + b.flip(); actual = Hex.encodeHex(b, false); - assertTrue(expected.equals(new String(actual))); + assertEquals(expected, new String(actual)); + assertEquals(0, b.remaining()); } @Test @@ -486,13 +508,18 @@ public class HexTest { @Test public void testEncodeHex_ByteBufferWithLimit() { - final ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); + final ByteBuffer bb = allocate(16); + for (int i = 0; i < 16; i++) { + bb.put((byte) i); + } + bb.flip(); final String expected = "000102030405060708090a0b0c0d0e0f"; // Test pairs of bytes for (int i = 0; i < 15; i++) { bb.position(i); bb.limit(i + 2); assertEquals(expected.substring(i * 2, i * 2 + 4), new String(Hex.encodeHex(bb))); + assertEquals(0, bb.remaining()); } } @@ -507,9 +534,11 @@ public class HexTest { final ByteBuffer bb = allocate(36); bb.limit(3); assertEquals("000000", Hex.encodeHexString(bb)); + assertEquals(0, bb.remaining()); bb.position(1); bb.limit(3); assertEquals("0000", Hex.encodeHexString(bb)); + assertEquals(0, bb.remaining()); } @Test @@ -530,12 +559,18 @@ public class HexTest { @Test public void testEncodeHexByteString_ByteBufferBoolean_ToLowerCase() { - assertEquals("0a", Hex.encodeHexString(ByteBuffer.wrap(new byte[] { 10 }), true)); + final ByteBuffer bb = allocate(1); + bb.put((byte) 10); + bb.flip(); + assertEquals("0a", Hex.encodeHexString(bb, true)); } @Test public void testEncodeHexByteString_ByteBufferBoolean_ToUpperCase() { - assertEquals("0A", Hex.encodeHexString(ByteBuffer.wrap(new byte[] { 10 }), false)); + final ByteBuffer bb = allocate(1); + bb.put((byte) 10); + bb.flip(); + assertEquals("0A", Hex.encodeHexString(bb, false)); } @Test @@ -545,6 +580,7 @@ public class HexTest { bb.position(1); bb.limit(2); assertEquals("0a", Hex.encodeHexString(bb, true)); + assertEquals(0, bb.remaining()); } @Test @@ -554,6 +590,7 @@ public class HexTest { bb.position(1); bb.limit(2); assertEquals("0A", Hex.encodeHexString(bb, false)); + assertEquals(0, bb.remaining()); } @Test