Skip to content

Commit 5d674c8

Browse files
committed
more fixes and assertion checks for tmpl_require_enum_prefix=false
1 parent 23feab5 commit 5d674c8

File tree

6 files changed

+116
-16
lines changed

6 files changed

+116
-16
lines changed

src/lib/server/map.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,10 @@ static int map_value_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_
11701170
* Don't bother trying things which we know aren't attributes.
11711171
*/
11721172
if ((t_rules->attr.prefix == TMPL_ATTR_REF_PREFIX_YES) && (*attr != '&')) {
1173+
extern bool tmpl_require_enum_prefix;
1174+
1175+
fr_assert(!tmpl_require_enum_prefix); /* @todo - fix this later */
1176+
11731177
slen = tmpl_afrom_substr(ctx, &map->lhs, &FR_SBUFF_IN(attr, talloc_array_length(attr) - 1), T_BARE_WORD, NULL, t_rules);
11741178
if (slen <= 0) goto marker;
11751179
break;
@@ -2651,7 +2655,7 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *
26512655
/*
26522656
* No enums here.
26532657
*/
2654-
fr_assert(my_rules.attr.prefix == TMPL_ATTR_REF_PREFIX_YES);
2658+
fr_assert(my_rules.attr.prefix != TMPL_ATTR_REF_PREFIX_NO);
26552659
fr_assert(my_rules.attr.list_def == request_attr_request);
26562660

26572661
my_rules.enumv = NULL;

src/lib/server/tmpl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ typedef struct tmpl_s tmpl_t;
264264
typedef enum {
265265
TMPL_ATTR_REF_PREFIX_YES = 0, //!< Attribute refs must have '&' prefix.
266266
TMPL_ATTR_REF_PREFIX_NO, //!< Attribute refs have no '&' prefix.
267-
TMPL_ATTR_REF_PREFIX_AUTO //!< Attribute refs may have a '&' prefix.
267+
TMPL_ATTR_REF_PREFIX_AUTO //!< Attribute refs may have a '&' prefix.
268268
} tmpl_attr_prefix_t;
269269

270270
/** Specify whether attribute references can have a list (or parent) reference
@@ -327,6 +327,8 @@ struct tmpl_attr_rules_s {
327327
uint8_t allow_foreign:1; //!< Allow arguments not found in dict_def.
328328

329329
uint8_t disallow_filters:1; //!< disallow filters.
330+
331+
uint8_t xlat:1 ; //!< for %{User-Name}
330332
};
331333

332334
struct tmpl_xlat_rules_s {

src/lib/server/tmpl_tokenize.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,18 @@ TMPL_REQUEST_REF_DEF(tmpl_request_def_parent, REQUEST_PARENT);
103103
*
104104
* Defaults are used if a NULL rules pointer is passed to the parsing function.
105105
*/
106-
#define DEFAULT_RULES tmpl_rules_t const default_rules = { .attr = { .list_def = request_attr_request }}
106+
#define DEFAULT_RULES tmpl_rules_t default_rules = { .attr = { .list_def = request_attr_request }}
107+
108+
#define CHECK_T_RULES do { \
109+
if (!t_rules) { \
110+
t_rules = &default_rules; \
111+
if (tmpl_require_enum_prefix) default_rules.attr.prefix = TMPL_ATTR_REF_PREFIX_AUTO; \
112+
} else if (tmpl_require_enum_prefix && (t_rules->attr.prefix == TMPL_ATTR_REF_PREFIX_YES)) { \
113+
default_rules = *t_rules; \
114+
default_rules.attr.prefix = TMPL_ATTR_REF_PREFIX_AUTO; \
115+
t_rules = &default_rules; \
116+
} \
117+
} while (0)
107118

108119

