]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add terminal chars to adv_past_whitespace
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 17 Dec 2020 16:48:08 +0000 (10:48 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 17 Dec 2020 16:48:12 +0000 (10:48 -0600)
src/bin/unit_test_attribute.c
src/lib/server/cf_parse.c
src/lib/server/cond_tokenize.c
src/lib/server/tmpl_tokenize.c
src/lib/unlang/xlat_tokenize.c
src/lib/util/sbuff.c
src/lib/util/sbuff.h
src/lib/util/sbuff_tests.c
src/modules/rlm_json/rlm_json.c

index f7d6a59d8b72269d50e9f7d143017e2dd8285ac0..53cc64ba841dc5d899bac84164687ad879e26a17 100644 (file)
@@ -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;
                }
index 52573105ec2aa301671e4cc30f0b1199a0696e79..1426d4b212987b5d8eedb891abaa98b556be7351 100644 (file)
@@ -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;
index 0794a81e25d0f43ff3c8bf4b614ca876fc2e979a..9beee2cbf47c09abc974a399f9f910fabc1756b6 100644 (file)
@@ -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;
        }
 
index be8aac6228cb4a074ece14193417db886fb1cf1d..8fb29927a1b8a1ea341c755664ae67f18bbc5d8b 100644 (file)
@@ -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;
 
index 1a56805b34d253849630e89b872e914efa7b83ab..273b1ef592dfa4de57d97182557fbdc3cd49a51f 100644 (file)
@@ -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
index 8b557765fa9483fe5f546ea0618397419c1a2336..6673403f1f63f41ce2985d1229a327385709c72f 100644 (file)
@@ -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);
 }
index 9748fa443b2e413e358c2350e43fad8331f31ccb..0fd78b76b893c67eaff0985143f2f2ed5a4101b6 100644 (file)
@@ -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]);
 
index 6a42c2d86b52c83bb5fa0f6f8bee91f7b687b767..02d9b59faafc53655dae422614d704c4660150e3 100644 (file)
@@ -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");
 }
 
index 60367b8d6699e4c7716f14723b956cec24d80d9b..293f92de12897e87701306ee27216c0b7d51c2e2 100644 (file)
@@ -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);
        }
 
        /*