You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2019/03/28 22:39:32 UTC

svn commit: r1856507 - /httpd/httpd/trunk/modules/cache/cache_util.c

Author: ylavic
Date: Thu Mar 28 22:39:31 2019
New Revision: 1856507

URL: http://svn.apache.org/viewvc?rev=1856507&view=rev
Log:
mod_cache: follow up to r1856493: cache_strqtok() to reject quoted tokens.

Use a real state machine to track where quotes are allowed, and for
better clarity too...

Modified:
    httpd/httpd/trunk/modules/cache/cache_util.c

Modified: httpd/httpd/trunk/modules/cache/cache_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=1856507&r1=1856506&r2=1856507&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/cache_util.c (original)
+++ httpd/httpd/trunk/modules/cache/cache_util.c Thu Mar 28 22:39:31 2019
@@ -932,7 +932,12 @@ apr_status_t cache_strqtok(char *str, ch
 {
 #define CACHE_TOKEN_SEPS "\t ,"
     apr_status_t rv = APR_SUCCESS;
-    int quoted = 0;
+    enum {
+        IN_TOKEN,
+        IN_BETWEEN,
+        IN_ARGUMENT,
+        IN_QUOTES
+    } state = IN_TOKEN;
     char *wpos;
 
     if (!str) {         /* subsequent call */
@@ -964,32 +969,43 @@ apr_status_t cache_strqtok(char *str, ch
      * quoted strings, escaped characters.
      */
     for (wpos = str; *str; ++str) {
-        if (!quoted) {
-            if (*str == '"') {
-                quoted = 1;
-                continue;
-            }
-            if (arg && !*arg && *str == '=') {
+        switch (state) {
+        case IN_TOKEN:
+            if (*str == '=') {
+                state = IN_BETWEEN;
                 *wpos++ = '\0';
                 *arg = wpos;
                 continue;
             }
+            break;
+
+        case IN_BETWEEN:
+            if (*str == '"') {
+                state = IN_QUOTES;
+                continue;
+            }
+            /* fall through */
+            state = IN_ARGUMENT;
+        case IN_ARGUMENT:
             if (TEST_CHAR(*str, T_HTTP_TOKEN_STOP)) {
-                break;
+                goto end;
             }
-        }
-        else {
+            break;
+
+        default:
+            AP_DEBUG_ASSERT(state == IN_QUOTES);
             if (*str == '"') {
                 ++str;
-                break;
+                goto end;
             }
             if (*str == '\\' && *(str + 1)) {
                 ++str;
             }
+            break;
         }
         *wpos++ = *str;
     }
-
+end:
     /* anything after should be trailing OWS or comma */
     for (; *str; ++str) {
         if (*str == ',') {