- make http_parse_cookie() "quoted string" aware and add test
authorMichael Wallner <mike@php.net>
Fri, 10 Feb 2006 20:25:58 +0000 (20:25 +0000)
committerMichael Wallner <mike@php.net>
Fri, 10 Feb 2006 20:25:58 +0000 (20:25 +0000)
http_api.c
tests/parse_cookie_001.phpt [new file with mode: 0644]

index 549d283918b067ef7f35b465e4366e37c1720c26..0b0eea748831e87098ab354dacad0f3a778b57a1 100644 (file)
@@ -95,13 +95,14 @@ void _http_key_list_default_decoder(const char *encoded, size_t encoded_len, cha
 /* {{{ */
 STATUS _http_parse_key_list(const char *list, HashTable *items, char separator, http_key_list_decode_t decode, zend_bool first_entry_is_name_value_pair TSRMLS_DC)
 {
-       const char *key = list, *val = NULL;
+       char *str = estrdup(list), *key = str, *val = NULL;
        int vallen = 0, keylen = 0, done = 0;
        zval array;
 
        INIT_ZARR(array, items);
 
-       if (!(val = strchr(list, '='))) {
+       if (!(val = strchr(str, '='))) {
+               efree(str);
                return FAILURE;
        }
 
@@ -119,16 +120,27 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator,
        }
 #define HTTP_KEYLIST_FIXKEY() \
        { \
-                       while (isspace(*key)) ++key; \
-                       keylen = val - key; \
-                       while (isspace(key[keylen - 1])) --keylen; \
+               while (isspace(*key)) ++key; \
+               keylen = val - key; \
+               while (isspace(key[keylen - 1])) --keylen; \
        }
 #define HTTP_KEYLIST_FIXVAL() \
        { \
+               ++val; \
+               while (isspace(*val)) ++val; \
+               vallen = key - val; \
+               while (isspace(val[vallen - 1])) --vallen; \
+               if (val[0] == '"' && val[vallen - 1] == '"') { \
+                       int i; \
                        ++val; \
-                       while (isspace(*val)) ++val; \
-                       vallen = key - val; \
-                       while (isspace(val[vallen - 1])) --vallen; \
+                       vallen -= 2; \
+                       for (i = 0; i < vallen; ++i) { \
+                               if (val[i] == '\\' && val[i+1] == '"' && (!i || val[i-1] != '\\')) { \
+                                       memmove(&val[i], &val[i+1], vallen - i); \
+                                       --vallen; \
+                               } \
+                       } \
+               } \
        }
 
        HTTP_KEYLIST_FIXKEY();
@@ -141,6 +153,7 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator,
                        key = val + strlen(val);
                        HTTP_KEYLIST_FIXVAL();
                        HTTP_KEYLIST_VAL(&array, "value", val, vallen);
+                       efree(str);
                        return SUCCESS;
                }
                /* additional info appended */
@@ -173,6 +186,7 @@ STATUS _http_parse_key_list(const char *list, HashTable *items, char separator,
                efree(keydup);
        } while (!done);
 
+       efree(str);
        return SUCCESS;
 }
 /* }}} */
diff --git a/tests/parse_cookie_001.phpt b/tests/parse_cookie_001.phpt
new file mode 100644 (file)
index 0000000..3e42f6b
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+parse cookie
+--SKIPIF--
+<?php
+include 'skip.inc';
+?>
+--FILE--
+<?php
+echo "-TEST\n";
+
+var_dump(http_parse_cookie('name="value"; foo="bar\"baz"; hey=got\"it'));
+
+echo "Done\n";
+?>
+--EXPECTF--
+%sTEST
+object(stdClass)#1 (4) {
+  ["name"]=>
+  string(4) "name"
+  ["value"]=>
+  string(5) "value"
+  ["foo"]=>
+  string(7) "bar"baz"
+  ["hey"]=>
+  string(7) "got\"it"
+}
+Done