109120
/* clang-format off */
@@ -541,11 +552,8 @@ static fr_slen_t tmpl_request_ref_list_from_substr(TALLOC_CTX *ctx, tmpl_attr_er
541552
tmpl_attr_rules_t const *at_rules;
542553
DEFAULT_RULES;
543554

544-
if (!t_rules) {
545-
at_rules = &default_rules.attr;
546-
} else {
547-
at_rules = &t_rules->attr;
548-
}
555+
CHECK_T_RULES;
556+
at_rules = &t_rules->attr;
549557

550558
/*
551559
* The caller wants to know the default namespace for
@@ -1076,6 +1084,11 @@ int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src)
10761084
tmpl_request_list_talloc_reverse_free(&dst->data.attribute.rr);
10771085
tmpl_request_ref_list_copy(dst, &dst->data.attribute.rr, &src->data.attribute.rr);
10781086

1087+
/*
1088+
* Ensure that we copy over any parsing rules, defaults, etc.
1089+
*/
1090+
dst->rules = src->rules;
1091+
10791092
TMPL_ATTR_VERIFY(dst);
10801093

10811094
return 0;
@@ -1773,6 +1786,8 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t
17731786
fr_dict_attr_err_t dict_err;
17741787
fr_dict_attr_t const *our_parent = parent;
17751788

1789+
fr_assert(!tmpl_require_enum_prefix || (vpt->rules.attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
1790+
17761791
fr_sbuff_marker(&m_s, name);
17771792

17781793
if (depth > FR_DICT_MAX_TLV_STACK) {
@@ -2163,6 +2178,8 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t
21632178
if (tmpl_is_attr(vpt) && tmpl_attr_tail_is_normal(vpt) &&
21642179
(tmpl_rules_cast(vpt) == tmpl_attr_tail_da(vpt)->type)) vpt->rules.cast = FR_TYPE_NULL;
21652180

2181+
TMPL_VERIFY(vpt);
2182+
21662183
fr_sbuff_marker_release(&m_s);
21672184
return 0;
21682185
}
@@ -2218,13 +2235,17 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
22182235
fr_sbuff_t our_name = FR_SBUFF(name); /* Take a local copy in case we need to back track */
22192236
bool is_raw = false;
22202237
tmpl_attr_rules_t const *at_rules;
2238+
tmpl_attr_rules_t our_at_rules;
22212239
fr_sbuff_marker_t m_l;
22222240
fr_dict_attr_t const *namespace;
22232241
DEFAULT_RULES;
22242242

2225-
if (!t_rules) t_rules = &default_rules;
2243+
CHECK_T_RULES;
2244+
22262245
at_rules = &t_rules->attr;
22272246

2247+
fr_assert(!tmpl_require_enum_prefix || (at_rules->prefix != TMPL_ATTR_REF_PREFIX_YES));
2248+
22282249
if (err) *err = TMPL_ATTR_ERROR_NONE;
22292250

22302251
if (!fr_sbuff_extend(&our_name)) {
@@ -2246,6 +2267,14 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
22462267
}
22472268
break;
22482269
}
2270+
2271+
/*
2272+
* Rewrite the prefix parsing to "auto", which affects the printing.
2273+
*/
2274+
our_at_rules = *at_rules;
2275+
our_at_rules.prefix = TMPL_ATTR_REF_PREFIX_AUTO;
2276+
at_rules = &our_at_rules;
2277+
22492278
FALL_THROUGH; /* if we do require enum prefixes, then the '&' is optional */
22502279

22512280
case TMPL_ATTR_REF_PREFIX_AUTO:
@@ -2270,6 +2299,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
22702299
*/
22712300
MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_ATTR, T_BARE_WORD, NULL, 0));
22722301
vpt->data.attribute.ref_prefix = TMPL_ATTR_REF_PREFIX_YES;
2302+
vpt->rules.attr.prefix = at_rules->prefix;
22732303

22742304
/*
22752305
* The "raw." prefix marks up the leaf attribute
@@ -2433,6 +2463,9 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
24332463
fr_assert(ar != NULL);
24342464

24352465
if (tmpl_attr_is_list_attr(ar)) vpt->rules.attr.list_def = ar->ar_da;
2466+
2467+
fr_assert(!tmpl_require_enum_prefix || (vpt->rules.attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
2468+
24362469
}
24372470

24382471
if (!tmpl_substr_terminal_check(&our_name, p_rules)) {
@@ -2478,7 +2511,7 @@ ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
24782511
ssize_t slen, name_len;
24792512
DEFAULT_RULES;
24802513

2481-
if (!t_rules) t_rules = &default_rules; /* Use the defaults */
2514+
CHECK_T_RULES;
24822515

24832516
name_len = strlen(name);
24842517
slen = tmpl_afrom_attr_substr(ctx, err, out, &FR_SBUFF_IN(name, name_len), NULL, t_rules);
@@ -3188,7 +3221,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
31883221
tmpl_t *vpt = NULL;
31893222
DEFAULT_RULES;
31903223

3191-
if (!t_rules) t_rules = &default_rules; /* Use the defaults */
3224+
CHECK_T_RULES;
31923225

31933226
*out = NULL;
31943227

