From 886a7aae465cceb5f90ede01d98de31e35ae404a Mon Sep 17 00:00:00 2001 From: radai-rosenblatt Date: Sun, 20 Nov 2016 17:06:52 -0800 Subject: [PATCH] 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 --- .../codec/http/HttpHeaderDateFormatter.java | 17 ++++++++++------- .../codec/http/HttpHeaderDateFormatterTest.java | 9 +++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderDateFormatter.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderDateFormatter.java index 5fefabcd02..729c568cba 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderDateFormatter.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpHeaderDateFormatter.java @@ -188,40 +188,43 @@ public final class HttpHeaderDateFormatter { int localSeconds = -1; int currentPartNumber = 0; int currentPartValue = 0; + int numDigits = 0; for (int i = tokenStart; i < tokenEnd; i++) { char c = txt.charAt(i); if (isDigit(c)) { currentPartValue = currentPartValue * 10 + getNumericalValue(c); + if (++numDigits > 2) { + return false; // too many digits in this part + } } else if (c == ':') { - if (currentPartValue == 0) { - // invalid :: (nothing in between) + if (numDigits == 0) { + // no digits between separators return false; } switch (currentPartNumber) { case 0: // flushing hours localHours = currentPartValue; - currentPartValue = 0; - currentPartNumber++; break; case 1: // flushing minutes localMinutes = currentPartValue; - currentPartValue = 0; - currentPartNumber++; break; default: // invalid, too many : return false; } + currentPartValue = 0; + currentPartNumber++; + numDigits = 0; } else { // invalid char return false; } } - if (currentPartValue > 0) { + if (numDigits > 0) { // pending seconds localSeconds = currentPartValue; } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpHeaderDateFormatterTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpHeaderDateFormatterTest.java index c22868b49e..24f8b4343e 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpHeaderDateFormatterTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpHeaderDateFormatterTest.java @@ -78,6 +78,11 @@ public class HttpHeaderDateFormatterTest { 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 public void testParseInvalidInput() { // 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 08:69:37 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