Fix gh-issue #6
authorMichael Wallner <mike@php.net>
Wed, 22 Jul 2015 04:51:39 +0000 (06:51 +0200)
committerMichael Wallner <mike@php.net>
Wed, 22 Jul 2015 04:51:39 +0000 (06:51 +0200)
Allow RFC1738 unsafe characters in URL query/fragment.
Closes issue #6.

package.xml
php_http_url.c
tests/gh-issue6.phpt [new file with mode: 0644]

index 30e067a..922589a 100644 (file)
@@ -48,6 +48,7 @@ http://dev.iworks.at/ext-http/lcov/ext/http/
  <notes><![CDATA[
 * Fixed VC11 build (Jan Erhardt)
 * Fixed gh-issue #2: comparison of obsolete pointers in the header parser (xiaoyjy)
+* Fixed gh-issue #6: allow RFC1738 unsafe characters in query/fragment
 + SSL certinfo is available for libcurl >= 7.42 with gnutls (openssl has already been since 7.19.1)
 + Added "falsestart" SSL request option (available with libcurl >= 7.42 and darwinssl/NSS)
 + Added "service_name" and "proxy_service_name" request options for SPNEGO (available with libcurl >= 7.43)
@@ -246,6 +247,7 @@ http://dev.iworks.at/ext-http/lcov/ext/http/
      <file role="test" name="etag001.phpt"/>
      <file role="test" name="filterchunked.phpt"/>
      <file role="test" name="filterzlib.phpt"/>
+     <file role="test" name="gh-issue6.phpt"/>
      <file role="test" name="header001.phpt"/>
      <file role="test" name="header002.phpt"/>
      <file role="test" name="header003.phpt"/>
index c296bbc..d782962 100644 (file)
@@ -1288,8 +1288,11 @@ static const char *parse_query(struct parse_state *state)
                        state->buffer[state->offset++] = *state->ptr;
                        break;
 
-               case ']':
-               case '[':
+               /* RFC1738 unsafe */
+               case '{': case '}':
+               case '<': case '>':
+               case '[': case ']':
+               case '|': case '\\': case '^': case '`': case '"': case ' ':
                        if (state->flags & PHP_HTTP_URL_PARSE_TOPCT) {
                                state->buffer[state->offset++] = '%';
                                state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) >> 4];
@@ -1361,6 +1364,19 @@ static const char *parse_fragment(struct parse_state *state)
                        state->buffer[state->offset++] = *state->ptr;
                        break;
 
+               /* RFC1738 unsafe */
+               case '{': case '}':
+               case '<': case '>':
+               case '[': case ']':
+               case '|': case '\\': case '^': case '`': case '"': case ' ':
+                       if (state->flags & PHP_HTTP_URL_PARSE_TOPCT) {
+                               state->buffer[state->offset++] = '%';
+                               state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) >> 4];
+                               state->buffer[state->offset++] = parse_xdigits[((unsigned char) *state->ptr) & 0xf];
+                               break;
+                       }
+                       /* no break */
+
                case '?': case '/':
                case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
                case '+': case ',': case ';': case '=': /* sub-delims */
diff --git a/tests/gh-issue6.phpt b/tests/gh-issue6.phpt
new file mode 100644 (file)
index 0000000..3de34bd
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+url - unsafe characters
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php 
+
+echo "Test\n";
+
+echo (new http\Url("?__utma=1152894289.1017686999.9107388726.1439222726.1494721726.1&__utmb=115739289.1.10.1437388726&__utmc=115883619&__utmx=-&__utmz=115111289.14310476.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)&__utmv=-&__utmk=112678937"))->query;
+echo "\n";
+echo (new http\Url("?id={\$id}"))->query;
+echo "\n";
+
+?>
+===DONE===
+--EXPECT--
+Test
+__utma=1152894289.1017686999.9107388726.1439222726.1494721726.1&__utmb=115739289.1.10.1437388726&__utmc=115883619&__utmx=-&__utmz=115111289.14310476.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)&__utmv=-&__utmk=112678937
+id={$id}
+===DONE===