From: Arran Cudbard-Bell Date: Thu, 28 Oct 2021 22:00:40 +0000 (-0400) Subject: Add substr parser from time deltas X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95d37dce4d3edf2a5c55876ca1d0c67fd2e34d44;p=thirdparty%2Ffreeradius-server.git Add substr parser from time deltas --- diff --git a/src/bin/dhcpclient.c b/src/bin/dhcpclient.c index 8596e3781cb..b793133a87e 100644 --- a/src/bin/dhcpclient.c +++ b/src/bin/dhcpclient.c @@ -608,7 +608,7 @@ int main(int argc, char **argv) break; case 't': - if (fr_time_delta_from_str(&timeout, optarg, FR_TIME_RES_SEC) < 0) usage(); + if (fr_time_delta_from_str(&timeout, optarg, strlen(optarg), FR_TIME_RES_SEC) < 0) usage(); break; case 'v': diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 2e4977bdd78..4fb7d49b1e3 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -1315,7 +1315,7 @@ int main(int argc, char **argv) break; case 't': - if (fr_time_delta_from_str(&timeout, optarg, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&timeout, optarg, strlen(optarg), FR_TIME_RES_SEC) < 0) { fr_perror("Failed parsing timeout value"); fr_exit_now(EXIT_FAILURE); } diff --git a/src/bin/radsnmp.c b/src/bin/radsnmp.c index 92beb9fb9af..53b5038a30e 100644 --- a/src/bin/radsnmp.c +++ b/src/bin/radsnmp.c @@ -1013,7 +1013,7 @@ int main(int argc, char **argv) break; case 't': - if (fr_time_delta_from_str(&conf->timeout, optarg, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&conf->timeout, optarg, strlen(optarg), FR_TIME_RES_SEC) < 0) { fr_perror("Failed parsing timeout value"); fr_exit_now(EXIT_FAILURE); } diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index b374e48ccbb..99dd53d41f9 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -483,7 +483,7 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM { fr_time_delta_t delta; - if (fr_time_delta_from_str(&delta, cp->value, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&delta, cp->value, strlen(cp->value), FR_TIME_RES_SEC) < 0) { cf_log_perr(cp, "Failed parsing config item"); goto error; } diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index 42c918a5323..f734cc247e5 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -1574,7 +1574,7 @@ static bool compile_retry_section(unlang_actions_t *actions, CONF_ITEM *ci) * magical reasons. */ if (strcmp(name, "initial_rtx_time") == 0) { - if (fr_time_delta_from_str(&actions->retry.irt, value, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&actions->retry.irt, value, strlen(value), FR_TIME_RES_SEC) < 0) { error: cf_log_err(csi, "Failed parsing '%s = %s' - %s", name, value, fr_strerror()); @@ -1582,7 +1582,7 @@ static bool compile_retry_section(unlang_actions_t *actions, CONF_ITEM *ci) } } else if (strcmp(name, "max_rtx_time") == 0) { - if (fr_time_delta_from_str(&actions->retry.mrt, value, FR_TIME_RES_SEC) < 0) goto error; + if (fr_time_delta_from_str(&actions->retry.mrt, value, strlen(value), FR_TIME_RES_SEC) < 0) goto error; } else if (strcmp(name, "max_rtx_count") == 0) { unsigned long v = strtoul(value, 0, 0); @@ -1596,7 +1596,7 @@ static bool compile_retry_section(unlang_actions_t *actions, CONF_ITEM *ci) actions->retry.mrc = v; } else if (strcmp(name, "max_rtx_duration") == 0) { - if (fr_time_delta_from_str(&actions->retry.mrd, value, FR_TIME_RES_SEC) < 0) goto error; + if (fr_time_delta_from_str(&actions->retry.mrd, value, strlen(value), FR_TIME_RES_SEC) < 0) goto error; } else { cf_log_err(csi, "Invalid item '%s' in 'retry' configuration.", name); return false; diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 33cc3fd3b91..6b55971e0db 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -64,6 +64,10 @@ bool const sbuff_char_class_float[UINT8_MAX + 1] = { ['-'] = true, ['+'] = true, ['e'] = true, ['E'] = true, ['.'] = true, }; +bool const sbuff_char_class_zero[UINT8_MAX + 1] = { + ['0'] = true +}; + bool const sbuff_char_class_hex[UINT8_MAX + 1] = { SBUFF_CHAR_CLASS_HEX }; bool const sbuff_char_alpha_num[UINT8_MAX + 1] = { SBUFF_CHAR_CLASS_ALPHA_NUM }; bool const sbuff_char_whitespace[UINT8_MAX + 1] = { diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index f0f068aaa71..6d3ae09b335 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -259,6 +259,7 @@ typedef enum { extern bool const sbuff_char_class_uint[UINT8_MAX + 1]; extern bool const sbuff_char_class_int[UINT8_MAX + 1]; extern bool const sbuff_char_class_float[UINT8_MAX + 1]; +extern bool const sbuff_char_class_zero[UINT8_MAX + 1]; extern bool const sbuff_char_class_hex[UINT8_MAX + 1]; extern bool const sbuff_char_alpha_num[UINT8_MAX + 1]; extern bool const sbuff_char_whitespace[UINT8_MAX + 1]; @@ -1549,6 +1550,8 @@ size_t fr_sbuff_adv_past_strcase(fr_sbuff_t *sbuff, char const *needle, size_t n size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX + 1], fr_sbuff_term_t const *tt); +#define fr_sbuff_adv_past_zeros(_sbuff, _len, _tt) fr_sbuff_adv_past_allowed(_sbuff, _len, sbuff_char_class_zero, _tt) + #define fr_sbuff_adv_past_whitespace(_sbuff, _len, _tt) fr_sbuff_adv_past_allowed(_sbuff, _len, sbuff_char_whitespace, _tt) #define fr_sbuff_adv_past_blank(_sbuff, _len, _tt) fr_sbuff_adv_past_allowed(_sbuff, _len, sbuff_char_blank, _tt) diff --git a/src/lib/util/time.c b/src/lib/util/time.c index aeb5377d1f5..3d55a5c68b7 100644 --- a/src/lib/util/time.c +++ b/src/lib/util/time.c @@ -55,7 +55,7 @@ int64_t const fr_time_multiplier_by_res[] = { [FR_TIME_RES_SEC] = NSEC, [FR_TIME_RES_MIN] = (int64_t)NSEC * 60, [FR_TIME_RES_HOUR] = (int64_t)NSEC * 3600, - [FR_TIME_RES_DAY] = (int64_t)NSEC * 386400 + [FR_TIME_RES_DAY] = (int64_t)NSEC * 86400 }; fr_table_num_ordered_t const fr_time_precision_table[] = { @@ -240,249 +240,259 @@ int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta) /** Create fr_time_delta_t from a string * - * @param[out] out Where to write fr_time_delta_t - * @param[in] in String to parse. - * @param[in] hint scale for the parsing. Default is "seconds" + * @param[out] out Where to write fr_time_delta_t + * @param[in] in String to parse. + * @param[in] hint scale for the parsing. Default is "seconds". + * @param[in] no_trailing asserts that there should be a terminal sequence + * after the time delta. Allows us to produce + * better errors. + * @param[in] tt terminal sequences. * @return - * - 0 on success. - * - -1 on failure. + * - >= 0 on success. + * - <0 on failure. */ -int fr_time_delta_from_str(fr_time_delta_t *out, char const *in, fr_time_res_t hint) +fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, + bool no_trailing, fr_sbuff_term_t const *tt) { - int64_t sec; - uint64_t subsec = 0; - int scale = 1; - char *p, *next = NULL; - bool negative = false; - - if (*in == '-') negative = true; /* catch the case of negative zero! */ - - sec = strtoll(in, &next, 10); - if (in == next) { - failed: - fr_strerror_printf("Failed parsing \"%s\" as time_delta", in); - return -1; + fr_sbuff_t our_in = FR_SBUFF(in); + int64_t integer; /* Whole units */ + fr_time_res_t res; + bool negative; + fr_sbuff_parse_error_t sberr; + bool overflow; + fr_time_delta_t delta; /* The delta we're building */ + size_t match_len; + + negative = fr_sbuff_is_char(&our_in, '-'); + + if (fr_sbuff_out(&sberr, &integer, &our_in) < 0) { + num_error: + fr_strerror_printf("Failed parsing time_delta: %s", + fr_table_str_by_value(sbuff_parse_error_table, sberr, "")); + return fr_sbuff_error(&our_in); } + fr_sbuff_out_by_longest_prefix(&match_len, &res, fr_time_precision_table, &our_in, FR_TIME_RES_INVALID); /* - * The input is just a number. Scale and clamp it as appropriate. + * We now determine which one of the three formats + * we accept the string is in. + * + * Either: + * - [] + * - .[] + * - [hours:]minutes:seconds */ - if (!next || !*next) { - *out = fr_time_delta_from_nsec(fr_time_scale(sec, hint)); - return 0; - } /* - * Allow "1ns", etc. - */ - if ((*next >= 'a') && (*next <= 'z')) { - p = next; - goto parse_precision; - } - - /* - * Decimal number + * We have a fractional component + * + * .[] */ - if (*next == '.') { - int len; - - len = subsec = 0; - - next++; - p = next; + if (fr_sbuff_next_if_char(&our_in, '.')) { + fr_sbuff_marker_t m_f; + size_t f_len; + uint64_t f; /* Fractional units */ /* - * Parse the decimal portion of a number like "0.1". + * Normalise as a positive integer */ - while ((*p >= '0') && (*p <= '9')) { - if (len > 9) { - fr_strerror_const("Too much precision for time_delta"); - return -1; - } - - subsec *= 10; - subsec += *p - '0'; - p++; - len++; - } + if (negative) integer = -(integer); /* - * We've just parsed the fractional part of "0.1" - * as "1". We need to shift it left to convert - * it to nanoseconds. + * Mark the start of the fractional component */ - while (len < 9) { - subsec *= 10; - len++; - } + fr_sbuff_marker(&m_f, &our_in); - parse_precision: /* - * No precision qualifiers, it defaults to - * whatever scale the caller passed as a hint. + * Leading zeros appear to mess up integer parsing */ - if (!*p) goto do_scale; + fr_sbuff_adv_past_zeros(&our_in, SIZE_MAX, tt); - if ((p[0] == 's') && !p[1]) { - scale = NSEC; - goto done; + if (fr_sbuff_out(&sberr, &f, &our_in) < 0) { + /* + * Crappy workaround for .0 + * + * Advancing past the leading zeros screws + * up the fractional parsing when the + * fraction is all zeros... + */ + if ((sberr != FR_SBUFF_PARSE_ERROR_NOT_FOUND) || (*fr_sbuff_current(&m_f) != '0')) goto num_error; + } + + f_len = fr_sbuff_behind(&m_f); + if (f_len > 9) { + fr_strerror_const("Too much precision for time_delta"); + fr_sbuff_set(&our_in, fr_sbuff_current(&m_f) + 10); + return fr_sbuff_error(&our_in); } /* - * Everything else has "ms" or "us" or "ns". + * Convert to nanoseconds * - * "1.1ns" means "parse it as 1.1s, and then - * shift it right 9 orders of magnitude to - * convert it to nanoseconds. + * This can't overflow. */ - if ((p[1] == 's') && (p[2] == '\0')) { - if (p[0] == 'm') { - scale = 1000000; /* 1,000,000 nanoseconds in a millisecond */ - goto done; - } + while (f_len < 9) { + f *= 10; + f_len++; + } - if (p[0] == 'u') { - scale = 1000; /* 1,000 msec on a used */ - goto done; + /* + * Look for a scale suffix + */ + fr_sbuff_out_by_longest_prefix(&match_len, &res, fr_time_precision_table, &our_in, FR_TIME_RES_INVALID); + + if (no_trailing && !fr_sbuff_is_terminal(&our_in, tt)) { + trailing_data: + /* Got a qualifier but there's stuff after */ + if (res != FR_TIME_RES_INVALID) { + fr_strerror_const("Trailing data after time_delta"); + return fr_sbuff_error(&our_in); } - if (p[0] == 'n') { - scale = 1; - goto done; - } + fr_strerror_const("Invalid precision qualifier for time_delta"); + return fr_sbuff_error(&our_in); } + /* Scale defaults to hint */ + if (res == FR_TIME_RES_INVALID) res = hint; + /* - * minutes, hours, or days. - * - * Fractional numbers are not allowed. + * Subseconds was parsed as if it was nanoseconds. + * But instead it may be something else, so it should + * be truncated. * - * minutes / hours / days larger than 64K are disallowed. + * Note that this operation can't overflow. */ - if (sec > 65535) { - fr_strerror_printf("Invalid value at \"%s\"", in); - return -1; + f *= fr_time_multiplier_by_res[res]; + f /= NSEC; + + delta = fr_time_delta_from_integer(&overflow, integer, res); + if (overflow) { + overflow: + fr_strerror_printf("time_delta would %s", negative ? "underflow" : "overflow"); + fr_sbuff_set_to_start(&our_in); + return fr_sbuff_error(&our_in); } - if ((p[0] == 'm') && !p[1]) { - *out = fr_time_delta_from_sec(sec * 60); - return 0; - } + { + int64_t tmp; - if ((p[0] == 'h') && !p[1]) { - *out = fr_time_delta_from_sec(sec * 3600); - return 0; - } + /* + * Add fractional and integral parts checking for overflow + */ + if (!fr_add(&tmp, fr_time_delta_unwrap(delta), f)) goto overflow; - if ((p[0] == 'd') && !p[1]) { - *out = fr_time_delta_from_sec(sec * 86400); - return 0; + /* + * Flip the sign back to negative + */ + if (negative) tmp = -(tmp); + + *out = fr_time_delta_wrap(tmp); } - error: - fr_strerror_printf("Invalid time qualifier at \"%s\"", p); - return -1; + return fr_sbuff_set(in, &our_in); + /* + * It's timestamp format + * + * [hours:]minutes:seconds + */ + } else if (fr_sbuff_next_if_char(&our_in, ':')) { + uint64_t hours, minutes, seconds; + fr_sbuff_marker_t m1; + + res = FR_TIME_RES_SEC; + + fr_sbuff_marker(&m1, &our_in); - } else if (*next == ':') { + if (fr_sbuff_out(&sberr, &seconds, &our_in) < 0) goto num_error; + + /* + * minutes:seconds + */ + if (!fr_sbuff_next_if_char(&our_in, ':')) { + hours = 0; + minutes = negative ? -(integer) : integer; + + if (minutes > UINT16_MAX) { + fr_strerror_printf("minutes component of time_delta is too large"); + fr_sbuff_set_to_start(&our_in); + return fr_sbuff_error(&our_in); + } /* - * 00:01 is at least minutes, potentially hours + * hours:minutes:seconds */ - int minutes = sec; + } else { + hours = negative ? -(integer) : integer; + minutes = seconds; - p = next + 1; - errno = 0; /* Must be reset */ - sec = strtoul(p, &next, 10); - if (p == next) goto failed; + if (fr_sbuff_out(&sberr, &seconds, &our_in) < 0) goto num_error; - if (*next) goto failed; + if (hours > UINT16_MAX) { + fr_strerror_printf("hours component of time_delta is too large"); + fr_sbuff_set_to_start(&our_in); + return fr_sbuff_error(&our_in); + } - if (((errno = ERANGE) && ((unsigned long)sec == ULONG_MAX)) || (sec > 60)) { /* ERANGE is for wrap detection */ - fr_strerror_printf("Too many seconds in \"%s\"", in); - return -1; + if (minutes > UINT16_MAX) { + fr_strerror_printf("minutes component of time_delta is too large"); + return fr_sbuff_error(&m1); + } } - if (minutes > 60) { - fr_strerror_printf("Too many minutes in \"%s\"", in); - return -1; - } + if (no_trailing && !fr_sbuff_is_terminal(&our_in, tt)) goto trailing_data; /* - * @todo - support hours, maybe. Even though - * pretty much nothing needs them right now. + * Add all the components together... */ - if (*next) goto failed; - - if (negative) { - *out = fr_time_delta_from_sec(((int64_t)minutes * 60) - sec); - } else { - *out = fr_time_delta_from_sec(((int64_t)minutes * 60) + sec); - } - return 0; - - } else if (*next) { - p = next; - goto error; + if (!fr_add(&integer, ((hours * 60) * 60) + (minutes * 60), seconds)) goto overflow; - } else { - do_scale: - switch (hint) { - case FR_TIME_RES_SEC: - scale = NSEC; - break; - - case FR_TIME_RES_MSEC: - scale = 1000000; - break; - - case FR_TIME_RES_USEC: - scale = 1000; - break; - - case FR_TIME_RES_NSEC: - scale = 1; - break; - - default: - fr_strerror_printf("Invalid hint %d for time delta", hint); - return -1; - } - } + /* + * Flip the sign back to negative + */ + if (negative) integer = -(integer); -done: + *out = fr_time_delta_from_sec(integer); + return fr_sbuff_set(in, &our_in); /* - * Subseconds was parsed as if it was nanoseconds. But - * instead it may be something else, so it should be - * truncated. + * Nothing fancy here it's just a time delta as an integer * - * Note that this operation can't overflow. + * [] */ - subsec *= scale; - subsec /= NSEC; + } else { + if (no_trailing && !fr_sbuff_is_terminal(&our_in, tt)) goto trailing_data; - /* - * Now sec && subsec are in the same scale. - */ - if (negative) { - if (sec <= (INT64_MIN / scale)) { - fr_strerror_const("Integer underflow in time_delta value."); - return -1; - } + /* Scale defaults to hint */ + if (res == FR_TIME_RES_INVALID) res = hint; - sec *= scale; - sec -= subsec; - } else { - if (sec >= (INT64_MAX / scale)) { - fr_strerror_const("Integer overflow in time_delta value."); - return -1; - } + /* Do the scale conversion */ + *out = fr_time_delta_from_integer(&overflow, integer, res); + if (overflow) goto overflow; - sec *= scale; - sec += subsec; + return fr_sbuff_set(in, &our_in); } +} - *out = fr_time_delta_wrap(sec); +/** Create fr_time_delta_t from a string + * + * @param[out] out Where to write fr_time_delta_t + * @param[in] in String to parse. + * @param[in] inlen Length of string. + * @param[in] hint scale for the parsing. Default is "seconds" + * @return + * - 0 on success. + * - -1 on failure. + */ +fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t inlen, fr_time_res_t hint) +{ + fr_slen_t slen; - return 0; + slen = fr_time_delta_from_substr(out, &FR_SBUFF_IN(in, inlen), hint, true, NULL); + if (slen < 0) return slen; + if (slen != (fr_slen_t)inlen) { + fr_strerror_const("trailing data after time_delta"); /* Shouldn't happen with no_trailing */ + return -(inlen + 1); + } + return slen; } DIAG_OFF(format-nonliteral) diff --git a/src/lib/util/time.h b/src/lib/util/time.h index f187ca84bd6..548962eeec6 100644 --- a/src/lib/util/time.h +++ b/src/lib/util/time.h @@ -965,7 +965,10 @@ int fr_time_sync(void); int64_t fr_time_scale(int64_t t, fr_time_res_t hint); int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta) CC_HINT(nonnull); -int fr_time_delta_from_str(fr_time_delta_t *out, char const *in, fr_time_res_t hint) CC_HINT(nonnull); + +fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, + bool no_trailing, fr_sbuff_term_t const *tt) CC_HINT(nonnull(1,2)); +fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t inlen, fr_time_res_t hint) CC_HINT(nonnull); size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt) CC_HINT(format(strftime, 3, 0)); size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt) CC_HINT(format(strftime, 3, 0)); diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 9fda0b37d8f..e7b2f8bd987 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -4342,6 +4342,7 @@ ssize_t fr_value_box_from_substr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_sbuff_t our_in = FR_SBUFF(in); ssize_t ret; char buffer[256]; + fr_slen_t slen; if (!fr_cond_assert(dst_type != FR_TYPE_NULL)) return -1; @@ -4573,9 +4574,6 @@ parse: return fr_value_box_from_numeric_substr(dst, dst_type, dst_enumv, in, tainted); case FR_TYPE_BOOL: - { - fr_slen_t slen; - fr_value_box_init(dst, dst_type, dst_enumv, tainted); /* @@ -4609,7 +4607,6 @@ parse: "\"yes\", \"no\", \"true\", \"false\" or any unquoted integer"); return slen; /* Just whatever the last error offset was */ - } case FR_TYPE_ETHERNET: { @@ -4680,6 +4677,15 @@ parse: return fr_sbuff_set(in, &our_in); } + case FR_TYPE_TIME_DELTA: + fr_value_box_init(dst, FR_TYPE_TIME_DELTA, dst_enumv, tainted); + + slen = fr_time_delta_from_substr(&dst->datum.time_delta, &our_in, + dst_enumv ? dst_enumv->flags.flag_time_res : FR_TIME_RES_SEC, + false, rules->terminals); + if (slen < 0) return slen; + return fr_sbuff_set(in, &our_in); + case FR_TYPE_NULL: if (!rules->escapes && fr_sbuff_adv_past_str_literal(in, "NULL")) { fr_value_box_init(dst, dst_type, dst_enumv, tainted); @@ -4715,14 +4721,6 @@ parse: if (fr_size_from_str(&dst->datum.size, buffer) < 0) return -1; break; - case FR_TYPE_TIME_DELTA: - if (dst_enumv) { - if (fr_time_delta_from_str(&dst->datum.time_delta, buffer, dst_enumv->flags.flag_time_res) < 0) return -1; - } else { - if (fr_time_delta_from_str(&dst->datum.time_delta, buffer, FR_TIME_RES_SEC) < 0) return -1; - } - break; - case FR_TYPE_DATE: { if (dst_enumv) { diff --git a/src/modules/proto_ldap_sync/sync_touch.c b/src/modules/proto_ldap_sync/sync_touch.c index e7663db383b..70dfe2d255b 100644 --- a/src/modules/proto_ldap_sync/sync_touch.c +++ b/src/modules/proto_ldap_sync/sync_touch.c @@ -100,7 +100,7 @@ int main(int argc, char **argv) break; case 't': - if (fr_time_delta_from_str(&conf->timeout, optarg, FR_TIME_RES_SEC) < 0) { + if (fr_time_delta_from_str(&conf->timeout, optarg, strlen(optarg), FR_TIME_RES_SEC) < 0) { PERROR("Failed parsing timeout value"); fr_exit_now(EXIT_FAILURE); } diff --git a/src/tests/unit/data_types.txt b/src/tests/unit/data_types.txt index b9b54089412..7de28cbd30b 100644 --- a/src/tests/unit/data_types.txt +++ b/src/tests/unit/data_types.txt @@ -38,9 +38,18 @@ match 0.000000001 value time_delta 1:30 match 90 +value time_delta 1:1:30 +match 3690 + +value time_delta 01:01:30 +match 3690 + value time_delta 1h match 3600 +value time_delta 1d +match 86400 + # # And negative numbers # @@ -68,10 +77,17 @@ match -0.000000001 value time_delta -1:30 match -90 +value time_delta -1:1:30 +match -3690 + +value time_delta -01:01:30 +match -3690 + value time_delta -1h match -3600 - +value time_delta -1d +match -86400 # # uint8 @@ -215,4 +231,4 @@ encode-dns-label www_foo.com match Invalid character 0x5f in label count -match 104 +match 116