@@ -3318,6 +3351,8 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out,
33183351
if (slen > 0) goto done_bareword;
33193352
fr_assert(!*out);
33203353

3354+
fr_assert(!tmpl_require_enum_prefix || (t_rules->attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
3355+
33213356
/*
33223357
* See if it's an attribute reference
33233358
* without the prefix.
@@ -3596,6 +3631,8 @@ tmpl_t *tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in)
35963631
if (unlikely(xlat_copy(vpt, vpt->data.xlat.ex, in->data.xlat.ex) < 0)) goto error;
35973632
}
35983633

3634+
TMPL_ATTR_VERIFY(vpt);
3635+
35993636
return vpt;
36003637
}
36013638

@@ -4265,6 +4302,8 @@ int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules)
42654302
fr_assert(0);
42664303
}
42674304

4305+
TMPL_VERIFY(vpt);
4306+
42684307
return ret;
42694308
}
42704309

@@ -4644,6 +4683,13 @@ fr_slen_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t
46444683
return 0;
46454684
}
46464685

4686+
/*
4687+
* Suppress the prefix on new syntax.
4688+
*/
4689+
if (tmpl_require_enum_prefix && (ar_prefix == TMPL_ATTR_REF_PREFIX_YES)) {
4690+
ar_prefix = TMPL_ATTR_REF_PREFIX_AUTO;
4691+
}
4692+
46474693
/*
46484694
* Handle printing the request reference
46494695
* prefix.
@@ -4837,6 +4883,13 @@ fr_slen_t tmpl_print(fr_sbuff_t *out, tmpl_t const *vpt,
48374883

48384884
TMPL_VERIFY(vpt);
48394885

4886+
/*
4887+
* Suppress the prefix on new syntax.
4888+
*/
4889+
if (tmpl_require_enum_prefix && (ar_prefix == TMPL_ATTR_REF_PREFIX_YES)) {
4890+
ar_prefix = TMPL_ATTR_REF_PREFIX_AUTO;
4891+
}
4892+
48404893
switch (vpt->type) {
48414894
case TMPL_TYPE_ATTR_UNRESOLVED:
48424895
case TMPL_TYPE_ATTR:
@@ -4993,6 +5046,8 @@ void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt)
49935046

49945047
fr_assert(tmpl_is_attr_unresolved(vpt) || tmpl_is_attr(vpt));
49955048

5049+
fr_assert(!tmpl_require_enum_prefix || (vpt->rules.attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
5050+
49965051
/*
49975052
* Loop detection
49985053
*/
@@ -5781,6 +5836,8 @@ void tmpl_rules_child_init(TALLOC_CTX *ctx, tmpl_rules_t *out, tmpl_rules_t cons
57815836

57825837
if (!tmpl_is_attr(vpt)) return;
57835838

5839+
fr_assert(!tmpl_require_enum_prefix || (vpt->rules.attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
5840+
57845841
da = tmpl_attr_tail_da(vpt);
57855842

57865843
/*

src/lib/unlang/compile.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ static int unlang_fixup_map(map_t *map, UNUSED void *ctx)
408408
/*
409409
* Anal-retentive checks.
410410
*/
411-
if (DEBUG_ENABLED3) {
411+
if (!tmpl_require_enum_prefix && DEBUG_ENABLED3) {
412412
if (tmpl_is_attr(map->lhs) && (map->lhs->name[0] != '&')) {
413413
cf_log_warn(cp, "Please change attribute reference to '&%s %s ...'",
414414
map->lhs->name, fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));
@@ -474,7 +474,7 @@ int unlang_fixup_update(map_t *map, void *ctx)
474474
/*
475475
* Anal-retentive checks.
476476
*/
477-
if (DEBUG_ENABLED3) {
477+
if (!tmpl_require_enum_prefix && DEBUG_ENABLED3) {
478478
if (tmpl_is_attr(map->lhs) && (map->lhs->name[0] != '&')) {
479479
cf_log_warn(cp, "Please change attribute reference to '&%s %s ...'",
480480
map->lhs->name, fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));
@@ -1306,7 +1306,7 @@ static int unlang_fixup_edit(map_t *map, void *ctx)
13061306
/*
13071307
* Anal-retentive checks.
13081308
*/
1309-
if (DEBUG_ENABLED3) {
1309+
if (!tmpl_require_enum_prefix && DEBUG_ENABLED3) {
13101310
if (tmpl_is_attr(map->lhs) && (map->lhs->name[0] != '&')) {
13111311
cf_log_warn(cp, "Please change attribute reference to '&%s %s ...'",
13121312
map->lhs->name, fr_table_str_by_value(fr_tokens_table, map->op, "<INVALID>"));

src/lib/unlang/xlat_expr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2704,7 +2704,7 @@ static fr_slen_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuf
27042704
#ifndef NDEBUG
27052705
if (vpt->name[0] == '%') {
27062706
fr_assert(vpt->rules.attr.prefix == TMPL_ATTR_REF_PREFIX_NO);
2707-
} else {
2707+
} else if (!tmpl_require_enum_prefix) {
27082708
fr_assert(vpt->rules.attr.prefix == TMPL_ATTR_REF_PREFIX_YES);
27092709
}
27102710
#endif

src/lib/unlang/xlat_tokenize.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ RCSID("$Id$")
4545
# define XLAT_HEXDUMP(...)
4646
#endif
4747

48+
extern bool tmpl_require_enum_prefix;
49+
4850
/** These rules apply to literal values and function arguments inside of an expansion
4951
*
5052
*/
@@ -465,10 +467,17 @@ static int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in,
465467
xlat_exp_t *node;
466468

467469
fr_sbuff_marker_t m_s;
468-
tmpl_rules_t our_t_rules;
470+
tmpl_rules_t our_t_rules;
469471

470472
XLAT_DEBUG("ATTRIBUTE <-- %.*s", (int) fr_sbuff_remaining(in), fr_sbuff_current(in));
471473

474+
/*
475+
* Suppress the prefix on new syntax.
476+
*/
477+
if (tmpl_require_enum_prefix && (attr_prefix == TMPL_ATTR_REF_PREFIX_YES)) {
478+
attr_prefix = TMPL_ATTR_REF_PREFIX_AUTO;
479+
}
480+
472481
/*
473482
* We need a local copy as we always allow unknowns.
474483
* This is because not all attribute references
@@ -550,6 +559,14 @@ static int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in,
550559
}
551560

552561
done:
562+
/*
563+
* Remember that it was %{User-Name}
564+
*
565+
* This is a temporary hack until all of the unit tests
566+
* pass without '&'.
567+
*/
568+
UNCONST(tmpl_attr_rules_t *, &vpt->rules.attr)->xlat = true;
569+
553570
/*
554571
* Attributes and module calls aren't pure.
555572
*/
@@ -1137,6 +1154,12 @@ ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t
11371154
fr_assert(talloc_parent(node->vpt) == node);
11381155
fr_assert(!node->flags.pure);
11391156

1157+
/*
1158+
* Can't have prefix YES if we're using the new flag. The parser / tmpl alloc routines
1159+
* MUST have set this to prefix AUTO.
1160+
*/
1161+
fr_assert(!tmpl_require_enum_prefix || (node->vpt->rules.attr.prefix != TMPL_ATTR_REF_PREFIX_YES));
1162+
11401163
/*
11411164
* Parsing &User-Name or User-Name gets printed as &User-Name.
11421165
*
@@ -1147,6 +1170,18 @@ ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t
11471170
FR_SBUFF_IN_STRCPY_RETURN(out, node->fmt);
11481171
goto done;
11491172
}
1173+
1174+
/*
1175+
* No '&', print the name, BUT without any attribute prefix.
1176+
*/
1177+
if (tmpl_require_enum_prefix && !node->vpt->rules.attr.xlat) {
1178+
char const *p = node->fmt;
1179+
1180+
if (*p == '&') p++;
1181+
1182+
FR_SBUFF_IN_STRCPY_RETURN(out, p);
1183+
goto done;
1184+
}
11501185
break;
11511186

11521187
case XLAT_ONE_LETTER:
@@ -1354,6 +1389,8 @@ fr_slen_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t
13541389
* tmpl tokenizer, and then pass the tmpl to the function. Which also means that
13551390
* we need to be able to have a fr_value_box_t which holds a ptr to a tmpl. And
13561391
* update the function arguments to say "we want a tmpl, not a string".
1392+
*
1393+
* @todo - tmpl_require_enum_prefix
13571394
*/
13581395
if (allow_attr && fr_sbuff_is_char(&our_in, '&')) {
13591396
if (xlat_tokenize_attribute(node->group, &our_in, our_p_rules, t_rules, TMPL_ATTR_REF_PREFIX_YES) < 0) goto error;

0 commit comments

Comments
 (0)