#include <ctype.h>
+#define WITH_EVAL_DEBUG (1)
+
#ifdef WITH_UNLANG
#ifdef WITH_EVAL_DEBUG
# define EVAL_DEBUG(fmt, ...) printf("EVAL: ");printf(fmt, ## __VA_ARGS__);printf("\n");fflush(stdout)
}
+static size_t regex_escape(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
+{
+ char *p = out;
+
+ while (*in && (outlen > 2)) {
+ switch (*in) {
+ case '\\':
+ case '.':
+ case '*':
+ case '+':
+ case '?':
+ case '|':
+ case '^':
+ case '$':
+ case '[': /* we don't list close braces */
+ case '{':
+ case '(':
+ if (outlen < 3) goto done;
+
+ *(p++) = '\\';
+ /* FALL-THROUGH */
+
+ default:
+ *(p++) = *(in++);
+ break;
+ }
+ }
+
+done:
+ *(p++) = '\0';
+ return p - out;
+}
+
/** Convert both operands to the same type
*
value_data_t lhs_cast, rhs_cast;
void *lhs_cast_buff = NULL, *rhs_cast_buff = NULL;
+ xlat_escape_t escape = NULL;
+
/*
* Cast operand to correct type.
*
* Regular expressions need both operands to be strings
*/
#ifdef HAVE_REGEX
- if (map->op == T_OP_REG_EQ) cast_type = PW_TYPE_STRING;
+ if (map->op == T_OP_REG_EQ) {
+ cast_type = PW_TYPE_STRING;
+ escape = regex_escape;
+ }
else
#endif
/*
if (map->rhs->type != TMPL_TYPE_LITERAL) {
char *p;
- ret = tmpl_aexpand(request, &p, request, map->rhs, NULL, NULL);
+ ret = tmpl_aexpand(request, &p, request, map->rhs, escape, NULL);
if (ret < 0) {
EVAL_DEBUG("FAIL [%i]", __LINE__);
rcode = -1;
return rcode;
}
+
/** Evaluate a map
*
* @param[in] request the REQUEST
if (map->lhs->type != TMPL_TYPE_LITERAL) {
char *p;
+ xlat_escape_t escape = NULL;
+
+ if (map->op == T_OP_REG_EQ) {
+ escape = regex_escape;
+ }
- ret = tmpl_aexpand(request, &p, request, map->lhs, NULL, NULL);
+ ret = tmpl_aexpand(request, &p, request, map->lhs, escape, NULL);
if (ret < 0) {
EVAL_DEBUG("FAIL [%i]", __LINE__);
return ret;
--- /dev/null
+#
+# PRE: update if
+#
+
+#
+# Strings which are expanded in a regex have regex special
+# characters escaped. Because the input strings are unsafe.
+#
+update request {
+ Tmp-String-0 := "example.com"
+ Tmp-String-1 := "exampleXcom"
+}
+
+if ("exampleXcom" =~ /%{Tmp-String-0}/) {
+ update reply {
+ Filter-Id := "fail 1"
+ }
+}
+
+elsif (&Tmp-String-1 =~ /%{Tmp-String-0}/) {
+ update reply {
+ Filter-Id := "fail 2"
+ }
+}
+else {
+ update reply {
+ Filter-Id := "filter"
+ }
+}
\ No newline at end of file