};
static size_t const expr_assignment_op_table_len = NUM_ELEMENTS(expr_assignment_op_table);
+static bool valid_type(xlat_exp_t *node)
+{
+ fr_dict_attr_t const *da;
+
+ if (node->type != XLAT_TMPL) return true;
+
+ if (tmpl_is_list(node->vpt)) {
+ list:
+ fr_strerror_const("Cannot use list references in condition");
+ return false;
+ }
+
+ if (!tmpl_is_attr(node->vpt)) return true;
+
+ da = tmpl_da(node->vpt);
+ if (fr_type_is_structural(da->type)) {
+ if (da->dict == fr_dict_internal()) goto list;
+
+ fr_strerror_const("Cannot use structural types in condition");
+ fprintf(stderr, "FAIL %d\n", __LINE__);
+ return false;
+ }
+
+ return true;
+}
+
/** Tokenize a mathematical operation.
*
* (EXPR)
xlat_t *func = NULL;
fr_token_t op;
ssize_t slen;
- fr_sbuff_marker_t marker;
+ fr_sbuff_marker_t m_lhs, m_op, m_rhs;
fr_sbuff_t our_in = FR_SBUFF(in);
xlat_exp_head_t *args;
fr_sbuff_skip_whitespace(&our_in);
+ fr_sbuff_marker(&m_lhs, &our_in);
+
/*
* Get the LHS of the operation.
*/
/*
* Remember where we were after parsing the LHS.
*/
- fr_sbuff_marker(&marker, &our_in);
+ fr_sbuff_marker(&m_op, &our_in);
/*
* Get the operator.
fr_assert(0);
#else
- fr_sbuff_set(&our_in, &marker);
+ fr_sbuff_set(&our_in, &m_op);
fr_strerror_printf("Invalid operator '%s' - regular expressions are not supported in this build.", fr_tokens[op]);
FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen);
#endif
if (!binary_ops[op].str) {
fr_strerror_printf("Invalid operator");
- fr_sbuff_set(&our_in, &marker);
+ fr_sbuff_set(&our_in, &m_op);
return -fr_sbuff_used(&our_in);
}
* take care of continuing.
*/
if (precedence[op] <= precedence[prev]) {
- fr_sbuff_set(&our_in, &marker);
+ fr_sbuff_set(&our_in, &m_op);
goto done;
}
+ fr_sbuff_skip_whitespace(&our_in);
+ fr_sbuff_marker(&m_rhs, &our_in);
+
/*
* We now parse the RHS, allowing a (perhaps different) cast on the RHS.
*/
* optimization minimizes the amount of run-time work we have to do.
*/
+ /*
+ * Remove invalid comparisons.
+ */
+ if (fr_equality_op[op]) {
+ if (!valid_type(lhs)) {
+ fr_sbuff_set(&our_in, &m_lhs);
+ return -fr_sbuff_used(&our_in);
+ }
+
+ if (!valid_type(rhs)) {
+ fr_sbuff_set(&our_in, &m_rhs);
+ return -fr_sbuff_used(&our_in);
+ }
+ }
+
/*
* Create the function node, with the LHS / RHS arguments.
*/
#
# @todo - fix list comparisons
#
-#xlat_purify &reply == &request
-#match ERROR offset 0: Cannot use list references in condition
+xlat_purify &reply == &request
+match ERROR offset 0: Cannot use list references in condition
-#xlat_purify &reply == "hello"
-#match ERROR offset 0: Cannot use list references in condition
+xlat_purify &reply == "hello"
+match ERROR offset 0: Cannot use list references in condition
-#xlat_purify "hello" == &reply
-#match ERROR offset 11: Cannot use list references in condition
+xlat_purify "hello" == &reply
+match ERROR offset 11: Cannot use list references in condition
#
# @todo - perhaps better errors for casts?
#
xlat_purify <ipaddr>&Filter-Id == <blerg>&Framed-IP-Address
-match ERROR offset 22: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
+match ERROR offset 23: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
xlat_purify <blerg>&Filter-Id == "foo"
match ERROR offset 1: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
xlat_purify &User-Name[a] == 'bob'
match ERROR offset 11: Invalid array index
-# @todo - really 25?
xlat_purify &User-Name == &Filter-Id[a]
-match ERROR offset 24: Invalid array index
+match ERROR offset 25: Invalid array index
#
# Bounds checks...
match ((&User-Name == "bob") && ((&User-Password == "bob") || &EAP-Message))
count
-match 261
+match 267