aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-11-14 14:57:32 -0500
committerNick Mathewson <nickm@torproject.org>2016-11-30 14:42:52 -0500
commit539eba0a4bab1e22a7e2e19132d356e99c32e232 (patch)
tree8cb80377dfdb33b7cb1fed231cf5b44c96851843
parentdf8256a931099767d9f70997c9eb1ef934afd392 (diff)
downloadtor-539eba0a4bab1e22a7e2e19132d356e99c32e232.tar.gz
tor-539eba0a4bab1e22a7e2e19132d356e99c32e232.zip
Teach parse_iso_time about the spaceless variant.
(We previously added support for generating the spaceless 2016-11-14T19:58:12 variant, but not for actually parsing it.)
-rw-r--r--src/common/util.c32
-rw-r--r--src/common/util.h3
-rw-r--r--src/or/entrynodes.c2
-rw-r--r--src/or/routerparse.c3
-rw-r--r--src/test/test_util.c17
5 files changed, 47 insertions, 10 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 3421d117b0..ec4ecf2d66 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1803,17 +1803,26 @@ format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
* parse it and store its value in *<b>t</b>. Return 0 on success, -1 on
* failure. Ignore extraneous stuff in <b>cp</b> after the end of the time
- * string, unless <b>strict</b> is set. */
+ * string, unless <b>strict</b> is set. If <b>nospace</b> is set,
+ * expect the YYYY-MM-DDTHH:MM:SS format. */
int
-parse_iso_time_(const char *cp, time_t *t, int strict)
+parse_iso_time_(const char *cp, time_t *t, int strict, int nospace)
{
struct tm st_tm;
unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0;
int n_fields;
- char extra_char;
- n_fields = tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u%c", &year, &month,
- &day, &hour, &minute, &second, &extra_char);
- if (strict ? (n_fields != 6) : (n_fields < 6)) {
+ char extra_char, separator_char;
+ n_fields = tor_sscanf(cp, "%u-%2u-%2u%c%2u:%2u:%2u%c",
+ &year, &month, &day,
+ &separator_char,
+ &hour, &minute, &second, &extra_char);
+ if (strict ? (n_fields != 7) : (n_fields < 7)) {
+ char *esc = esc_for_log(cp);
+ log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
+ tor_free(esc);
+ return -1;
+ }
+ if (separator_char != (nospace ? 'T' : ' ')) {
char *esc = esc_for_log(cp);
log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
tor_free(esc);
@@ -1855,7 +1864,16 @@ parse_iso_time_(const char *cp, time_t *t, int strict)
int
parse_iso_time(const char *cp, time_t *t)
{
- return parse_iso_time_(cp, t, 1);
+ return parse_iso_time_(cp, t, 1, 0);
+}
+
+/**
+ * As parse_iso_time, but parses a time encoded by format_iso_time_nospace().
+ */
+int
+parse_iso_time_nospace(const char *cp, time_t *t)
+{
+ return parse_iso_time_(cp, t, 1, 1);
}
/** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh),
diff --git a/src/common/util.h b/src/common/util.h
index 37f4bed1cb..2b3e48ea8e 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -255,8 +255,9 @@ void format_local_iso_time(char *buf, time_t t);
void format_iso_time(char *buf, time_t t);
void format_iso_time_nospace(char *buf, time_t t);
void format_iso_time_nospace_usec(char *buf, const struct timeval *tv);
-int parse_iso_time_(const char *cp, time_t *t, int strict);
+int parse_iso_time_(const char *cp, time_t *t, int strict, int nospace);
int parse_iso_time(const char *buf, time_t *t);
+int parse_iso_time_nospace(const char *cp, time_t *t);
int parse_http_time(const char *buf, struct tm *tm);
int format_time_interval(char *out, size_t out_len, long interval);
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index bd4d83c4a0..c96ff095da 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1502,7 +1502,7 @@ entry_guards_parse_state_for_guard_selection(
"EntryGuardDownSince/UnlistedSince without EntryGuard");
break;
}
- if (parse_iso_time_(line->value, &when, 0)<0) {
+ if (parse_iso_time_(line->value, &when, 0, 0)<0) {
*msg = tor_strdup("Unable to parse entry nodes: "
"Bad time in EntryGuardDownSince/UnlistedSince");
break;
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 2cfd3fc58a..60fdce0b64 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -5150,7 +5150,8 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
* descriptor. */
tok = find_by_keyword(tokens, R_PUBLICATION_TIME);
tor_assert(tok->n_args == 1);
- if (parse_iso_time_(tok->args[0], &result->timestamp, strict_time_fmt) < 0) {
+ if (parse_iso_time_(tok->args[0], &result->timestamp,
+ strict_time_fmt, 0) < 0) {
log_warn(LD_REND, "Invalid publication time: '%s'", tok->args[0]);
goto err;
}
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b74f658146..187bfdd93c 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1059,6 +1059,23 @@ test_util_time(void *arg)
tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res));
tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res));
+ /* but... that _is_ acceptable if we aren't being strict. */
+ t_res = 0;
+ i = parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res, 0, 0);
+ tt_int_op(0,OP_EQ, i);
+ tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
+
+ /* try nospace variant. */
+ t_res = 0;
+ i = parse_iso_time_nospace("2004-08-04T00:48:22", &t_res);
+ tt_int_op(0,OP_EQ, i);
+ tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
+
+ tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04T00:48:22", &t_res));
+ tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res));
+ tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04x00:48:22", &t_res));
+ tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res));
+
/* Test tor_gettimeofday */
end.tv_sec = 4;