]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
unit_test_module: Escape output of xlat functions in tests
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 Jun 2023 18:56:55 +0000 (14:56 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 Jun 2023 18:58:34 +0000 (14:58 -0400)
src/bin/unit_test_module.c

index 9f577c094338464d54efc01ea60ea138e1eb157f..f6bd923e237f5ef90e9c56e34effb0b12dbe4914 100644 (file)
@@ -31,6 +31,7 @@ RCSID("$Id$")
 #include <freeradius-devel/util/debug.h>
 #include <freeradius-devel/util/rand.h>
 #include <freeradius-devel/util/value.h>
+#include <freeradius-devel//util/sbuff.h>
 #include <freeradius-devel/io/listen.h>
 
 #include <freeradius-devel/tls/base.h>
@@ -308,7 +309,6 @@ static void print_packet(FILE *fp, fr_radius_packet_t *packet, fr_pair_list_t *l
        fr_pair_list_log(&default_log, 2, list);
 }
 
-
 /*
  *     Read a file compose of xlat's and expected results
  */
@@ -316,10 +316,12 @@ static bool do_xlats(fr_event_list_t *el, char const *filename, FILE *fp)
 {
        int             lineno = 0;
        ssize_t         len;
-       char            *p;
-       char            input[8192];
-       char            output[8192];
+       char            line_buff[8192];
+       char            output_buff[8192];
+       char            unescaped[sizeof(output_buff)];
        request_t       *request;
+       fr_sbuff_t      line = FR_SBUFF_IN(line_buff, sizeof(line_buff));
+       fr_sbuff_t      out = FR_SBUFF_OUT(output_buff, sizeof(output_buff));
 
        /*
         *      Create and initialize the new request.
@@ -360,67 +362,65 @@ static bool do_xlats(fr_event_list_t *el, char const *filename, FILE *fp)
 
        request->master_state = REQUEST_ACTIVE;
        request->log.lvl = fr_debug_lvl;
-       output[0] = '\0';
-
        request->async = talloc_zero(request, fr_async_t);
 
-       while (fgets(input, sizeof(input), fp) != NULL) {
+       while (fgets(line_buff, sizeof(line_buff), fp) != NULL) {
                lineno++;
 
-               /*
-                *      Ignore blank lines and comments
-                */
-               p = input;
-               fr_skip_whitespace(p);
-
-               if (*p < ' ') continue;
-               if (*p == '#') continue;
-
-               p = strchr(p, '\n');
-               if (!p) {
+               fr_sbuff_set_to_start(&out);
+               fr_sbuff_set_to_start(&line);
+               if (!fr_sbuff_adv_to_chr(&line, SIZE_MAX, '\n')) {
                        if (!feof(fp)) {
-                               fprintf(stderr, "Line %d too long in %s\n",
-                                       lineno, filename);
+                               fprintf(stderr, "Line %d too long in %s\n", lineno, filename);
                                TALLOC_FREE(request);
                                return false;
                        }
                } else {
-                       *p = '\0';
+                       fr_sbuff_terminate(&line);
                }
 
+               /*
+                *      Ignore blank lines and comments
+                */
+               fr_sbuff_adv_past_whitespace(&line, SIZE_MAX, NULL);
+
+               if (*fr_sbuff_current(&line) < ' ') continue;
+               if (fr_sbuff_is_char(&line, '#')) continue;
+
                /*
                 *      Look for "xlat"
                 */
-               if (strncmp(input, "xlat ", 5) == 0) {
+               if (fr_sbuff_adv_past_str_literal(&line, "xlat ") > 0) {
                        ssize_t                 slen;
                        TALLOC_CTX              *xlat_ctx = talloc_init_const("xlat");
-                       char                    *fmt = talloc_typed_strdup(xlat_ctx, input + 5);
                        xlat_exp_head_t         *head = NULL;
                        fr_sbuff_parse_rules_t  p_rules = { .escapes = &fr_value_unescape_double };
 
-                       slen = xlat_tokenize_ephemeral(xlat_ctx, &head, el,
-                                                      &FR_SBUFF_IN(fmt, talloc_array_length(fmt) - 1), &p_rules, NULL);
+                       slen = xlat_tokenize_ephemeral(xlat_ctx, &head, el, &line, &p_rules, NULL);
                        if (slen <= 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR offset %d '%s'", (int) -slen,
-                                        fr_strerror());
+                               fr_sbuff_in_sprintf(&out, "ERROR offset %d '%s'", (int) -slen, fr_strerror());
                                continue;
                        }
 
-                       if (input[slen + 5] != '\0') {
+                       if (fr_sbuff_remaining(&line) > 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR offset %d 'Too much text' ::%s::",
-                                        (int) slen, input + slen + 5);
+                               fr_sbuff_in_sprintf(&out,  "ERROR offset %d 'Too much text' ::%s::", (int) slen, fr_sbuff_current(&line));
                                continue;
                        }
 
-                       len = xlat_eval_compiled(output, sizeof(output), request, head, NULL, NULL);
+                       len = xlat_eval_compiled(unescaped, sizeof(unescaped), request, head, NULL, NULL);
                        if (len < 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR expanding xlat: %s", fr_strerror());
+                               fr_sbuff_in_sprintf(&out, "ERROR expanding xlat: %s", fr_strerror());
                                continue;
                        }
 
+                       /*
+                        *      Escape the output as if it were a double quoted string.
+                        */
+                       fr_sbuff_in_escape(&out, unescaped, len, &fr_value_escape_double);
+
                        TALLOC_FREE(xlat_ctx); /* also frees 'head' */
                        continue;
                }
@@ -428,14 +428,13 @@ static bool do_xlats(fr_event_list_t *el, char const *filename, FILE *fp)
                /*
                 *      Look for "xlat_expr"
                 */
-               if (strncmp(input, "xlat_expr ", 10) == 0) {
+               if (fr_sbuff_adv_past_str_literal(&line, "xlat_expr ") > 0) {
                        ssize_t                 slen;
                        TALLOC_CTX              *xlat_ctx = talloc_init_const("xlat");
-                       char                    *fmt = talloc_typed_strdup(xlat_ctx, input + 10);
                        xlat_exp_head_t         *head = NULL;
 
                        slen = xlat_tokenize_ephemeral_expression(xlat_ctx, &head, el,
-                                                                 &FR_SBUFF_IN(fmt, talloc_array_length(fmt) - 1),
+                                                                 &line,
                                                                  NULL,
                                                                  &(tmpl_rules_t) {
                                                                          .attr = {
@@ -447,31 +446,34 @@ static bool do_xlats(fr_event_list_t *el, char const *filename, FILE *fp)
                                                                );
                        if (slen <= 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR offset %d '%s'", (int) -slen,
-                                        fr_strerror());
+                               fr_sbuff_in_sprintf(&out, "ERROR offset %d '%s'", (int) -slen, fr_strerror());
                                continue;
                        }
 
-                       if (input[slen + 10] != '\0') {
+                       if (fr_sbuff_remaining(&line) > 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR offset %d Unexpected text '%s' after parsing",
-                                        (int) slen, input + slen + 10);
+                               fr_sbuff_in_sprintf(&out, "ERROR offset %d 'Too much text' ::%s::", (int) slen, fr_sbuff_current(&line));
                                continue;
                        }
 
                        if (xlat_resolve(head, NULL) < 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR resolving xlat: %s", fr_strerror());
+                               fr_sbuff_in_sprintf(&out, "ERROR resolving xlat: %s", fr_strerror());
                                continue;
                        }
 
-                       len = xlat_eval_compiled(output, sizeof(output), request, head, NULL, NULL);
+                       len = xlat_eval_compiled(unescaped, sizeof(unescaped), request, head, NULL, NULL);
                        if (len < 0) {
                                talloc_free(xlat_ctx);
-                               snprintf(output, sizeof(output), "ERROR expanding xlat: %s", fr_strerror());
+                               fr_sbuff_in_sprintf(&out, "ERROR expanding xlat: %s", fr_strerror());
                                continue;
                        }
 
+                       /*
+                        *      Escape the output as if it were a double quoted string.
+                        */
+                       fr_sbuff_in_escape(&out, unescaped, len, &fr_value_escape_double);
+
                        TALLOC_FREE(xlat_ctx); /* also frees 'head' */
                        continue;
                }
@@ -479,10 +481,10 @@ static bool do_xlats(fr_event_list_t *el, char const *filename, FILE *fp)
                /*
                 *      Look for "match".
                 */
-               if (strncmp(input, "match ", 6) == 0) {
-                       if (strcmp(input + 6, output) != 0) {
+               if (fr_sbuff_adv_past_str_literal(&line, "match ") > 0) {
+                       if (fr_sbuff_adv_past_str(&line, output_buff, strlen(output_buff)) == 0) {
                                fprintf(stderr, "Mismatch at %s[%u]\n\tgot      : %s\n\texpected : %s\n",
-                                       filename, lineno,  output, input + 6);
+                                       filename, lineno,  output_buff, fr_sbuff_current(&line));
                                TALLOC_FREE(request);
                                return false;
                        }