From: Alan T. DeKok Date: Tue, 10 Sep 2019 20:13:50 +0000 (-0400) Subject: make fr_cond_tokenize() take CONF_SECTION we're parsing X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=abbee5969946e0ea3b7da3243b96b2369d52f1bf;p=thirdparty%2Ffreeradius-server.git make fr_cond_tokenize() take CONF_SECTION we're parsing which ends up being easier than the alternative. That way instead of passing a bunch of things around, we can just pass a CONF_SECTION --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 81eaa7c845e..304c9be1038 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -73,6 +73,8 @@ static ssize_t xlat_test(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED size_ static char proto_name_prev[128]; static dl_t *dl; static dl_loader_t *dl_loader; +static const char *process_filename; +static int process_lineno; /** Concatenate error stack */ @@ -539,31 +541,33 @@ static void parse_condition(fr_dict_t const *dict, char const *input, char *outp ssize_t dec_len; char const *error = NULL; fr_cond_t *cond; - CONF_SECTION *this; + CONF_SECTION *cs; - this = cf_section_alloc(NULL, NULL, "if", "condition"); - if (!this) { + cs = cf_section_alloc(NULL, NULL, "if", "condition"); + if (!cs) { snprintf(output, outlen, "ERROR out of memory"); return; } + cf_filename_set(cs, process_filename); + cf_lineno_set(cs, process_lineno); - dec_len = fr_cond_tokenize(NULL, &cond, &error, dict, this, input, NULL, 0); - talloc_free(this); + dec_len = fr_cond_tokenize(cs, &cond, &error, dict, input); if (dec_len <= 0) { + talloc_free(cs); snprintf(output, outlen, "ERROR offset %d %s", (int) -dec_len, error); return; } input += dec_len; if (*input != '\0') { - talloc_free(cond); + talloc_free(cs); snprintf(output, outlen, "ERROR offset %d 'Too much text'", (int) dec_len); return; } cond_snprint(output, outlen, cond); - talloc_free(cond); + talloc_free(cs); } static void parse_xlat(fr_dict_t const *dict, char const *input, char *output, size_t outlen) @@ -864,6 +868,7 @@ do { \ lineno = 0; *output = '\0'; data_len = 0; + process_filename = filename; while (fgets(buffer, sizeof(buffer), fp) != NULL) { char *p = strchr(buffer, '\n'), *q; @@ -894,6 +899,7 @@ do { \ fr_skip_whitespace(p); if (!*p) continue; + process_lineno = lineno; DEBUG2("%s[%d]: %s\n", filename, lineno, buffer); strlcpy(input, p, sizeof(input)); diff --git a/src/lib/server/cf_file.c b/src/lib/server/cf_file.c index d2febf88306..5650b0c64f6 100644 --- a/src/lib/server/cf_file.c +++ b/src/lib/server/cf_file.c @@ -1052,11 +1052,21 @@ static CONF_SECTION *process_if(CONF_SECTION *this, char const **ptr_p, char *bu cd = cf_data_find_in_parent(this, fr_dict_t **, "dictionary"); if (cd) dict = *((fr_dict_t **)cf_data_value(cd)); + /* + * fr_cond_tokenize needs the current section, so we create it first. + */ + css = cf_section_alloc(this, this, buff[1], buff[2]); + if (!css) { + ERROR("%s[%d]: Failed allocating memory for section", filename, *lineno); + return NULL; + } + css->item.filename = filename; + css->item.lineno = *lineno; + /* * Skip (...) to find the { */ - slen = fr_cond_tokenize(this, &cond, &error, dict, - this, ptr, filename, *lineno); + slen = fr_cond_tokenize(css, &cond, &error, dict, ptr); if (slen < 0) { char *spaces, *text; @@ -1069,7 +1079,7 @@ static CONF_SECTION *process_if(CONF_SECTION *this, char const **ptr_p, char *bu talloc_free(spaces); talloc_free(text); - talloc_free(cond); + talloc_free(css); return NULL; } @@ -1079,7 +1089,7 @@ static CONF_SECTION *process_if(CONF_SECTION *this, char const **ptr_p, char *bu * into. */ if ((size_t) slen >= (talloc_array_length(buff[2]) - 1)) { - talloc_free(cond); + talloc_free(css); ERROR("%s[%d]: Condition is too large after \"%s\"", filename, *lineno, buff[1]); return NULL; } @@ -1097,20 +1107,15 @@ static CONF_SECTION *process_if(CONF_SECTION *this, char const **ptr_p, char *bu if (*ptr != '{') { ERROR("%s[%d]: Expected '{' instead of %s", filename, *lineno, ptr); - talloc_free(cond); + talloc_free(css); return NULL; } ptr++; - css = cf_section_alloc(this, this, buff[1], buff[2]); - if (!css) { - ERROR("%s[%d]: Failed allocating memory for section", filename, *lineno); - talloc_free(cond); - return NULL; - } - css->item.filename = filename; - css->item.lineno = *lineno; - + /* + * Now that the CONF_SECTION and condition are OK, add + * the condition to the CONF_SECTION. + */ cf_data_add(css, cond, NULL, false); *ptr_p = ptr; return css; diff --git a/src/lib/server/cf_util.c b/src/lib/server/cf_util.c index 1626518a31f..21f44dc7f94 100644 --- a/src/lib/server/cf_util.c +++ b/src/lib/server/cf_util.c @@ -742,6 +742,8 @@ CONF_SECTION *_cf_section_alloc(TALLOC_CTX *ctx, CONF_SECTION *parent, cs->item.type = CONF_ITEM_SECTION; cs->item.parent = cf_section_to_item(parent); fr_cursor_init(&cs->item.cursor, &cs->item.child); + if (filename) cf_filename_set(cs, filename); + if (lineno) cf_lineno_set(cs, lineno); MEM(cs->name1 = talloc_typed_strdup(cs, name1)); if (name2) { @@ -750,9 +752,6 @@ CONF_SECTION *_cf_section_alloc(TALLOC_CTX *ctx, CONF_SECTION *parent, } talloc_set_destructor(cs, _cf_section_free); - if (filename) cf_filename_set(cs, filename); - if (lineno) cf_lineno_set(cs, lineno); - if (parent) { CONF_DATA const *cd; CONF_PARSER *rule; diff --git a/src/lib/server/cond.h b/src/lib/server/cond.h index 0f2293d1753..ac7060fc05a 100644 --- a/src/lib/server/cond.h +++ b/src/lib/server/cond.h @@ -89,10 +89,8 @@ struct fr_cond_t { fr_cond_t *next; }; -ssize_t fr_cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **head, char const **error, - fr_dict_t const *dict, - CONF_SECTION *parent, char const *start, - char const *filename, int lineno) CC_HINT(nonnull(1,2,3,4,5)); +ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, char const **error, + fr_dict_t const *dict, char const *start) CC_HINT(nonnull); size_t cond_snprint(char *buffer, size_t bufsize, fr_cond_t const *c); bool fr_cond_walk(fr_cond_t *head, bool (*callback)(fr_cond_t *cond, void *uctx), void *uctx); diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 3edfad0e90e..139dd6ea31e 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -575,10 +575,11 @@ static ssize_t cond_check_attrs(fr_cond_t *c, char const *start, static ssize_t cond_preparse(TALLOC_CTX *ctx, char const **out, size_t *outlen, char const *start, FR_TOKEN *type, char const **error, fr_dict_attr_t const **castda, bool require_regex, - CONF_SECTION *parent, char const *filename, int lineno) + CONF_SECTION *cs) { ssize_t slen, my_slen; char *p, *expanded; + int lineno; char buffer[8192]; /* @@ -596,7 +597,9 @@ static ssize_t cond_preparse(TALLOC_CTX *ctx, char const **out, size_t *outlen, return slen; } - if (!cf_expand_variables(filename, &lineno, parent, buffer, sizeof(buffer), start, slen, NULL)) { + lineno = cf_lineno(cs); + if (!cf_expand_variables(cf_filename(cs), &lineno, cf_item_to_section(cf_parent(cs)), + buffer, sizeof(buffer), start, slen, NULL)) { *error = "Failed expanding configuration variable"; return -1; } @@ -628,22 +631,21 @@ static ssize_t cond_preparse(TALLOC_CTX *ctx, char const **out, size_t *outlen, /** Tokenize a conditional check * - * @param[in] ctx for talloc + * @param[in] ctx talloc ctx + * @param[in] cs our configuration section * @param[out] pcond pointer to the returned condition structure * @param[out] error the parse error (if any) - * @param[in] parent the parent CONF_SECTION * @param[in] start the start of the string to process. Should be "(..." * @param[in] brace look for a closing brace (how many deep we are) * @param[in] rules for attribute parsing - * @param[in] filename filename we read the condition from - * @param[in] lineno line where we read the condition from * @return * - Length of the string skipped. * - < 0 (the offset to the offending error) on error. */ -static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **error, - CONF_SECTION *parent, char const *start, int brace, - vp_tmpl_rules_t const *rules, char const *filename, int lineno) +static ssize_t cond_tokenize(TALLOC_CTX *ctx, CONF_SECTION *cs, + fr_cond_t **pcond, char const **error, + char const *start, int brace, + vp_tmpl_rules_t const *rules) { ssize_t slen, tlen; char const *p = start; @@ -699,8 +701,8 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er * brackets. Go recurse to get more. */ c->type = COND_TYPE_CHILD; - c->ci = cf_section_to_item(parent); - slen = cond_tokenize(c, &c->data.child, error, parent, p, brace + 1, rules, filename, lineno); + c->ci = cf_section_to_item(cs); + slen = cond_tokenize(c, cs, &c->data.child, error, p, brace + 1, rules); if (slen <= 0) return_SLEN; if (!c->data.child) { @@ -722,7 +724,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er /* * Grab the LHS */ - slen = cond_preparse(c, &lhs, &lhs_len, p, &lhs_type, error, &c->cast, false, parent, filename, lineno); + slen = cond_preparse(c, &lhs, &lhs_len, p, &lhs_type, error, &c->cast, false, cs); if (slen <= 0) { return_SLEN; } @@ -786,7 +788,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er } c->type = COND_TYPE_EXISTS; - c->ci = cf_section_to_item(parent); + c->ci = cf_section_to_item(cs); tlen = tmpl_afrom_str(c, &c->data.vpt, lhs, lhs_len, lhs_type, &parse_rules, true); @@ -813,7 +815,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er * The next thing should now be a comparison operator. */ c->type = COND_TYPE_MAP; - c->ci = cf_section_to_item(parent); + c->ci = cf_section_to_item(cs); switch (*p) { default: @@ -902,7 +904,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er return_P("Expected text after operator"); } - slen = cond_preparse(c, &rhs, &rhs_len, p, &rhs_type, error, NULL, regex, parent, filename, lineno); + slen = cond_preparse(c, &rhs, &rhs_len, p, &rhs_type, error, NULL, regex, cs); if (slen <= 0) { return_SLEN; } @@ -1039,9 +1041,9 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **pcond, char const **er #endif /* - * Save the parent for later. + * Save the current config section for later. */ - c->data.map->ci = cf_section_to_item(parent); + c->data.map->ci = cf_section_to_item(cs); /* * We cannot compare lists to anything. @@ -1132,7 +1134,7 @@ closing_brace: /* * May still be looking for a closing brace. */ - slen = cond_tokenize(c, &c->next, error, parent, p, brace, rules, filename, lineno); + slen = cond_tokenize(c, cs, &c->next, error, p, brace, rules); if (slen <= 0) { return_slen: talloc_free(c); @@ -1575,26 +1577,20 @@ done: /** Tokenize a conditional check * - * @param[in] ctx for talloc + * @param[in] cs current CONF_SECTION and talloc ctx * @param[out] head the parsed condition structure * @param[out] error the parse error (if any) * @param[in] dict dictionary to resolve attributes in. - * @param[in] parent the parent CONF_SECTION * @param[in] start the start of the string to process. Should be "(..." - * @param[in] filename filename we read the condition from - * @param[in] lineno line where we read the condition from * @return * - Length of the string skipped. * - < 0 (the offset to the offending error) on error. */ -ssize_t fr_cond_tokenize(TALLOC_CTX *ctx, +ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, char const **error, - fr_dict_t const *dict, - CONF_SECTION *parent, char const *start, - char const *filename, int lineno) + fr_dict_t const *dict, char const *start) { - return cond_tokenize(ctx, head, error, parent, start, 0, &(vp_tmpl_rules_t){ .dict_def = dict }, - filename, lineno); + return cond_tokenize(cs, cs, head, error, start, 0, &(vp_tmpl_rules_t){ .dict_def = dict }); } /*