details: https://hg.nginx.org/njs/rev/ed4ff34dfc63 branches: changeset: 2154:ed4ff34dfc63 user: Dmitry Volyntsev <xei...@nginx.com> date: Mon Jun 12 22:04:04 2023 -0700 description: Fixed Date.parse() with ISO-8601 format and UTC time offset.
diffstat: src/njs_date.c | 65 +++++++++++++++++++++++++++++++++++++++-------- src/test/njs_unit_test.c | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 11 deletions(-) diffs (162 lines): diff -r 803a5061b362 -r ed4ff34dfc63 src/njs_date.c --- a/src/njs_date.c Mon Jun 12 20:51:54 2023 -0700 +++ b/src/njs_date.c Mon Jun 12 22:04:04 2023 -0700 @@ -493,11 +493,44 @@ njs_date_parse(njs_vm_t *vm, njs_value_t } +static int64_t +njs_date_utc_offset_parse(const u_char *start, const u_char *end) +{ + int64_t utc_off, hour, min; + const u_char *p; + + if (njs_fast_path(start + 2 < end && (*start == '+' || *start == '-'))) { + p = njs_date_number_parse(&hour, start + 1, end, 2); + if (njs_slow_path(p == NULL || hour > 23)) { + return -1; + } + + if (p < end && *p == ':') { + p++; + } + + p = njs_date_number_parse(&min, p, end, 2); + if (njs_slow_path(p == NULL || min > 59)) { + return -1; + } + + utc_off = hour * 60 + min; + + if (*start == '-') { + utc_off = -utc_off; + } + + return utc_off; + } + + return -1; +} + static double njs_date_string_parse(njs_value_t *date) { size_t ms_length; - int64_t ext, skipped; + int64_t ext, utc_off; njs_str_t string; njs_bool_t sign, week, utc; const u_char *p, *next, *end; @@ -616,25 +649,37 @@ njs_date_string_parse(njs_value_t *date) p++; - ms_length = (end - p < 3) ? end - p : 3; + for (ms_length = 0; p + ms_length < end; ms_length++) { + if (p[ms_length] < '0' || p[ms_length] > '9') { + break; + } + } p = njs_date_number_parse(&tm[NJS_DATE_MSEC], p, end, ms_length); if (njs_slow_path(p == NULL)) { return NAN; } - if (end > p) { - p = njs_date_number_parse(&skipped, p, end, end - p); - if (njs_slow_path(p == NULL)) { - return NAN; - } - } - if (ms_length == 1) { tm[NJS_DATE_MSEC] *= 100; } else if (ms_length == 2) { tm[NJS_DATE_MSEC] *= 10; + + } else if (ms_length >= 4) { + for (ms_length -= 3; ms_length > 0; ms_length--) { + tm[NJS_DATE_MSEC] /= 10; + } + } + + if (p < end) { + utc_off = njs_date_utc_offset_parse(p, end); + if (njs_slow_path(utc_off == -1)) { + return NAN; + } + + utc = 1; + tm[NJS_DATE_MSEC] += -utc_off * 60000; } done: @@ -685,8 +730,6 @@ done: week = 0; } - - return njs_make_date(tm, 0); } diff -r 803a5061b362 -r ed4ff34dfc63 src/test/njs_unit_test.c --- a/src/test/njs_unit_test.c Mon Jun 12 20:51:54 2023 -0700 +++ b/src/test/njs_unit_test.c Mon Jun 12 22:04:04 2023 -0700 @@ -16172,6 +16172,54 @@ static njs_unit_test_t njs_test[] = { njs_str("Date.parse('2011-06-24T06:01:02.625Z')"), njs_str("1308895262625") }, + { njs_str("Date.parse('2011-06-24T06:01:02.625+00:00')"), + njs_str("1308895262625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+0000')"), + njs_str("1308895262625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+00:0')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+00:')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+00')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+0')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625-01:15')"), + njs_str("1308899762625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625-01:60')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625-25:59')"), + njs_str("NaN") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+01:15')"), + njs_str("1308890762625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625-23:59')"), + njs_str("1308981602625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625+23:59')"), + njs_str("1308808922625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.6255Z')"), + njs_str("1308895262625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.62555Z')"), + njs_str("1308895262625") }, + + { njs_str("Date.parse('2011-06-24T06:01:02.625555Z')"), + njs_str("1308895262625") }, + { njs_str("Date.parse('2011-06-24T06:01:02.6255555Z')"), njs_str("1308895262625") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel