Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8202760

UUID.fromString() accepts invalid (short) strings

XMLWordPrintable

    • x86_64
    • linux_ubuntu

      ADDITIONAL SYSTEM INFORMATION :
      java version "10.0.1" 2018-04-17
      Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
      Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      Within https://bugs.openjdk.java.net/browse/JDK-8006627 maximum UUID string length check was introduced.
      If UUID string is shorter then 36 characters it still will be successfully parsed in certain cases without an error.
      For example is "0-0-0-0-0" which would be parsed into NIL UUID "00000000-0000-0000-0000-000000000000".
      Another example is "00112233-4455-6677-8899-aabbccddee" which would be incorrectly parsed into "00112233-4455-6677-8899-00aabbccddee" (note 00 in last part)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Call UUID.fromString("0-0-0-0-0" )

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Call fails
      ACTUAL -
      Call succeeds with UUID result of "00000000-0000-0000-0000-000000000000"

      ---------- BEGIN SOURCE ----------
      package ru.ay;

      import org.junit.Test;

      import java.util.UUID;

      import static org.junit.Assert.fail;

      public class UUIDFromStringTest {

          @Test
          public void shouldFailOnInvalidUUIDFormat() {
              testFromStringError("00112233-4455-6677-8899-aabbccddee");
              testFromStringError("0-0-0-0-0");
          }

          private static void testFromStringError(String str) {
              try {
                  UUID.fromString(str);
                  fail("Should have thrown IAE");
              } catch (IllegalArgumentException iae) {
                  // pass
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I propose to check exact UUID string length and offsets of separators ('-').

          public static UUID fromString(String name) {
              // Canonical UUID format is 8-4-4-4-12 for a total of 36 characters
              if (name.length() != 36 ||
                      name.charAt(8) != '-' ||
                      name.charAt(13) != '-' ||
                      name.charAt(18) != '-' ||
                      name.charAt(23) != '-') {
                  throw new IllegalArgumentException("Invalid UUID string: " + name);
              }

              long mostSigBits = Long.parseLong(name, 0, 8, 16) << 32
                      | Long.parseLong(name, 8 + 1, 13, 16) << 16
                      | Long.parseLong(name, 13 + 1, 18, 16);

              long leastSigBits = Long.parseLong(name, 18 + 1, 23, 16) << 48
                      | Long.parseLong(name, 23 + 1, 36, 16);

              return new UUID(mostSigBits, leastSigBits);
          }

            prappo Pavel Rappo
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: