Skip to content

Commit e066324

Browse files
committed
clean up use of safe_for
remove explicit safe_for argument from xlat_tokenize(). It is already being passed in the tmpl_rules_t. Passing a separate and explicit 0 breaks all kinds of things. e.g.. "..." gets marked correctly, but %{"..."} does not. require xlat_tokenize() to be passed a tmpl_rules_t. update trigger code to allow the use of attributes from the local dictionary. Which is usually internal, but should arguably also be allowed to be a protocol dictionary. So that we can send protocol-specfic triggers add commented out function to double-check safe_for after parsing. update callers of xlat_tokenize() to create a local tmpl_rules_t, and pass the correct safe_for
1 parent d63436f commit e066324

File tree

9 files changed

+80
-47
lines changed

9 files changed

+80
-47
lines changed

src/bin/unit_test_attribute.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,8 +2864,7 @@ static size_t command_xlat_normalise(command_result_t *result, command_file_ctx_
28642864
.allow_unresolved = cc->tmpl_rules.attr.allow_unresolved
28652865
},
28662866
.xlat = cc->tmpl_rules.xlat,
2867-
},
2868-
0);
2867+
});
28692868
if (dec_len <= 0) {
28702869
fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len);
28712870

src/bin/unit_test_module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ static bool do_xlats(fr_event_list_t *el, request_t *request, char const *filena
486486
};
487487

488488

489-
slen = xlat_tokenize(xlat_ctx, &head, &line, &p_rules, &t_rules, 0);
489+
slen = xlat_tokenize(xlat_ctx, &head, &line, &p_rules, &t_rules);
490490
if (slen <= 0) {
491491
talloc_free(xlat_ctx);
492492
fr_sbuff_in_sprintf(&out, "ERROR offset %d '%s'", (int) -slen, fr_strerror());

src/lib/server/cf_parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ int cf_section_parse_pass2(void *base, CONF_SECTION *cs)
14021402
.allow_unresolved = false,
14031403
.allow_foreign = (dict == NULL)
14041404
},
1405-
}, 0);
1405+
});
14061406
if (slen < 0) {
14071407
char *spaces, *text;
14081408

src/lib/server/tmpl_tokenize.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,7 +3262,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
32623262
xlat_exp_head_t *head = NULL;
32633263

32643264
vpt = tmpl_alloc_null(ctx);
3265-
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules, t_rules->literals_safe_for);
3265+
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
32663266
if (slen <= 0) FR_SBUFF_ERROR_RETURN(&our_in);
32673267

32683268
if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
@@ -3471,7 +3471,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
34713471

34723472
vpt = tmpl_alloc_null(ctx);
34733473

3474-
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules, t_rules->literals_safe_for);
3474+
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules);
34753475
if (slen < 0) FR_SBUFF_ERROR_RETURN(&our_in);
34763476

34773477
/*
@@ -3555,6 +3555,9 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
35553555
{
35563556
xlat_exp_head_t *head = NULL;
35573557
tmpl_type_t type = TMPL_TYPE_REGEX_XLAT;
3558+
tmpl_rules_t arg_t_rules = *t_rules;
3559+
3560+
arg_t_rules.literals_safe_for = FR_REGEX_SAFE_FOR;
35583561

35593562
if (!fr_type_is_null(t_rules->cast)) {
35603563
fr_strerror_const("Casts cannot be used with regular expressions");
@@ -3564,7 +3567,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
35643567

35653568
vpt = tmpl_alloc_null(ctx);
35663569

3567-
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, t_rules, FR_REGEX_SAFE_FOR);
3570+
slen = xlat_tokenize(vpt, &head, &our_in, p_rules, &arg_t_rules);
35683571
if (slen < 0) FR_SBUFF_ERROR_RETURN(&our_in);
35693572

35703573
/*
@@ -4003,6 +4006,7 @@ int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv)
40034006
* i.e. TMPL_TYPE_DATA_UNRESOLVED != TMPL_TYPE_DATA(FR_TYPE_STRING)
40044007
*/
40054008
if (fr_value_box_cast_in_place(vpt, &vpt->data.literal, type, NULL) < 0) return -1;
4009+
// fr_value_box_mark_safe_for(&vpt->data.literal, vpt->rules.literals_safe_for); ??? is this necessary?
40064010

