.list_def = request_attr_request,
.allow_unresolved = true,
.allow_unknown = true
- }
+ },
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
};
/*
.allow_unknown = true,
.allow_unresolved = true,
.allow_foreign = true,
- }
+ },
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
};
fr_sbuff_t sbuff = FR_SBUFF_IN(cp->value, strlen(cp->value));
.prefix = TMPL_ATTR_REF_PREFIX_AUTO,
.list_def = request_attr_request,
.list_presence = TMPL_ATTR_LIST_ALLOW,
- }
+ },
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
+
};
rhs_rules = (tmpl_rules_t) {
.attr = {
.list_def = request_attr_request,
.list_presence = TMPL_ATTR_LIST_ALLOW,
.bare_word_enum = v3_compat,
- }
+ },
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
};
while (true) {
.dict_def = dict,
.list_def = request_attr_request,
},
+
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
};
fr_assert(parse_rules.attr.dict_def != NULL);
while ((child = fr_value_box_list_pop_head(&vb->vb_group)) != NULL) {
child->tainted = true;
+ fr_value_box_mark_unsafe(child);
fr_dcursor_append(out, child);
}
*/
void _fr_value_box_mark_safe_for(fr_value_box_t *vb, fr_value_box_safe_for_t safe_for)
{
+ /*
+ * Don't over-ride value-boxes which are already safe.
+ */
+ if (vb->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY) {
+ fr_assert(!vb->tainted);
+ return;
+ }
+
vb->safe_for = safe_for;
+ vb->tainted = false;
}
/** Mark a value-box as "unsafe"
*/
void fr_value_box_list_mark_safe_for(fr_value_box_list_t *list, fr_value_box_safe_for_t safe_for)
{
- fr_value_box_list_foreach(list, vb) vb->safe_for = safe_for;
+ fr_value_box_list_foreach(list, vb) {
+ /*
+ * Don't over-ride value-boxes which are already safe.
+ */
+ if (vb->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY) {
+ fr_assert(!vb->tainted);
+
+ } else {
+ vb->safe_for = safe_for;
+ vb->tainted = false;
+ }
+ }
}
/** Check truthiness of values.
*/
typedef uintptr_t fr_value_box_safe_for_t;
+#define FR_VALUE_BOX_SAFE_FOR_NONE ((uintptr_t) 0)
+#define FR_VALUE_BOX_SAFE_FOR_ANY (~((uintptr_t) 0))
+
/** Union containing all data types supported by the server
*
* This union contains all data types that can be represented by fr_pair_ts. It may also be used in other parts
void fr_value_box_mark_unsafe(fr_value_box_t *box)
CC_HINT(nonnull);
-#define fr_value_box_is_safe_for(_box, _safe_for) (_box->safe_for == (fr_value_box_safe_for_t)_safe_for)
+#define fr_value_box_is_safe_for(_box, _safe_for) ((_box->safe_for == (fr_value_box_safe_for_t)_safe_for) || (_box->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY))
void fr_value_box_list_mark_safe_for(fr_value_box_list_t *list, fr_value_box_safe_for_t safe_for);
.xlat = {
.runtime_el = unlang_interpret_event_list(request),
},
- .at_runtime = true
+ .at_runtime = true,
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
});
if (!vpt) {
REMARKER(tmpl_str, -slen, "%s", fr_strerror());
.list_def = request_attr_request,
.list_presence = TMPL_ATTR_LIST_FORBID,
.prefix = TMPL_ATTR_REF_PREFIX_AUTO,
- }
+ },
+ .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
};
rcode = map_afrom_cs(ctx, head, cs, &parse_rules, &parse_rules, status_check_verify, parent, 128);
# Strings which are expanded in a regex have regex special
# characters escaped. Because the input strings are unsafe.
#
-test_string1 := "example.com"
+test_string1 := %taint("example.com")
test_string2 := "exampleXcom"
if ("exampleXcom" =~ /%{test_string1}/) {