]> granicus.if.org Git - apache/commitdiff
Introduce integer comparison support in RewriteCond
authorWilliam A. Rowe Jr <wrowe@apache.org>
Thu, 16 Sep 2010 18:57:23 +0000 (18:57 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Thu, 16 Sep 2010 18:57:23 +0000 (18:57 +0000)
The operators -gt, -ge, -eq, -le, -lt and -ne follow the bash test' semantics
for comparing the integer values of the lhs and rhs expressions, as opposed
to the string evaluations performed by > >= = <= and <.

Note that -lt and -le overlap the existing -l test, and could be confused in
expresions such as -ltestfile - to avoid this conflict use -L or -h in place
of the legacy -l file symlink test operator.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@997878 13f79535-47bb-0310-9956-ffa450edef68

modules/mappers/mod_rewrite.c

index f06abc32d2bcfb92b8de1ea77c8041230d5776d0..6e0929cfe2ac7d7c1a9deaf7e392b2bd226f2af0 100644 (file)
@@ -264,7 +264,12 @@ typedef enum {
     CONDPAT_STR_LE,
     CONDPAT_STR_EQ,
     CONDPAT_STR_GT,
-    CONDPAT_STR_GE
+    CONDPAT_STR_GE,
+    CONDPAT_INT_LT,
+    CONDPAT_INT_LE,
+    CONDPAT_INT_EQ,
+    CONDPAT_INT_GT,
+    CONDPAT_INT_GE
 } pattern_type;
 
 typedef struct {
@@ -3178,12 +3183,32 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
             case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break;
             case 's': newcond->ptype = CONDPAT_FILE_SIZE;   break;
             case 'd': newcond->ptype = CONDPAT_FILE_DIR;    break;
-            case 'l': newcond->ptype = CONDPAT_FILE_LINK;   break;
             case 'x': newcond->ptype = CONDPAT_FILE_XBIT;   break;
             case 'h': newcond->ptype = CONDPAT_FILE_LINK;   break;
             case 'L': newcond->ptype = CONDPAT_FILE_LINK;   break;
             case 'U': newcond->ptype = CONDPAT_LU_URL;      break;
             case 'F': newcond->ptype = CONDPAT_LU_FILE;     break;
+            case 'l': if (a2[2] == 't')
+                          a2 += 3, newcond->ptype = CONDPAT_INT_LT;
+                      else if (a2[2] == 'e')
+                          a2 += 3, newcond->ptype = CONDPAT_INT_LE;
+                      else /* Historical; prefer -L or -h instead */
+                          newcond->ptype = CONDPAT_FILE_LINK;
+                      break;
+            case 'g': if (a2[2] == 't')
+                          a2 += 3, newcond->ptype = CONDPAT_INT_GT;
+                      else if (a2[2] == 'e')
+                          a2 += 3, newcond->ptype = CONDPAT_INT_GE;
+                      break;
+            case 'e': if (a2[2] == 'q')
+                          a2 += 3, newcond->ptype = CONDPAT_INT_EQ;
+                      break;
+            case 'n': if (a2[2] == 'e') {
+                          /* Inversion, ensure !-ne == -eq */
+                          a2 += 3, newcond->ptype = CONDPAT_INT_EQ;
+                          newcond->flags ^= CONDFLAG_NOTMATCH;
+                      }
+                      break;
             }
         }
         else {
@@ -3706,6 +3731,14 @@ test_str_l:
         }
         break;
 
+    case CONDPAT_INT_GE: rc = (atoi(input) >= atoi(p->pattern)); break;
+    case CONDPAT_INT_GT: rc = (atoi(input) > atoi(p->pattern));  break;
+
+    case CONDPAT_INT_LE: rc = (atoi(input) <= atoi(p->pattern)); break;
+    case CONDPAT_INT_LT: rc = (atoi(input) < atoi(p->pattern));  break;
+
+    case CONDPAT_INT_EQ: rc = (atoi(input) == atoi(p->pattern)); break;
+
     default:
         /* it is really a regexp pattern, so apply it */
         rc = !ap_regexec(p->regexp, input, AP_MAX_REG_MATCH, regmatch, 0);