Fix timestamp parsing in HttpHeaderDateFormatter
Motivation: code assumes a numeric value of 0 means no digits were read between separators, which fails for timestamps like 00:00:00. also code accepts invalid timestamps like 0:0:000 Modifications: explicitly check for number of digits between separators instead of relying on the numeric value. also add tests. Result: timestamps with 00 successfully parse, timestamps with 000 no longer Signed-off-by: radai-rosenblatt <radai.rosenblatt@gmail.com>
This commit is contained in:
parent
9b7fb2f362
commit
886a7aae46
@ -188,40 +188,43 @@ public final class HttpHeaderDateFormatter {
|
|||||||
int localSeconds = -1;
|
int localSeconds = -1;
|
||||||
int currentPartNumber = 0;
|
int currentPartNumber = 0;
|
||||||
int currentPartValue = 0;
|
int currentPartValue = 0;
|
||||||
|
int numDigits = 0;
|
||||||
|
|
||||||
for (int i = tokenStart; i < tokenEnd; i++) {
|
for (int i = tokenStart; i < tokenEnd; i++) {
|
||||||
char c = txt.charAt(i);
|
char c = txt.charAt(i);
|
||||||
if (isDigit(c)) {
|
if (isDigit(c)) {
|
||||||
currentPartValue = currentPartValue * 10 + getNumericalValue(c);
|
currentPartValue = currentPartValue * 10 + getNumericalValue(c);
|
||||||
|
if (++numDigits > 2) {
|
||||||
|
return false; // too many digits in this part
|
||||||
|
}
|
||||||
} else if (c == ':') {
|
} else if (c == ':') {
|
||||||
if (currentPartValue == 0) {
|
if (numDigits == 0) {
|
||||||
// invalid :: (nothing in between)
|
// no digits between separators
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (currentPartNumber) {
|
switch (currentPartNumber) {
|
||||||
case 0:
|
case 0:
|
||||||
// flushing hours
|
// flushing hours
|
||||||
localHours = currentPartValue;
|
localHours = currentPartValue;
|
||||||
currentPartValue = 0;
|
|
||||||
currentPartNumber++;
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// flushing minutes
|
// flushing minutes
|
||||||
localMinutes = currentPartValue;
|
localMinutes = currentPartValue;
|
||||||
currentPartValue = 0;
|
|
||||||
currentPartNumber++;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// invalid, too many :
|
// invalid, too many :
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
currentPartValue = 0;
|
||||||
|
currentPartNumber++;
|
||||||
|
numDigits = 0;
|
||||||
} else {
|
} else {
|
||||||
// invalid char
|
// invalid char
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPartValue > 0) {
|
if (numDigits > 0) {
|
||||||
// pending seconds
|
// pending seconds
|
||||||
localSeconds = currentPartValue;
|
localSeconds = currentPartValue;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,11 @@ public class HttpHeaderDateFormatterTest {
|
|||||||
assertEquals(_08_09_07, parse("Sunday, 6 Nov 1994 8:9:07 GMT"));
|
assertEquals(_08_09_07, parse("Sunday, 6 Nov 1994 8:9:07 GMT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseMidnight() {
|
||||||
|
assertEquals(new Date(784080000000L), parse("Sunday, 6 Nov 1994 00:00:00 GMT"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseInvalidInput() {
|
public void testParseInvalidInput() {
|
||||||
// missing field
|
// missing field
|
||||||
@ -96,6 +101,10 @@ public class HttpHeaderDateFormatterTest {
|
|||||||
assertNull(parse("Sun, 6 Nov 1994 28:49:37 GMT"));
|
assertNull(parse("Sun, 6 Nov 1994 28:49:37 GMT"));
|
||||||
assertNull(parse("Sun, 6 Nov 1994 08:69:37 GMT"));
|
assertNull(parse("Sun, 6 Nov 1994 08:69:37 GMT"));
|
||||||
assertNull(parse("Sun, 6 Nov 1994 08:49:67 GMT"));
|
assertNull(parse("Sun, 6 Nov 1994 08:49:67 GMT"));
|
||||||
|
//wrong number of digits in timestamp
|
||||||
|
assertNull(parse("Sunday, 6 Nov 1994 0:0:000 GMT"));
|
||||||
|
assertNull(parse("Sunday, 6 Nov 1994 0:000:0 GMT"));
|
||||||
|
assertNull(parse("Sunday, 6 Nov 1994 000:0:0 GMT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user