Author: fanningpj
Date: Fri Dec  8 12:43:56 2023
New Revision: 1914459

URL: http://svn.apache.org/viewvc?rev=1914459&view=rev
Log:
[XMLBEANS-646] Hex Binary decoding support can throw 
ArrayIndexOutOfBoundException

Added:
    xmlbeans/trunk/src/test/java/tools/hex/
    xmlbeans/trunk/src/test/java/tools/hex/checkin/
    xmlbeans/trunk/src/test/java/tools/hex/checkin/HexBinTest.java
Modified:
    xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/HexBin.java
    xmlbeans/trunk/src/main/java9/module-info.class

Modified: xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/HexBin.java
URL: 
http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/HexBin.java?rev=1914459&r1=1914458&r2=1914459&view=diff
==============================================================================
--- xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/HexBin.java 
(original)
+++ xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/HexBin.java Fri 
Dec  8 12:43:56 2023
@@ -18,9 +18,11 @@ package org.apache.xmlbeans.impl.util;
 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;
@@ -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;
     }
 
     /**
@@ -94,6 +100,10 @@ public final class HexBin {
         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;

Modified: xmlbeans/trunk/src/main/java9/module-info.class
URL: 
http://svn.apache.org/viewvc/xmlbeans/trunk/src/main/java9/module-info.class?rev=1914459&r1=1914458&r2=1914459&view=diff
==============================================================================
Binary files - no diff available.

Added: xmlbeans/trunk/src/test/java/tools/hex/checkin/HexBinTest.java
URL: 
http://svn.apache.org/viewvc/xmlbeans/trunk/src/test/java/tools/hex/checkin/HexBinTest.java?rev=1914459&view=auto
==============================================================================
--- xmlbeans/trunk/src/test/java/tools/hex/checkin/HexBinTest.java (added)
+++ xmlbeans/trunk/src/test/java/tools/hex/checkin/HexBinTest.java Fri Dec  8 
12:43:56 2023
@@ -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);
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to