When I looked into the implementation of java.util.UUID.fromString
, I found that it doesn\'t check for the UUID length. Is there any particular reason for this?
The behaviour of UUID.fromString is strange I am not sure if it is a bug or not, but here is what I have been doing to catch those errors.
public class UUIDUtils {
public static boolean isValid(String uuid){
if( uuid == null) return false;
try {
// we have to convert to object and back to string because the built in fromString does not have
// good validation logic.
UUID fromStringUUID = UUID.fromString(uuid);
String toStringUUID = fromStringUUID.toString();
return toStringUUID.equals(uuid);
} catch(IllegalArgumentException e) {
return false;
}
}
}
Make sure to test against id.equalsIgnoreCase(parsed.toString())
because UUID.fromString(id)
returns lower case even if you pass id
as upper case.
@Component
public class UuidDtoValidator {
public boolean isValidUuid(String id) {
if (isBlank(id)) {
return false;
}
try {
UUID parsed = UUID.fromString(id);
if (parsed.equals(new UUID(0, 0))) {
return false;
}
return id.equalsIgnoreCase(parsed.toString());
} catch (IllegalArgumentException e) {
return false;
}
}
}
A copy of ams's answer but for scala xD
def isValidUuid(uuid: String): Boolean =
try uuid != null && UUID.fromString(uuid).toString.equals(uuid)
catch {
case e: IllegalArgumentException => false
}
Here's a solution:
import java.util.UUID
import scala.util.control.Exception._
val uuId: Option[UUID] = allCatch opt UUID.fromString(uuidToTest)
require(uuId.isDefined, "invalid UUID")
Only the original authors of the UUID class could tell you why they chose not to check the component lengths in the fromString method, but I suspect they were trying to heed Postel's law:
Be liberal in what you accept, and conservative in what you send.
You can always check the input against a regular expression like this one:
[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}