JDK-8165199 : UUID.fromString accepts wrong placements of the dashes
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 8,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2016-08-31
  • Updated: 2019-01-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b18, mixed mode)

Although I pasted my actual version, please note this also occurs on the latest JDK9 version as I copied/pasted the code to test the JDK9 implementation of UUID::fromString with my JDK8 version (I had to mock Long.parseLong(String,int,int,int) as well).

ADDITIONAL OS VERSION INFORMATION :
Windows 7 64 bits

A DESCRIPTION OF THE PROBLEM :
UUID parsing is not working as expected. Wrongly placed dashes Additional leading digits in groups are swallowed without exceptions and the result is not the expected.

4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 is a valid UUID.

4d4d8f-3b3b81-44f3-968d-d1c1a48b4ac8 is not (moved the first dashes two characters to the left)

Calling UUID::fromString() with the invalid one results in an UUID representing 004d4dbf-3b81-44f3-968d-d1c1a48b4ac8.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and execute the executable test case.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The executable test case should throw an IllegalArgumentException as per javadoc.
ACTUAL -
The executable test case prints 004d4dbf-3b81-44f3-968d-d1c1a48b4ac8.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Foo {
  public static void main(String[] args) {
    System.out.println(UUID.fromString("4d4d8f-3b3b81-44f3-968d-d1c1a48b4ac8"));
  }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
From the code here: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/ca7fb78b94b6/src/java.base/share/classes/java/util/UUID.java

    public static UUID fromString(String name) {
        int len = name.length();
        if (len > 36) {
            throw new IllegalArgumentException("UUID string too large");
        }

        int dash1 = name.indexOf('-', 0);
        int dash2 = name.indexOf('-', dash1 + 1);
        int dash3 = name.indexOf('-', dash2 + 1);
        int dash4 = name.indexOf('-', dash3 + 1);
        int dash5 = name.indexOf('-', dash4 + 1);

        if (dash1 != 8 || dash2 != 13 || dash3 != 18 || dash4 != 23 || dash5 >= 0) {
            throw new IllegalArgumentException("Invalid UUID string: " + name);
        }

        long mostSigBits = Long.parseLong(name, 0, dash1, 16) & 0xffffffffL;
        mostSigBits <<= 16;
        mostSigBits |= Long.parseLong(name, dash1 + 1, dash2, 16) & 0xffffL;
        mostSigBits <<= 16;
        mostSigBits |= Long.parseLong(name, dash2 + 1, dash3, 16) & 0xffffL;
        long leastSigBits = Long.parseLong(name, dash3 + 1, dash4, 16) & 0xffffL;
        leastSigBits <<= 48;
        leastSigBits |= Long.parseLong(name, dash4 + 1, len, 16) & 0xffffffffffffL;
        
        return new UUID(mostSigBits, leastSigBits);
    }


Comments
So having discussed on the maillist (http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-December/057470.html) the general concensus seems to be that as this would be a "behavioral compatibility concern" and would thus require a CSR to be submitted and reviewed, we should leave as-is. The behaviour as it currently stands has been like this for many years.
17-12-2018

I'll take a look at this one
13-12-2018

To reproduce the issue , run the attached test case. Following are the results on various JDK versions: JDK 8u112ea - Fail JDK 9ea+128 - Fail Following is the output : java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+128) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+128, mixed mode) 004d4d8f-3b81-44f3-968d-d1c1a48b4ac8
01-09-2016