Skip to content

Commit dc302bd

Browse files
committed
Fix JsonReader parsing of "Date()"
JAVA-2024
1 parent db69a2f commit dc302bd

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ public BsonType readBsonType() {
181181
setCurrentBsonType(BsonType.BINARY);
182182
currentValue = visitBinDataConstructor();
183183
} else if ("Date".equals(value)) {
184-
setCurrentBsonType(BsonType.DATE_TIME);
185-
currentValue = visitDateTimeConstructor(); // withNew = false
184+
currentValue = visitDateTimeConstructorWithOutNew();
185+
setCurrentBsonType(BsonType.STRING);
186186
} else if ("HexData".equals(value)) {
187187
setCurrentBsonType(BsonType.BINARY);
188188
currentValue = visitHexDataConstructor();
@@ -845,6 +845,25 @@ private long visitDateTimeConstructor() {
845845
}
846846
}
847847

848+
private String visitDateTimeConstructorWithOutNew() {
849+
verifyToken("(");
850+
JsonToken token = popToken();
851+
if (token.getType() != JsonTokenType.RIGHT_PAREN) {
852+
while (token.getType() != JsonTokenType.END_OF_FILE) {
853+
token = popToken();
854+
if (token.getType() == JsonTokenType.RIGHT_PAREN) {
855+
break;
856+
}
857+
}
858+
if (token.getType() != JsonTokenType.RIGHT_PAREN) {
859+
throw new JsonParseException("JSON reader expected a ')' but found '%s'.", token.getValue());
860+
}
861+
}
862+
863+
DateFormat df = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z", Locale.ENGLISH);
864+
return df.format(new Date());
865+
}
866+
848867
private BsonBinary visitBinDataExtendedJson() {
849868
verifyToken(":");
850869
JsonToken bytesToken = popToken();
@@ -883,7 +902,7 @@ private long visitDateTimeExtendedJson() {
883902
try {
884903
return DatatypeConverter.parseDateTime(dateTimeString).getTimeInMillis();
885904
} catch (IllegalArgumentException e) {
886-
throw new JsonParseException("JSON reader expected an ISO-8601 date time string but found.", dateTimeString);
905+
throw new JsonParseException("JSON reader expected an ISO-8601 date time string but found '%s'.", dateTimeString);
887906
}
888907
} else {
889908
throw new JsonParseException("JSON reader expected an integer or string but found '%s'.", valueToken.getValue());

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
import org.bson.types.ObjectId;
2727
import org.junit.Test;
2828

29+
import java.text.ParsePosition;
30+
import java.text.SimpleDateFormat;
2931
import java.util.Date;
32+
import java.util.Locale;
3033

3134
import static org.junit.Assert.assertArrayEquals;
3235
import static org.junit.Assert.assertEquals;
@@ -716,12 +719,22 @@ public void testEmptyDateTimeConstructorWithNew() {
716719
}
717720

718721
@Test
719-
public void testEmptyDateTimeConstructor() {
720-
long currentTime = new Date().getTime();
722+
public void testDateTimeWithOutNew() {
723+
long currentTime = currentTimeWithoutMillis();
721724
String json = "Date()";
722725
bsonReader = new JsonReader(json);
723-
assertEquals(BsonType.DATE_TIME, bsonReader.readBsonType());
724-
assertTrue(bsonReader.readDateTime() >= currentTime);
726+
assertEquals(BsonType.STRING, bsonReader.readBsonType());
727+
assertTrue(dateStringToTime(bsonReader.readString()) >= currentTime);
728+
assertEquals(AbstractBsonReader.State.DONE, bsonReader.getState());
729+
}
730+
731+
@Test
732+
public void testDateTimeWithOutNewContainingJunk() {
733+
long currentTime = currentTimeWithoutMillis();
734+
String json = "Date({ok: 1}, 1234)";
735+
bsonReader = new JsonReader(json);
736+
assertEquals(BsonType.STRING, bsonReader.readBsonType());
737+
assertTrue(dateStringToTime(bsonReader.readString()) >= currentTime);
725738
assertEquals(AbstractBsonReader.State.DONE, bsonReader.getState());
726739
}
727740

@@ -798,4 +811,14 @@ public void testDBPointerWithNew() {
798811
assertEquals(new ObjectId("5209296cd6c4e38cf96fffdc"), dbPointer.getId());
799812
}
800813

814+
private long dateStringToTime(final String date) {
815+
SimpleDateFormat df = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z", Locale.ENGLISH);
816+
return df.parse(date, new ParsePosition(0)).getTime();
817+
}
818+
819+
private long currentTimeWithoutMillis() {
820+
long currentTime = new Date().getTime();
821+
return currentTime - (currentTime % 1000);
822+
}
823+
801824
}

0 commit comments

Comments
 (0)