Skip to content

Commit

Permalink
[XMLBEANS-646] Hex Binary decoding support can throw ArrayIndexOutOfB…
Browse files Browse the repository at this point in the history
…oundException

git-svn-id: https://svn.apache.org/repos/asf/xmlbeans/trunk@1914459 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
pjfanning committed Dec 8, 2023
1 parent a9e2640 commit f9a0ed8
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/main/java/org/apache/xmlbeans/impl/util/HexBin.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import java.nio.charset.StandardCharsets;

/**
* format validation
* This class encodes/decodes hexadecimal data.
* <p>
* This class encodes/decodes hexadecimal data
* This class is for internal use in Apache XMLBeans. If you need to do your own hexadecimal
* encoding/decoding, please find another library that specialises in this sort of support.
* </p>
*/
public final class HexBin {
static private final int BASELENGTH = 255;
Expand Down Expand Up @@ -55,7 +57,11 @@ public final class HexBin {
* byte to be tested if it is Base64 alphabet
*/
static boolean isHex(byte octect) {
return (hexNumberTable[octect] != -1);
// byte is a signed type and [] operator takes an int as an index.
// If use `octect` directly, negative byte will be promoted to the
// negative int and ArrayIndexOutOfBoundException will be thrown.
// `& 0xFF` will convert negative byte to positive int
return hexNumberTable[octect & 0xFF] != -1;
}

/**
Expand Down Expand Up @@ -94,6 +100,10 @@ static public byte[] encode(byte[] binaryData) {
return encodedData;
}

/**
* @param binaryData
* @return decoded bytes - can return null if the input is null, empty or includes bytes that are not valid Hex
*/
static public byte[] decode(byte[] binaryData) {
if (binaryData == null) {
return null;
Expand Down
Binary file modified src/main/java9/module-info.class
Binary file not shown.
55 changes: 55 additions & 0 deletions src/test/java/tools/hex/checkin/HexBinTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tools.hex.checkin;

import java.util.Random;

import org.apache.xmlbeans.impl.util.HexBin;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

public class HexBinTest {
@Test
void testDecodeInvalid() {
final byte[] bytes = {(byte)0xEF, (byte)0xBF};
final byte[] result = HexBin.decode(bytes);
assertNull(result);
}

@Test
void testDecodeNull() {
final byte[] result = HexBin.decode((byte[]) null);
assertNull(result);
}

@Test
void testDecodeEmpty() {
final byte[] bytes = new byte[0];
final byte[] result = HexBin.decode(bytes);
assertArrayEquals(bytes, result);
}

@Test
void testEncodeDecode() {
Random rnd = new Random();
final byte[] bytes = new byte[64];
rnd.nextBytes(bytes);
final byte[] encoded = HexBin.encode(bytes);
final byte[] decoded = HexBin.decode(encoded);
assertArrayEquals(bytes, decoded);
}
}

0 comments on commit f9a0ed8

Please sign in to comment.