From: Arran Cudbard-Bell Date: Tue, 27 Jun 2023 18:56:55 +0000 (-0400) Subject: unit_test_module: Escape output of xlat functions in tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac66b93bab2d6210b7272643474d179c1ea8d66e;p=thirdparty%2Ffreeradius-server.git unit_test_module: Escape output of xlat functions in tests --- diff --git a/src/bin/unit_test_module.c b/src/bin/unit_test_module.c index 9f577c09433..f6bd923e237 100644 --- a/src/bin/unit_test_module.c +++ b/src/bin/unit_test_module.c @@ -31,6 +31,7 @@ RCSID("$Id$") #include #include #include +#include #include #include @@ -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; }