JDK-8159339 : UUID:fromString() parses incorrect strings without error
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 8u92
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2016-06-10
  • Updated: 2020-12-02
  • Resolved: 2016-06-26
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
OS X 10.11.5

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

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

24d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 is not (added a '2' in front of the valid one)

Calling UUID::fromString() with either one results in the same result, an UUID representing 4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just add a leading digit to a valid UUID and parse it

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
UUID::fromString() should throw IllegalArgumentException if passing a UUID that doesn't match the specification.
ACTUAL -
When parsing a UUID with an added leading digit, the original UUID is returned. 

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
String uuid = "4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8";

assert UUID.fromString(uuid).toString().equals(uuid);

assert !UUID.fromString("2" + uuid).toString().equals(uuid);
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
In the implementation of fromString() (pasted below), validate each group before building the result. At least the length of each string in components array should be checked, that is not expensive.

public static UUID fromString(String name) {
        String[] components = name.split("-");
        if (components.length != 5)
            throw new IllegalArgumentException("Invalid UUID string: "+name);
        for (int i=0; i<5; i++)
            components[i] = "0x"+components[i];

        long mostSigBits = Long.decode(components[0]).longValue();
        mostSigBits <<= 16;
        mostSigBits |= Long.decode(components[1]).longValue();
        mostSigBits <<= 16;
        mostSigBits |= Long.decode(components[2]).longValue();

        long leastSigBits = Long.decode(components[3]).longValue();
        leastSigBits <<= 48;
        leastSigBits |= Long.decode(components[4]).longValue();

        return new UUID(mostSigBits, leastSigBits);
    }


Comments
As mentioned by Sean, It brings a compatibility change in update releases and risks disruptions to programs that are already running with JDK 8 releases. And is already fixed in JDK 9. Hence closing this as Won't Fix.
26-06-2016

[~rpatil] - I don't think this is suitable for fixing in an update release. It brings a compatibility change and risks disruptions to programs that are already running with JDK 8 releases. It's a P4 and is already fixed in JDK 9. I suggest closing this record out as 'will not fix'
22-06-2016

We could correct the implementation to be more strict on formation of UUID Objects. It brings behavioural changes into update releases though.
13-06-2016

Attached test case executed on : JDK 8u92 - Fail JDK 9 ea- Pass Output on JDK 8u92: 4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 Output on JDK 9ea: 4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 Exception in thread "main" java.lang.IllegalArgumentException: UUID string too large at java.util.UUID.fromString(java.base@9-ea/UUID.java:199) at JI9039681.main(JI9039681.java:8)
13-06-2016