Bug 1402151, part 1 - Improve handling of two digit years. r=michal draft
 author Andrew McCreight Thu, 21 Sep 2017 16:34:07 -0700 changeset 680191 e0b4a0b0f307b12921afb9f47a80cd4f32b46987 parent 680024 196dadb2fe500e75c6fbddcac78106648676cf10 child 680192 0d1a14f97e12b7324e31d61215d3359e01f10878 push id 84417 push user bmo:continuation@gmail.com push date Fri, 13 Oct 2017 16:41:48 +0000 reviewers michal bugs 1402151 milestone 58.0a1
Bug 1402151, part 1 - Improve handling of two digit years. r=michal The tm_year field of PRExplodedTime is an absolute year, not years since 1900, so fix a few places that try to do the latter. I also made the conversion of 2 digit years more consistent. MozReview-Commit-ID: GetS2wmXHhA
```--- a/netwerk/streamconv/converters/ParseFTPList.cpp
+++ b/netwerk/streamconv/converters/ParseFTPList.cpp
@@ -20,16 +20,29 @@ using mozilla::CheckedInt;

static inline int ParsingFailed(struct list_state *state)
{
if (state->parsed_one || state->lstyle) /* junk if we fail to parse */
return '?';      /* this time but had previously parsed successfully */
return '"';        /* its part of a comment or error message */
}

+void
+FixupYear(PRExplodedTime* aTime)
+{
+  /* if year has only two digits then assume that
+     00-79 is 2000-2079
+     80-99 is 1980-1999 */
+  if (aTime->tm_year < 80) {
+    aTime->tm_year += 2000;
+  } else if (aTime->tm_year < 100) {
+    aTime->tm_year += 1900;
+  }
+}
+
int ParseFTPList(const char *line, struct list_state *state,
struct list_result *result )
{
unsigned int carry_buf_len; /* copy of state->carry_buf_len */
unsigned int pos;
const char *p;

if (!line || !state || !result)
@@ -650,28 +663,27 @@ int ParseFTPList(const char *line, struc
if (lstyle == 'C')
{
state->parsed_one = 1;
state->lstyle = lstyle;

p = tokens[tokmarker+4];
if (toklen[tokmarker+4] == 10) /* newstyle: YYYY-MM-DD format */
{
-          result->fe_time.tm_year = atoi(p+0) - 1900;
+          result->fe_time.tm_year = atoi(p+0);
result->fe_time.tm_month  = atoi(p+5) - 1;
result->fe_time.tm_mday = atoi(p+8);
}
else /* oldstyle: [M]M/DD/YY format */
{
pos = toklen[tokmarker+4];
result->fe_time.tm_month  = atoi(p) - 1;
result->fe_time.tm_mday = atoi((p+pos)-5);
result->fe_time.tm_year = atoi((p+pos)-2);
-          if (result->fe_time.tm_year < 70)
-            result->fe_time.tm_year += 100;
+          FixupYear(&result->fe_time);
}

p = tokens[tokmarker+5];
pos = toklen[tokmarker+5];
result->fe_time.tm_hour  = atoi(p);
result->fe_time.tm_min = atoi((p+pos)-5);
result->fe_time.tm_sec = atoi((p+pos)-2);

@@ -824,23 +836,17 @@ int ParseFTPList(const char *line, struc
}

result->fe_time.tm_month = atoi(tokens[0]+0);
if (result->fe_time.tm_month != 0)
{
result->fe_time.tm_month--;
result->fe_time.tm_mday = atoi(tokens[0]+3);
result->fe_time.tm_year = atoi(tokens[0]+6);
-          /* if year has only two digits then assume that
-               00-79 is 2000-2079
-               80-99 is 1980-1999 */
-          if (result->fe_time.tm_year < 80)
-            result->fe_time.tm_year += 2000;
-          else if (result->fe_time.tm_year < 100)
-            result->fe_time.tm_year += 1900;
+          FixupYear(&result->fe_time);
}

result->fe_time.tm_hour = atoi(tokens[1]+0);
result->fe_time.tm_min = atoi(tokens[1]+3);
if (toklen[1] == 7)
{
if ((tokens[1][5]) == 'P' && result->fe_time.tm_hour < 12)
result->fe_time.tm_hour += 12;
@@ -942,18 +948,17 @@ int ParseFTPList(const char *line, struc
pos = (sizeof(result->fe_size)-1);
memcpy( result->fe_size, tokens[0], pos );
result->fe_size[pos] = '\0';
}

result->fe_time.tm_month = atoi(&p[35-18]) - 1;
result->fe_time.tm_mday = atoi(&p[38-18]);
result->fe_time.tm_year = atoi(&p[41-18]);
-        if (result->fe_time.tm_year < 80)
-          result->fe_time.tm_year += 100;
+        FixupYear(&result->fe_time);
result->fe_time.tm_hour = atoi(&p[46-18]);
result->fe_time.tm_min = atoi(&p[49-18]);

/* the caller should do this (if dropping "." and ".." is desired)
if (result->fe_type == 'd' && result->fe_fname[0] == '.' &&
(result->fe_fnlen == 1 || (result->fe_fnlen == 2 &&
result->fe_fname[1] == '.')))
return '?';
@@ -1369,29 +1374,28 @@ int ParseFTPList(const char *line, struc
for (pos = 0; pos < (12*3); pos+=3)
{
if (tbuf[0] == month_names[pos+0] &&
tbuf[1] == month_names[pos+1] &&
tbuf[2] == month_names[pos+2])
{
result->fe_time.tm_month = pos/3;
result->fe_time.tm_mday = atoi(tokens[3]);
-              result->fe_time.tm_year = atoi(tokens[4]) - 1900;
+              result->fe_time.tm_year = atoi(tokens[4]);
break;
}
}
pos = 5; /* Chameleon toknum of date field */
}
else
{
result->fe_time.tm_month = atoi(p+0)-1;
result->fe_time.tm_mday = atoi(p+3);
result->fe_time.tm_year = atoi(p+6);
-          if (result->fe_time.tm_year < 80) /* SuperTCP */
-            result->fe_time.tm_year += 100;
+          FixupYear(&result->fe_time); /* SuperTCP */

pos = 3; /* SuperTCP toknum of date field */
}

result->fe_time.tm_hour = atoi(tokens[pos]);
result->fe_time.tm_min = atoi(&(tokens[pos][toklen[pos]-2]));

/* the caller should do this (if dropping "." and ".." is desired)
@@ -1626,17 +1630,17 @@ int ParseFTPList(const char *line, struc
}
if (result->fe_time.tm_mday)
{
tokmarker += 3; /* skip mday/mon/yrtime (to find " -> ") */
p = tokens[tokmarker];

pos = atoi(p);
if (pos > 24)
-                result->fe_time.tm_year = pos-1900;
+                result->fe_time.tm_year = pos;
else
{
if (p[1] == ':')
p--;
result->fe_time.tm_hour = pos;
result->fe_time.tm_min = atoi(p+3);
if (!state->now_time)
{```