Skip to content

Commit 07bdfd1

Browse files
authored
improved date string parser; support optional ms digits
* improved data string parser; support optional ms digits (see issue mozilla#1895) * skip ms digits, extended year support is not available in es6
1 parent feeb9e7 commit 07bdfd1

2 files changed

Lines changed: 335 additions & 19 deletions

File tree

rhino/src/main/java/org/mozilla/javascript/NativeDate.java

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -976,39 +976,70 @@ private static double parseISOString(Context cx, String s) {
976976
i += 1;
977977
yearlen = 6;
978978
yearmod = (c == '-') ? -1 : 1;
979-
} else if (c == 'T') {
979+
} else if (c == 'T' && cx.getLanguageVersion() < Context.VERSION_ES6) {
980980
// time-only forms no longer in spec, but follow spidermonkey here
981981
i += 1;
982982
state = HOUR;
983983
}
984984
}
985985
loop:
986986
while (state != ERROR) {
987-
int m = i + (state == YEAR ? yearlen : state == MSEC ? 3 : 2);
988-
if (m > len) {
989-
state = ERROR;
990-
break;
991-
}
987+
if (state == MSEC) {
988+
// milli secs are different, digit 2 and 3 are optional
989+
int value = 0;
990+
int digitsFound = 0;
991+
for (; i < len; i++) {
992+
char c = s.charAt(i);
993+
if (c < '0' || c > '9') {
994+
break;
995+
}
992996

993-
int value = 0;
994-
for (; i < m; ++i) {
995-
char c = s.charAt(i);
996-
if (c < '0' || c > '9') {
997+
// skip more digits
998+
if (digitsFound < 3) {
999+
value = 10 * value + (c - '0');
1000+
digitsFound++;
1001+
}
1002+
}
1003+
if (digitsFound == 0) {
9971004
state = ERROR;
9981005
break loop;
9991006
}
1000-
value = 10 * value + (c - '0');
1001-
}
1002-
values[state] = value;
1007+
if (digitsFound < 3) {
1008+
value = value * (digitsFound == 1 ? 100 : 10);
1009+
}
1010+
values[state] = value;
10031011

1004-
if (i == len) {
1005-
// reached EOF, check for end state
1006-
switch (state) {
1007-
case HOUR:
1008-
case TZHOUR:
1012+
if (i == len) {
1013+
// no timezone at all is correct here
1014+
break;
1015+
}
1016+
} else {
1017+
int m = i + (state == YEAR ? yearlen : 2);
1018+
if (m > len) {
1019+
state = ERROR;
1020+
break;
1021+
}
1022+
1023+
int value = 0;
1024+
for (; i < m; ++i) {
1025+
char c = s.charAt(i);
1026+
if (c < '0' || c > '9') {
10091027
state = ERROR;
1028+
break loop;
1029+
}
1030+
value = 10 * value + (c - '0');
1031+
}
1032+
values[state] = value;
1033+
1034+
if (i == len) {
1035+
// reached EOF, check for end state
1036+
switch (state) {
1037+
case HOUR:
1038+
case TZHOUR:
1039+
state = ERROR;
1040+
}
1041+
break;
10101042
}
1011-
break;
10121043
}
10131044

10141045
char c = s.charAt(i++);
@@ -1017,6 +1048,9 @@ private static double parseISOString(Context cx, String s) {
10171048
values[TZHOUR] = 0;
10181049
values[TZMIN] = 0;
10191050
switch (state) {
1051+
case YEAR:
1052+
case MONTH:
1053+
case DAY:
10201054
case MIN:
10211055
case SEC:
10221056
case MSEC:

0 commit comments

Comments
 (0)