Skip to content

Commit 01019c7

Browse files
committed
Fix JSON parsing of shell-mode UUID constructor
It's quite broken in a number of ways, actually: * It produced the wrong binary subtype for UUID/GUID (legacy instead of standard) * It partially supported alternate constructors for UUIDs that were proposed long ago for the shell but never implemented, but does not actually produced the correct byte ordering for CSUUID/CSGUID or JUUID/JGUID This fix does two things: * It produces the correct subtype for the UUID constructor: standard, subtype 4 * It removes the broken support for all the other constructors that were never actually implemented correctly. JAVA-3749
1 parent 6267ee3 commit 01019c7

File tree

2 files changed

+20
-26
lines changed

2 files changed

+20
-26
lines changed

bson/src/main/org/bson/json/JsonReader.java

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,9 @@ public BsonType readBsonType() {
244244
} else if ("DBPointer".equals(value)) {
245245
setCurrentBsonType(BsonType.DB_POINTER);
246246
currentValue = visitDBPointerConstructor();
247-
} else if ("UUID".equals(value)
248-
|| "GUID".equals(value)
249-
|| "CSUUID".equals(value)
250-
|| "CSGUID".equals(value)
251-
|| "JUUID".equals(value)
252-
|| "JGUID".equals(value)
253-
|| "PYUUID".equals(value)
254-
|| "PYGUID".equals(value)) {
247+
} else if ("UUID".equals(value)) {
255248
setCurrentBsonType(BsonType.BINARY);
256-
currentValue = visitUUIDConstructor(value);
249+
currentValue = visitUUIDConstructor();
257250
} else if ("new".equals(value)) {
258251
visitNew();
259252
} else {
@@ -594,15 +587,8 @@ private void visitNew() {
594587
} else if ("DBPointer".equals(value)) {
595588
currentValue = visitDBPointerConstructor();
596589
setCurrentBsonType(BsonType.DB_POINTER);
597-
} else if ("UUID".equals(value)
598-
|| "GUID".equals(value)
599-
|| "CSUUID".equals(value)
600-
|| "CSGUID".equals(value)
601-
|| "JUUID".equals(value)
602-
|| "JGUID".equals(value)
603-
|| "PYUUID".equals(value)
604-
|| "PYGUID".equals(value)) {
605-
currentValue = visitUUIDConstructor(value);
590+
} else if ("UUID".equals(value)) {
591+
currentValue = visitUUIDConstructor();
606592
setCurrentBsonType(BsonType.BINARY);
607593
} else {
608594
throw new JsonParseException("JSON reader expected a type name but found '%s'.", value);
@@ -716,16 +702,11 @@ private BsonBinary visitBinDataConstructor() {
716702
return new BsonBinary(subTypeToken.getValue(Integer.class).byteValue(), bytes);
717703
}
718704

719-
private BsonBinary visitUUIDConstructor(final String uuidConstructorName) {
705+
private BsonBinary visitUUIDConstructor() {
720706
verifyToken(JsonTokenType.LEFT_PAREN);
721-
String hexString = readStringFromExtendedJson().replaceAll("\\{", "").replaceAll("}", "").replaceAll("-", "");
707+
String hexString = readStringFromExtendedJson().replace("-", "");
722708
verifyToken(JsonTokenType.RIGHT_PAREN);
723-
byte[] bytes = decodeHex(hexString);
724-
BsonBinarySubType subType = BsonBinarySubType.UUID_STANDARD;
725-
if (!"UUID".equals(uuidConstructorName) || !"GUID".equals(uuidConstructorName)) {
726-
subType = BsonBinarySubType.UUID_LEGACY;
727-
}
728-
return new BsonBinary(subType, bytes);
709+
return new BsonBinary(BsonBinarySubType.UUID_STANDARD, decodeHex(hexString));
729710
}
730711

731712
private BsonRegularExpression visitRegularExpressionConstructor() {

bson/src/test/unit/org/bson/json/JsonReaderTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,19 @@ public void testCanonicalExtendedJsonBinaryWithIncorrectFirstKey() {
945945
}, JsonParseException.class);
946946
}
947947

948+
@Test
949+
public void testUuidConstructor() {
950+
String json = "UUID(\"b5f21e0c-2a0d-42d6-ad03-d827008d8ab6\")";
951+
testStringAndStream(json, bsonReader -> {
952+
assertEquals(BsonType.BINARY, bsonReader.readBsonType());
953+
BsonBinary binary = bsonReader.readBinaryData();
954+
assertEquals(BsonBinarySubType.UUID_STANDARD.getValue(), binary.getType());
955+
assertArrayEquals(new byte[]{-75, -14, 30, 12, 42, 13, 66, -42, -83, 3, -40, 39, 0, -115, -118, -74}, binary.getData());
956+
assertEquals(AbstractBsonReader.State.DONE, bsonReader.getState());
957+
return null;
958+
});
959+
}
960+
948961
@Test
949962
public void testInfinity() {
950963
String json = "{ \"value\" : Infinity }";

0 commit comments

Comments
 (0)