Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Unified Diff: base/third_party/nspr/prtime.cc

Issue 266193002: Extend PR_ParseTimeString() to accept some ISO 8601 formats to fix timezone parsing in SyslogParser. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address wtc's comments. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/third_party/nspr/prtime.h ('k') | base/time/pr_time_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/third_party/nspr/prtime.cc
diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
index 0c97bc16d8832c793da8269c01bc8d9350e1e404..e6253cbb4135cac6e769127d94735beffff031c7 100644
--- a/base/third_party/nspr/prtime.cc
+++ b/base/third_party/nspr/prtime.cc
@@ -61,6 +61,8 @@
* 1. prtime.h
* 2. prtypes.h
* 3. prlong.h
+ *
+ * Unit tests are in base/time/pr_time_unittest.cc.
*/
#include "base/logging.h"
@@ -505,6 +507,7 @@ typedef enum
* 06/21/95 04:24:34 PM
* 20/06/95 21:07
* 95-06-08 19:32:48 EDT
+ * 1995-06-17T23:11:25.342156Z
*
* If the input string doesn't contain a description of the timezone,
* we consult the `default_to_gmt' to decide whether the string should
@@ -531,6 +534,7 @@ PR_ParseTimeString(
int hour = -1;
int min = -1;
int sec = -1;
+ int usec = -1;
const char *rest = string;
@@ -774,6 +778,7 @@ PR_ParseTimeString(
int tmp_hour = -1;
int tmp_min = -1;
int tmp_sec = -1;
+ int tmp_usec = -1;
const char *end = rest + 1;
while (*end >= '0' && *end <= '9')
end++;
@@ -833,14 +838,35 @@ PR_ParseTimeString(
else
tmp_sec = (rest[0]-'0');
- /* If we made it here, we've parsed hour and min,
- and possibly sec, so it worked as a unit. */
-
- /* skip over whitespace and see if there's an AM or PM
- directly following the time.
- */
- if (tmp_hour <= 12)
+ /* fractional second */
+ rest = end;
+ if (*rest == '.') {
+ rest++;
+ end++;
+ tmp_usec = 0;
+ /* use up to 6 digits, skip over the rest */
+ while (*end >= '0' && *end <= '9') {
+ if (end - rest < 6) {
+ tmp_usec = tmp_usec * 10 + *end - '0';
+ }
+ end++;
+ }
+ int ndigits = end - rest;
+ while (ndigits++ < 6)
+ tmp_usec *= 10;
+ }
+
+ if (*end == 'Z') {
+ zone = TT_GMT;
wtc 2014/05/12 19:47:15 Should we do end++; here? Otherwise 'Z' may
Thiemo Nagel 2014/05/13 14:08:19 It's not strictly necessary because the break will
+ }
wtc 2014/05/12 19:47:15 Nit: Lines 843-861 probably should follow the brac
Thiemo Nagel 2014/05/13 14:08:19 Thanks, I fully agree. Done.
+ else if (tmp_hour <= 12)
{
+ /* If we made it here, we've parsed hour and min,
+ and possibly sec, so it worked as a unit. */
wtc 2014/05/12 19:47:15 By "it worked as a unit", did you mean we have ful
Thiemo Nagel 2014/05/13 14:08:19 That's how I understand the original author. (I'v
+
+ /* skip over whitespace and see if there's an AM or PM
+ directly following the time.
+ */
const char *s = end;
while (*s && (*s == ' ' || *s == '\t'))
s++;
@@ -858,6 +884,7 @@ PR_ParseTimeString(
hour = tmp_hour;
min = tmp_min;
sec = tmp_sec;
+ usec = tmp_usec;
rest = end;
break;
}
@@ -865,8 +892,7 @@ PR_ParseTimeString(
end[1] >= '0' && end[1] <= '9')
{
/* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95
- or even 95-06-05...
- #### But it doesn't handle 1995-06-22.
+ or even 95-06-05 or 1995-06-22.
*/
int n1, n2, n3;
const char *s;
@@ -877,10 +903,18 @@ PR_ParseTimeString(
s = rest;
- n1 = (*s++ - '0'); /* first 1 or 2 digits */
+ n1 = (*s++ - '0'); /* first 1, 2 or 4 digits */
if (*s >= '0' && *s <= '9')
n1 = n1*10 + (*s++ - '0');
+ if (*s >= '0' && *s <= '9') /* optional digits 3 and 4 */
+ {
+ n1 = n1*10 + (*s++ - '0');
+ if (*s < '0' || *s > '9')
+ break;
wtc 2014/05/12 19:47:15 This break statement means you want to disallow a
Thiemo Nagel 2014/05/13 14:08:19 Yes, that's the intent.
+ n1 = n1*10 + (*s++ - '0');
+ }
wtc 2014/05/12 19:47:15 Nit: it seems that this new if block (lines 910-91
Thiemo Nagel 2014/05/13 14:08:19 Yes, good point, that's more readable.
+
if (*s != '/' && *s != '-') /* slash */
break;
s++;
@@ -911,17 +945,21 @@ PR_ParseTimeString(
n3 = n3*10 + (*s++ - '0');
}
- if ((*s >= '0' && *s <= '9') || /* followed by non-alphanum */
- (*s >= 'A' && *s <= 'Z') ||
- (*s >= 'a' && *s <= 'z'))
+ if (*s == 'T' && s[1] >= '0' && s[1] <= '9')
+ /* followed by ISO 8601 T delimiter and number is ok */
+ ;
+ else if ((*s >= '0' && *s <= '9') ||
+ (*s >= 'A' && *s <= 'Z') ||
+ (*s >= 'a' && *s <= 'z'))
+ /* but other alphanumerics are not ok */
break;
- /* Ok, we parsed three 1-2 digit numbers, with / or -
+ /* Ok, we parsed three multi-digit numbers, with / or -
between them. Now decide what the hell they are
- (DD/MM/YY or MM/DD/YY or YY/MM/DD.)
+ (DD/MM/YY or MM/DD/YY or [YY]YY/MM/DD.)
*/
- if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */
+ if (n1 > 31 || n1 == 0) /* must be [YY]YY/MM/DD */
{
if (n2 > 12) break;
if (n3 > 31) break;
@@ -1026,14 +1064,15 @@ PR_ParseTimeString(
*rest != ',' && *rest != ';' &&
*rest != '-' && *rest != '+' &&
*rest != '/' &&
- *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']')
+ *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']' &&
+ !(*rest == 'T' && rest[1] >= '0' && rest[1] <= '9') /* T precedes time in ISO 8601 */
wtc 2014/05/12 19:47:15 Nit: maybe this comment should be moved to the com
Thiemo Nagel 2014/05/13 14:08:19 Done. At that occasion, I've updated the pre-exis
+ )
rest++;
/* skip over uninteresting chars. */
SKIP_MORE:
- while (*rest &&
Thiemo Nagel 2014/05/09 16:19:00 *rest is redundant here.
- (*rest == ' ' || *rest == '\t' ||
- *rest == ',' || *rest == ';' || *rest == '/' ||
- *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']'))
+ while (*rest == ' ' || *rest == '\t' ||
+ *rest == ',' || *rest == ';' || *rest == '/' ||
+ *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']')
rest++;
/* "-" is ignored at the beginning of a token if we have not yet
@@ -1047,7 +1086,11 @@ PR_ParseTimeString(
goto SKIP_MORE;
}
- }
+ /* Skip T that may precede ISO 8601 time. */
+ if (*rest == 'T' && rest[1] >= '0' && rest[1] <= '9')
+ rest++;
+
wtc 2014/05/12 19:47:15 Nit: delete this blank line.
Thiemo Nagel 2014/05/13 14:08:19 Done.
+ } /* while */
if (zone != TT_UNKNOWN && zone_offset == -1)
{
@@ -1082,6 +1125,8 @@ PR_ParseTimeString(
return PR_FAILURE;
memset(result, 0, sizeof(*result));
+ if (usec != -1)
+ result->tm_usec = usec;
if (sec != -1)
result->tm_sec = sec;
if (min != -1)
« no previous file with comments | « base/third_party/nspr/prtime.h ('k') | base/time/pr_time_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698