40074011
/*
40084012
* Strings get quoted, everything else is a bare

src/lib/server/trigger.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,17 @@ int trigger_exec(unlang_interpret_t *intp,
380380
MEM(trigger = talloc_zero(request, fr_trigger_t));
381381
fr_value_box_list_init(&trigger->args);
382382
trigger->command = talloc_strdup(trigger, value);
383-
trigger->timeout = fr_time_delta_from_sec(5); /* FIXME - Should be configurable? */
383+
trigger->timeout = fr_time_delta_from_sec(5); /* @todo - Should be configurable? */
384384

385385
slen = xlat_tokenize_argv(trigger, &trigger->xlat,
386386
&FR_SBUFF_IN(trigger->command, talloc_array_length(trigger->command) - 1),
387-
NULL, NULL, NULL, true);
387+
NULL, NULL, &(tmpl_rules_t) {
388+
.attr = {
389+
.dict_def = request->dict,
390+
.list_def = request_attr_request,
391+
.allow_unresolved = false,
392+
},
393+
}, true);
388394
if (slen <= 0) {
389395
char *spaces, *text;
390396

src/lib/unlang/xlat.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,12 +405,11 @@ fr_slen_t xlat_tokenize_condition(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sb
405405
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
406406

407407
fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in,
408-
xlat_t const *xlat,
409-
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, bool spaces);
408+
xlat_t const *xlat, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
409+
bool spaces) CC_HINT(nonnull(1,2,3,6));
410410

411411
fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in,
412-
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
413-
fr_value_box_safe_for_t literals_safe_for);
412+
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
414413

415414
fr_slen_t xlat_print(fr_sbuff_t *in, xlat_exp_head_t const *node, fr_sbuff_escape_rules_t const *e_rules);
416415

