Merge pull request #314 from supertomcat/LOG4J2-2707

LOG4J2-2707: ArrayIndexOutOfBoundsException in UuidUtil, when MAC add…
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/UuidUtil.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/UuidUtil.java
index 7b392ed..cf1d9d3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/UuidUtil.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/UuidUtil.java
@@ -52,8 +52,6 @@
     private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
     private static final long INITIAL_UUID_SEQNO = PropertiesUtil.getProperties().getLongProperty(UUID_SEQUENCE, 0);
 
-    private static final long LEAST;
-
     private static final long LOW_MASK = 0xffffffffL;
     private static final long MID_MASK = 0xffff00000000L;
     private static final long HIGH_MASK = 0xfff000000000000L;
@@ -63,8 +61,19 @@
     private static final int SHIFT_6 = 48;
     private static final int HUNDRED_NANOS_PER_MILLI = 10000;
 
-    static {
-        byte[] mac = NetUtils.getMacAddress();
+    private static final long LEAST = initialize(NetUtils.getMacAddress());
+
+    /* This class cannot be instantiated */
+    private UuidUtil() {
+    }
+
+    /**
+     * Initializes this class
+     * 
+     * @param mac MAC address
+     * @return Least
+     */
+    static long initialize(byte[] mac) {
         final Random randomGenerator = new SecureRandom();
         if (mac == null || mac.length == 0) {
             mac = new byte[6];
@@ -78,7 +87,7 @@
         for (int i = 2; i < NODE_SIZE; ++i) {
             node[i] = 0;
         }
-        System.arraycopy(mac, index, node, index + 2, length);
+        System.arraycopy(mac, index, node, 2, length);
         final ByteBuffer buf = ByteBuffer.wrap(node);
         long rand = INITIAL_UUID_SEQNO;
         String assigned = PropertiesUtil.getProperties().getStringProperty(ASSIGNED_SEQUENCES);
@@ -114,12 +123,7 @@
         assigned = assigned == null ? Long.toString(rand) : assigned + ',' + Long.toString(rand);
         System.setProperty(ASSIGNED_SEQUENCES, assigned);
 
-        LEAST = buf.getLong() | rand << SHIFT_6;
-    }
-
-
-    /* This class cannot be instantiated */
-    private UuidUtil() {
+        return buf.getLong() | rand << SHIFT_6;
     }
 
     /**
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/UuidTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/UuidTest.java
index 556f765..dbb4517 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/UuidTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/UuidTest.java
@@ -64,6 +64,22 @@
     }
 
     @Test
+    public void testInitialize() {
+        // Test if no ArrayIndexOutOfBoundsException is thrown when Mac address array is null
+        UuidUtil.initialize(null);
+
+        // Test if no ArrayIndexOutOfBoundsException is thrown for different Mac address lengths
+        for (int i=0; i < 10; i++) {
+            // Create MAC address byte array with i as size
+            byte[] mac = new byte[i];
+            for(int j=0; j < i; j++) {
+                mac[j] = (byte)j;
+            }
+            UuidUtil.initialize(mac);
+        }
+    }
+
+    @Test
     public void testThreads() throws Exception {
         final Thread[] threads = new Thread[THREADS];
         final UUID[] uuids = new UUID[COUNT * THREADS];