diff --git a/CHANGES b/CHANGES
index 4dc11b1b..fb03438f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
14 Jan 2010 - 2.5.12
--------------------
+ * Now support macro expansion in numeric operators (@eq, @ge, @lt, etc.)
+
* Update copyright to 2010.
* Reserved 700,000-799,999 IDs for Ivan Ristic.
diff --git a/apache2/re_operators.c b/apache2/re_operators.c
index 0c7cf2fe..7eb9239e 100644
--- a/apache2/re_operators.c
+++ b/apache2/re_operators.c
@@ -1778,18 +1778,27 @@ static int msre_op_validateUtf8Encoding_execute(modsec_rec *msr, msre_rule *rule
static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
+ msc_string str;
int left, right;
char *target = NULL;
+ if (error_msg == NULL) return -1;
+ *error_msg = NULL;
+
if ((var->value == NULL)||(rule->op_param == NULL)) {
/* NULL values do not match anything. */
return 0;
}
+ str.value = (char *)rule->op_param;
+ str.value_len = strlen(str.value);
+
+ expand_macros(msr, &str, rule, msr->mp);
+
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
- right = atoi(rule->op_param);
+ right = atoi(str.value);
if (left != right) {
/* No match. */
@@ -1807,6 +1816,7 @@ static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
+ msc_string str;
int left, right;
char *target = NULL;
@@ -1815,10 +1825,23 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
+ if (error_msg == NULL) return -1;
+ *error_msg = NULL;
+
+ if ((var->value == NULL)||(rule->op_param == NULL)) {
+ /* NULL values do not match anything. */
+ return 0;
+ }
+
+ str.value = (char *)rule->op_param;
+ str.value_len = strlen(str.value);
+
+ expand_macros(msr, &str, rule, msr->mp);
+
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
- right = atoi(rule->op_param);
+ right = atoi(str.value);
if (left <= right) {
/* No match. */
@@ -1836,6 +1859,7 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
+ msc_string str;
int left, right;
char *target = NULL;
@@ -1844,10 +1868,23 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
+ if (error_msg == NULL) return -1;
+ *error_msg = NULL;
+
+ if ((var->value == NULL)||(rule->op_param == NULL)) {
+ /* NULL values do not match anything. */
+ return 0;
+ }
+
+ str.value = (char *)rule->op_param;
+ str.value_len = strlen(str.value);
+
+ expand_macros(msr, &str, rule, msr->mp);
+
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
- right = atoi(rule->op_param);
+ right = atoi(str.value);
if (left >= right) {
/* No match. */
@@ -1865,6 +1902,7 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
+ msc_string str;
int left, right;
char *target = NULL;
@@ -1873,10 +1911,23 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
+ if (error_msg == NULL) return -1;
+ *error_msg = NULL;
+
+ if ((var->value == NULL)||(rule->op_param == NULL)) {
+ /* NULL values do not match anything. */
+ return 0;
+ }
+
+ str.value = (char *)rule->op_param;
+ str.value_len = strlen(str.value);
+
+ expand_macros(msr, &str, rule, msr->mp);
+
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
- right = atoi(rule->op_param);
+ right = atoi(str.value);
if (left < right) {
/* No match. */
@@ -1894,6 +1945,7 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
char **error_msg)
{
+ msc_string str;
int left, right;
char *target = NULL;
@@ -1902,10 +1954,23 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
return 0;
}
+ if (error_msg == NULL) return -1;
+ *error_msg = NULL;
+
+ if ((var->value == NULL)||(rule->op_param == NULL)) {
+ /* NULL values do not match anything. */
+ return 0;
+ }
+
+ str.value = (char *)rule->op_param;
+ str.value_len = strlen(str.value);
+
+ expand_macros(msr, &str, rule, msr->mp);
+
target = apr_pstrmemdup(msr->mp, var->value, var->value_len);
if (target == NULL) return -1;
left = atoi(target);
- right = atoi(rule->op_param);
+ right = atoi(str.value);
if (left > right) {
/* No match. */
@@ -1918,7 +1983,7 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
}
}
-/* ------------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
/**
*
diff --git a/doc/modsecurity2-apache-reference.xml b/doc/modsecurity2-apache-reference.xml
index 7dac11af..acac4098 100644
--- a/doc/modsecurity2-apache-reference.xml
+++ b/doc/modsecurity2-apache-reference.xml
@@ -5576,6 +5576,9 @@ SecRule ARGS:route "!@endsWith %{REQUEST_ADDR}" t:none,deny
Example:
SecRule &REQUEST_HEADERS_NAMES "@eq 15"
+
+ Macro expansion is performed so you may use variable names such
+ as %{TX.1}, etc.
@@ -5587,6 +5590,8 @@ SecRule ARGS:route "!@endsWith %{REQUEST_ADDR}" t:none,deny
Example:
SecRule &REQUEST_HEADERS_NAMES "@ge 15"
+
+ Macro expansion is performed so you may use variable names such
@@ -5629,6 +5634,8 @@ SecRule &GEO "@eq 0" "deny,status:403,msg:'Failed to lookup IP'"Example:
SecRule &REQUEST_HEADERS_NAMES "@gt 15"
+
+ Macro expansion is performed so you may use variable names such
@@ -5677,6 +5684,8 @@ end
Example:
SecRule &REQUEST_HEADERS_NAMES "@le 15"
+
+ Macro expansion is performed so you may use variable names such
@@ -5688,6 +5697,8 @@ end
Example:
SecRule &REQUEST_HEADERS_NAMES "@lt 15"
+
+ Macro expansion is performed so you may use variable names such