src/lib/unlang/xlat_eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ ssize_t _xlat_eval(TALLOC_CTX *ctx, char **out, size_t outlen, request_t *reques
15091509
.runtime_el = unlang_interpret_event_list(request),
15101510
},
15111511
.at_runtime = true,
1512-
}, 0);
1512+
});
15131513
if (len == 0) {
15141514
if (*out) {
15151515
**out = '\0';

src/lib/unlang/xlat_tokenize.c

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ static int xlat_validate_function_arg(xlat_arg_parser_t const *arg_p, xlat_exp_t
220220
fr_assert(tmpl_rules_cast(vpt) == FR_TYPE_NULL);
221221

222222
fr_value_box_steal(node, &node->data, tmpl_value(vpt));
223-
224223
talloc_free(vpt);
225224
xlat_exp_set_type(node, XLAT_BOX);
225+
fr_value_box_mark_safe_for(&node->data, arg_p->safe_for);
226226

227227
} else {
228228
fr_assert(!tmpl_is_data_unresolved(node->vpt));
@@ -310,7 +310,7 @@ fr_slen_t xlat_validate_function_args(xlat_exp_t *node)
310310
* - 0 if the string was parsed into a function.
311311
* - <0 on parse error.
312312
*/
313-
static int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_rules_t const *t_rules)
313+
static CC_HINT(nonnull) int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_rules_t const *t_rules)
314314
{
315315
char c;
316316
xlat_exp_t *node;
@@ -403,7 +403,7 @@ static int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tm
403403
*/
404404
node = xlat_exp_alloc(head, XLAT_FUNC, fr_sbuff_current(&m_s), fr_sbuff_behind(&m_s));
405405
if (!func) {
406-
if (!t_rules || !t_rules->attr.allow_unresolved|| t_rules->at_runtime) {
406+
if (!t_rules->attr.allow_unresolved|| t_rules->at_runtime) {
407407
fr_strerror_const("Unresolved expansion functions are not allowed here");
408408
fr_sbuff_set(in, &m_s); /* backtrack */
409409
fr_sbuff_marker_release(&m_s);
@@ -413,7 +413,7 @@ static int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tm
413413
node->flags.needs_resolving = true; /* Needs resolution during pass2 */
414414
} else {
415415
node->call.func = func;
416-
if (t_rules) node->call.dict = t_rules->attr.dict_def;
416+
node->call.dict = t_rules->attr.dict_def;
417417
node->flags = func->flags;
418418
node->flags.impure_func = !func->flags.pure;
419419
node->call.input_type = func->input_type;
@@ -824,15 +824,12 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, fr_sbuff_t *in,
824824
* @param[in] in sbuff to parse.
825825
* @param[in] p_rules that control parsing.
826826
* @param[in] t_rules that control attribute reference and xlat function parsing.
827-
* @param[in] safe_for mark up literal values as being pre-escaped. May be merged
828-
* with t_rules in future.
829827
* @return
830828
* - <0 on failure
831829
* - >=0 for number of bytes parsed
832830
*/
833-
static ssize_t xlat_tokenize_input(xlat_exp_head_t *head, fr_sbuff_t *in,
834-
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
835-
fr_value_box_safe_for_t safe_for)
831+
static CC_HINT(nonnull(1,2,4)) ssize_t xlat_tokenize_input(xlat_exp_head_t *head, fr_sbuff_t *in,
832+
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
836833
{
837834
xlat_exp_t *node = NULL;
838835
fr_slen_t slen;
@@ -883,7 +880,7 @@ static ssize_t xlat_tokenize_input(xlat_exp_head_t *head, fr_sbuff_t *in,
883880
do_value_box:
884881
xlat_exp_set_name_buffer_shallow(node, str);
885882
fr_value_box_strdup(node, &node->data, NULL, str, false);
886-
fr_value_box_mark_safe_for(&node->data, safe_for);
883+
fr_value_box_mark_safe_for(&node->data, t_rules->literals_safe_for);
887884
node->flags.constant = true;
888885
fr_assert(node->flags.pure);
889886

@@ -1348,6 +1345,35 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_head_t const *head, fr_sbuff_escape
13481345
return fr_sbuff_used_total(out) - at_in;
13491346
}
13501347

1348+
#if 0
1349+
static void xlat_safe_for(xlat_exp_head_t *head, fr_value_box_safe_for_t safe_for)
1350+
{
1351+
xlat_exp_foreach(head, node) {
1352+
switch (node->type) {
1353+
case XLAT_BOX:
1354+
if (node->data.safe_for != safe_for) {
1355+
ERROR("FAILED %lx %lx - %s", node->data.safe_for, safe_for, node->fmt);
1356+
}
1357+
fr_assert(node->data.safe_for == safe_for);
1358+
break;
1359+
1360+
case XLAT_GROUP:
1361+
xlat_safe_for(node->group, safe_for);
1362+
break;
1363+
1364+
case XLAT_TMPL:
1365+
if (!tmpl_is_xlat(node->vpt)) break;
1366+
1367+
xlat_safe_for(tmpl_xlat(node->vpt), safe_for);
1368+
break;
1369+
1370+
default:
1371+
break;
1372+
}
1373+
}
1374+
}
1375+
#endif
1376+
13511377

13521378
/** Tokenize an xlat expansion into a series of XLAT_TYPE_CHILD arguments
13531379
*
@@ -1378,8 +1404,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
13781404
fr_sbuff_parse_rules_t tmp_p_rules;
13791405
xlat_exp_head_t *head;
13801406
xlat_arg_parser_t const *arg = NULL, *arg_start;
1381-
tmpl_rules_t const *our_t_rules = t_rules;
1382-
tmpl_rules_t tmp_t_rules;
1407+
tmpl_rules_t arg_t_rules;
13831408

13841409
if (xlat && xlat->args) {
13851410
arg_start = arg = xlat->args; /* Track the arguments as we parse */
@@ -1388,6 +1413,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
13881413
XLAT_ARG_PARSER_TERMINATOR };
13891414
arg_start = arg = &default_arg[0];
13901415
}
1416+
arg_t_rules = *t_rules;
13911417

13921418
if (spaces) {
13931419
fr_assert(p_rules != &xlat_function_arg_rules);
@@ -1421,15 +1447,12 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
14211447
* expression to be just about anything.
14221448
*/
14231449
if (!xlat_func_bare_words) {
1424-
tmp_t_rules = *t_rules;
1425-
our_t_rules = &tmp_t_rules;
1426-
1427-
tmp_t_rules.enumv = NULL;
1428-
tmp_t_rules.cast = FR_TYPE_NULL;
1429-
tmp_t_rules.attr.namespace = NULL;
1430-
tmp_t_rules.attr.request_def = NULL;
1431-
tmp_t_rules.attr.list_def = request_attr_request;
1432-
tmp_t_rules.attr.list_presence = TMPL_ATTR_LIST_ALLOW;
1450+
arg_t_rules.enumv = NULL;
1451+
arg_t_rules.cast = FR_TYPE_NULL;
1452+
arg_t_rules.attr.namespace = NULL;
1453+
arg_t_rules.attr.request_def = NULL;
1454+
arg_t_rules.attr.list_def = request_attr_request;
1455+
arg_t_rules.attr.list_presence = TMPL_ATTR_LIST_ALLOW;
14331456
}
14341457
}
14351458

@@ -1449,6 +1472,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
14491472
size_t len;
14501473

14511474
fr_sbuff_set(&m, &our_in); /* Record start of argument */
1475+
arg_t_rules.literals_safe_for = arg->safe_for;
14521476

14531477
/*
14541478
* Whitespace isn't significant for comma-separated argvs
@@ -1497,7 +1521,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
14971521
*
14981522
* No spaces - each arugment is an expression, which can have embedded spaces.
14991523
*/
1500-
slen = xlat_tokenize_input(node->group, &our_in, our_p_rules, t_rules, arg->safe_for);
1524+
slen = xlat_tokenize_input(node->group, &our_in, our_p_rules, &arg_t_rules);
15011525

15021526
} else {
15031527
tokenize_expression:
@@ -1508,7 +1532,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
15081532
slen = 0;
15091533

15101534
} else {
1511-
slen = xlat_tokenize_expression(node, &node->group, &our_in, our_p_rules, our_t_rules);
1535+
slen = xlat_tokenize_expression(node, &node->group, &our_in, our_p_rules, &arg_t_rules);
15121536
}
15131537
}
15141538
if (slen < 0) {
@@ -1551,7 +1575,7 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
15511575
XLAT_DEBUG("ARGV double quotes <-- %.*s", (int) fr_sbuff_remaining(&our_in), fr_sbuff_current(&our_in));
15521576

15531577
if (xlat_tokenize_input(node->group, &our_in,
1554-
&value_parse_rules_double_quoted, t_rules, arg->safe_for) < 0) goto error;
1578+
&value_parse_rules_double_quoted, &arg_t_rules) < 0) goto error;
15551579
break;
15561580

15571581
/*
@@ -1600,6 +1624,13 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
16001624
fmt = talloc_bstrndup(node, fr_sbuff_current(&m), fr_sbuff_behind(&m));
16011625
xlat_exp_set_name_buffer_shallow(node, fmt);
16021626

1627+
/*
1628+
* Assert that the parser has created things which are safe for the current argument.
1629+
*
1630+
* @todo - function should be marked up with safe_for, and not each individual argument.
1631+
*/
1632+
// xlat_safe_for(node->group, arg->safe_for);
1633+
16031634
node->flags = node->group->flags;
16041635

16051636
xlat_exp_insert_tail(head, node);
@@ -1682,20 +1713,14 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
16821713
* @param[in] p_rules controlling how the string containing the xlat
16831714
* expansions should be parsed.
16841715
* @param[in] t_rules controlling how attribute references are parsed.
1685-
* Do NOT alter this function to take tmpl_rules_t
1686-
* as this provides another value for literals_safe_for
1687-
* and this gets very confusing.
1688-
* @param[in] literals_safe_for the safe_for value to assign to any literals occurring at the
1689-
* top level of the expansion.
16901716
* @return
16911717
* - >0 on success.
16921718
* - 0 and *head == NULL - Parse failure on first char.
16931719
* - 0 and *head != NULL - Zero length expansion
16941720
* - < 0 the negative offset of the parse failure.
16951721
*/
16961722
fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in,
1697-
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
1698-
fr_value_box_safe_for_t literals_safe_for)
1723+
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
16991724
{
17001725
fr_sbuff_t our_in = FR_SBUFF(in);
17011726
xlat_exp_head_t *head;
@@ -1704,7 +1729,7 @@ fr_slen_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in,
17041729
MEM(head = xlat_exp_head_alloc(ctx));
17051730
fr_strerror_clear(); /* Clear error buffer */
17061731

1707-
if (xlat_tokenize_input(head, &our_in, p_rules, t_rules, literals_safe_for) < 0) {
1732+
if (xlat_tokenize_input(head, &our_in, p_rules, t_rules) < 0) {
17081733
talloc_free(head);
17091734
FR_SBUFF_ERROR_RETURN(&our_in);
17101735
}

src/modules/rlm_sqlcounter/rlm_sqlcounter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ static int call_env_query_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *
463463
['%'] = '%',
464464
['\\'] = '\\',
465465
},
466-
}}, t_rules, 0) < 0) {
466+
}}, t_rules) < 0) {
467467
talloc_free(query);
468468
return -1;
469469
}

0 commit comments

Comments
 (0)