From: Arran Cudbard-Bell Date: Thu, 17 Dec 2020 16:48:08 +0000 (-0600) Subject: Add terminal chars to adv_past_whitespace X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcb0a50b3f590cf1dbf83c1c7efc96a3d9320a05;p=thirdparty%2Ffreeradius-server.git Add terminal chars to adv_past_whitespace --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index f7d6a59d8b7..53cc64ba841 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -2165,7 +2165,7 @@ static size_t command_tmpl_rules(command_result_t *result, command_file_ctx_t *c static size_t tmpl_rule_func_table_len = NUM_ELEMENTS(tmpl_rule_func_table); while (fr_sbuff_extend(&sbuff)) { - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); fr_sbuff_out_by_longest_prefix(&slen, &func, tmpl_rule_func_table, &sbuff, NULL); if (func == NULL) { @@ -2174,7 +2174,7 @@ static size_t command_tmpl_rules(command_result_t *result, command_file_ctx_t *c RETURN_COMMAND_ERROR(); } - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); if (!fr_sbuff_next_if_char(&sbuff, '=')) { fr_strerror_printf("Expected '=' after rule identifier, got \"%pV\"", @@ -2182,7 +2182,7 @@ static size_t command_tmpl_rules(command_result_t *result, command_file_ctx_t *c RETURN_COMMAND_ERROR(); } - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); if (func(&cc->tmpl_rules, &sbuff) <= 0) RETURN_COMMAND_ERROR(); } @@ -2884,7 +2884,7 @@ static int line_ranges_parse(TALLOC_CTX *ctx, fr_dlist_head_t *out, fr_sbuff_t * fr_sbuff_parse_error_t err; while (fr_sbuff_extend(in)) { - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); MEM(lr = talloc_zero(ctx, command_line_range_t)); fr_dlist_insert_tail(out, lr); @@ -2903,7 +2903,7 @@ static int line_ranges_parse(TALLOC_CTX *ctx, fr_dlist_head_t *out, fr_sbuff_t * max = lr->start; } lr->end = lr->start; /* Default to a single line */ - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); again: if (!fr_sbuff_extend(in)) break; @@ -2919,7 +2919,7 @@ static int line_ranges_parse(TALLOC_CTX *ctx, fr_dlist_head_t *out, fr_sbuff_t * */ case ',': fr_sbuff_next(in); - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); continue; /* @@ -2928,7 +2928,7 @@ static int line_ranges_parse(TALLOC_CTX *ctx, fr_dlist_head_t *out, fr_sbuff_t * case '-': { fr_sbuff_next(in); - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); /* * A bare '-' with no number means @@ -2954,7 +2954,7 @@ static int line_ranges_parse(TALLOC_CTX *ctx, fr_dlist_head_t *out, fr_sbuff_t * } else { max = lr->end; } - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); } goto again; } diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index 52573105ec2..1426d4b2129 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -238,7 +238,7 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM talloc_free(text); goto error; } - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); } else if (attribute) { cf_log_err(cp, "Invalid quoting. Unquoted attribute reference is required"); goto error; diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 0794a81e25d..9beee2cbf47 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -1116,7 +1116,7 @@ static ssize_t cond_tokenize_operand(TALLOC_CTX *ctx, tmpl_t **out, slen = tmpl_cast_from_substr(&cast, &our_in); if (slen < 0) return slen; - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); fr_sbuff_marker(&m, &our_in); /* @@ -1253,7 +1253,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, MEM(c = talloc_zero(ctx, fr_cond_t)); - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); if (!fr_sbuff_extend(&our_in)) { fr_strerror_const("Empty condition is invalid"); error: @@ -1266,7 +1266,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, */ if (fr_sbuff_next_if_char(&our_in, '!')) { c->negate = true; - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); /* * Just for stupidity @@ -1300,7 +1300,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, goto error; } - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); goto closing_brace; } @@ -1332,7 +1332,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, /* * We may (or not) have an operator */ - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); /* * What's found directly after the LHS token determines @@ -1433,7 +1433,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, fr_strerror_const("Invalid operator"); goto error; } - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); { map_t *map; @@ -1515,7 +1515,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, goto error; } - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); /* * Check cast type. We can have the RHS @@ -1548,7 +1548,7 @@ closing_brace: goto error; } fr_sbuff_advance(&our_in, 1); - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); goto done; } diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index be8aac6228c..8fb29927a1b 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -2767,7 +2767,7 @@ ssize_t tmpl_cast_from_substr(fr_type_t *out, fr_sbuff_t *in) fr_strerror_const("Unterminated cast"); FR_SBUFF_ERROR_RETURN(&our_in); } - fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); } if (out) *out = cast; diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 1a56805b34d..273b1ef592d 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -1288,7 +1288,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *fla * don't want them to become a whitespace * literal. */ - fr_sbuff_adv_past_whitespace(in, SIZE_MAX); + fr_sbuff_adv_past_whitespace(in, SIZE_MAX, NULL); fr_sbuff_marker(&m, &our_in); fr_cursor_init(&cursor, head); @@ -1390,7 +1390,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *fla * then error. */ fr_sbuff_set(&m, &our_in); - len = fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX); + len = fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); /* * Check to see if we have a terminal char diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 8b557765fa9..6673403f1f6 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -431,13 +431,14 @@ static inline CC_HINT(always_inline) void fr_sbuff_terminal_idx_init(size_t *nee * @param[in] idx Fastpath index, populated by * fr_sbuff_terminal_idx_init. * @param[in] term terminals to search in. + * @param[in] needle_len Length of the longest needle. * @return * - true if found. * - false if not. */ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p, uint8_t idx[static UINT8_MAX + 1], - fr_sbuff_term_t const *term) + fr_sbuff_term_t const *term, size_t needle_len) { uint8_t term_idx; @@ -457,7 +458,7 @@ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p, /* * Special case for EOFlike states */ - remaining = fr_sbuff_extend_lowat(&status, in, 1); + remaining = fr_sbuff_extend_lowat(&status, in, needle_len); if (remaining == 0) { if (status & FR_SBUFF_EXTEND_ERROR) return false; return (idx['\0'] != 0); @@ -754,14 +755,14 @@ size_t fr_sbuff_out_bstrncpy_until(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, end = CONSTRAINED_END(&our_in, len, fr_sbuff_used_total(&our_in)); if (escape_chr == '\0') { - while ((p < end) && !fr_sbuff_terminal_search(in, p, idx, tt)) p++; + while ((p < end) && !fr_sbuff_terminal_search(in, p, idx, tt, needle_len)) p++; } else { while (p < end) { if (do_escape) { do_escape = false; } else if (*p == escape_chr) { do_escape = true; - } else if (fr_sbuff_terminal_search(in, p, idx, tt)) { + } else if (fr_sbuff_terminal_search(in, p, idx, tt, needle_len)) { break; } p++; @@ -947,7 +948,7 @@ size_t fr_sbuff_out_unescape_until(fr_sbuff_t *out, fr_sbuff_t *in, size_t len, } next: - if (tt && fr_sbuff_terminal_search(in, fr_sbuff_current(&our_in), idx, tt)) break; + if (tt && fr_sbuff_terminal_search(in, fr_sbuff_current(&our_in), idx, tt, needle_len)) break; fr_sbuff_advance(&our_in, 1); }; @@ -1605,15 +1606,20 @@ size_t fr_sbuff_adv_past_strcase(fr_sbuff_t *sbuff, char const *needle, size_t n * * @param[in] sbuff sbuff to search in. * @param[in] len Maximum amount to advance by. Unconstrained if SIZE_MAX. + * @param[in] tt If not NULL, stop if we find a terminal sequence. * @return how many bytes we advanced. */ -size_t fr_sbuff_adv_past_whitespace(fr_sbuff_t *sbuff, size_t len) +size_t fr_sbuff_adv_past_whitespace(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt) { size_t total = 0; char const *p; + uint8_t idx[UINT8_MAX + 1]; /* Fast path index */ + size_t needle_len = 0; CHECK_SBUFF_INIT(sbuff); + if (tt) fr_sbuff_terminal_idx_init(&needle_len, idx, tt); + while (total < len) { char *end; @@ -1621,7 +1627,8 @@ size_t fr_sbuff_adv_past_whitespace(fr_sbuff_t *sbuff, size_t len) end = CONSTRAINED_END(sbuff, len, total); p = sbuff->p; - while ((p < end) && isspace(*p)) p++; + while ((p < end) && isspace(*p) && + ((needle_len == 0) || !fr_sbuff_terminal_search(sbuff, p, idx, tt, needle_len))) p++; total += fr_sbuff_set(sbuff, p); if (p != end) break; /* stopped early, break */ @@ -1695,14 +1702,14 @@ size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const * p = sbuff->p; if (escape_chr == '\0') { - while ((p < end) && !fr_sbuff_terminal_search(sbuff, p, idx, tt)) p++; + while ((p < end) && !fr_sbuff_terminal_search(sbuff, p, idx, tt, needle_len)) p++; } else { while (p < end) { if (do_escape) { do_escape = false; } else if (*p == escape_chr) { do_escape = true; - } else if (fr_sbuff_terminal_search(sbuff, p, idx, tt)) { + } else if (fr_sbuff_terminal_search(sbuff, p, idx, tt, needle_len)) { break; } p++; @@ -1964,5 +1971,5 @@ bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt) */ fr_sbuff_terminal_idx_init(&needle_len, idx, tt); - return fr_sbuff_terminal_search(in, in->p, idx, tt); + return fr_sbuff_terminal_search(in, in->p, idx, tt, needle_len); } diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index 9748fa443b2..0fd78b76b89 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -1396,7 +1396,7 @@ size_t fr_sbuff_adv_past_strcase(fr_sbuff_t *sbuff, char const *needle, size_t n #define fr_sbuff_adv_past_strcase_literal(_sbuff, _needle) fr_sbuff_adv_past_strcase(_sbuff, _needle, sizeof(_needle) - 1) -size_t fr_sbuff_adv_past_whitespace(fr_sbuff_t *sbuff, size_t len); +size_t fr_sbuff_adv_past_whitespace(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt); size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool const allowed[static UINT8_MAX + 1]); diff --git a/src/lib/util/sbuff_tests.c b/src/lib/util/sbuff_tests.c index 6a42c2d86b5..02d9b59faaf 100644 --- a/src/lib/util/sbuff_tests.c +++ b/src/lib/util/sbuff_tests.c @@ -947,7 +947,7 @@ static void test_file_extend(void) TEST_CHECK(fr_sbuff_init_file(&sbuff, &fctx, buff, sizeof(buff), fp, 128) == &sbuff); TEST_CASE("Advance past whitespace, which will require shift/extend"); - TEST_CHECK_LEN(sizeof(fbuff) - 6, fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX)); + TEST_CHECK_LEN(sizeof(fbuff) - 6, fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL)); TEST_CASE("Verify that we passed all and only whitespace"); (void) fr_sbuff_out_abstrncpy(NULL, &post_ws, &sbuff, 24); TEST_CHECK_STRCMP(post_ws, "xyzzy"); @@ -1026,30 +1026,30 @@ static void test_adv_past_whitespace(void) TEST_CASE("Check for token at beginning of string"); fr_sbuff_init(&sbuff, in, sizeof(in)); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX), 5); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL), 5); TEST_CHECK_STRCMP(sbuff.p, "i am a test string"); TEST_CASE("Check for token not at beginning of string"); fr_sbuff_init(&sbuff, in_ns, sizeof(in_ns)); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX), 0); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL), 0); TEST_CHECK_STRCMP(sbuff.p, "i am a test string"); TEST_CASE("Check for token with zero length string"); fr_sbuff_init(&sbuff, in, 0 + 1); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX), 0); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL), 0); TEST_CASE("Check for token that is the string"); fr_sbuff_init(&sbuff, in_ws, sizeof(in_ws)); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX), 5); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL), 5); TEST_CASE("Length constraint with token match"); fr_sbuff_init(&sbuff, in, sizeof(in)); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, 2), 2); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, 2, NULL), 2); TEST_CHECK_STRCMP(sbuff.p, " i am a test string"); TEST_CASE("Length constraint without token match"); fr_sbuff_init(&sbuff, in_ns, sizeof(in_ns)); - TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, 2), 0); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&sbuff, 2, NULL), 0); TEST_CHECK_STRCMP(sbuff.p, "i am a test string"); } diff --git a/src/modules/rlm_json/rlm_json.c b/src/modules/rlm_json/rlm_json.c index 60367b8d669..293f92de128 100644 --- a/src/modules/rlm_json/rlm_json.c +++ b/src/modules/rlm_json/rlm_json.c @@ -211,7 +211,7 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request } sbuff = FR_SBUFF_IN((*in)->vb_strvalue, (*in)->vb_length); - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); /* * Iterate through the list of attribute templates in the xlat. For each @@ -273,7 +273,7 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, request TALLOC_FREE(vpt); /* Jump forward to next attr */ - fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX); + fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); } /*