#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>
fr_pair_list_log(&default_log, 2, list);
}
-
/*
* Read a file compose of xlat's and expected results
*/
{
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.
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;
}
/*
* 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 = {
);
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;
}
/*
* 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;
}