Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[#zf2-2461] correcting the url encoding of path segments

The function urlencode is used for encoding of path segments. But urlencode escapes
more chars than necessary. This could be a problem for legacy urls.
This adds a correction to the encode process. It decodes the valid but encoded chars.
  • Loading branch information...
commit 874a769d181e8349a05aa07e435b7fc3df826784 1 parent 17c7687
@baranga authored
View
60 library/Zend/Mvc/Router/Http/Segment.php
@@ -25,6 +25,38 @@
class Segment implements RouteInterface
{
/**
+ * Map of allowed special chars in path segments.
+ *
+ * http://tools.ietf.org/html/rfc3986#appendix-A
+ * segement = *pchar
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ * / "*" / "+" / "," / ";" / "="
+ *
+ * @var array
+ */
+ private static $urlencodeCorrectionMap = array(
+ '%21' => "!", // sub-delims
+ '%24' => "$", // sub-delims
+ '%26' => "&", // sub-delims
+ '%27' => "'", // sub-delims
+ '%28' => "(", // sub-delims
+ '%29' => ")", // sub-delims
+ '%2A' => "*", // sub-delims
+// '%2B' => "+", // sub-delims - special value for php/urlencode
+ '%2C' => ",", // sub-delims
+// '%2D' => "-", // unreserved - not touched by urlencode
+// '%2E' => ".", // unreserved - not touched by urlencode
+ '%3A' => ":", // pchar
+ '%3B' => ";", // sub-delims
+ '%3D' => "=", // sub-delims
+ '%40' => "@", // pchar
+// '%5F' => "_", // unreserved - not touched by urlencode
+ '%7E' => "~", // unreserved
+ );
+
+ /**
* Parts of the route.
*
* @var array
@@ -264,7 +296,7 @@ protected function buildPath(array $parts, array $mergedParams, $isOptional, $ha
$skip = false;
}
- $path .= urlencode($mergedParams[$part[1]]);
+ $path .= $this->encode($mergedParams[$part[1]]);
$this->assembledParams[] = $part[1];
break;
@@ -330,7 +362,7 @@ public function match(Request $request, $pathOffset = null)
foreach ($this->paramMap as $index => $name) {
if (isset($matches[$index]) && $matches[$index] !== '') {
- $params[$name] = urldecode($matches[$index]);
+ $params[$name] = $this->decode($matches[$index]);
}
}
@@ -367,4 +399,28 @@ public function getAssembledParams()
{
return $this->assembledParams;
}
+
+ /**
+ * Encode a path segment.
+ *
+ * @param string $value
+ * @return string
+ */
+ private function encode($value)
+ {
+ $encoded = urlencode($value);
+ $encoded = strtr($encoded, self::$urlencodeCorrectionMap);
+ return $encoded;
+ }
+
+ /**
+ * Decode a path segment.
+ *
+ * @param string $value
+ * @return string
+ */
+ private function decode($value)
+ {
+ return urldecode($value);
+ }
}
View
6 tests/ZendTest/Mvc/Router/Http/SegmentTest.php
@@ -153,6 +153,12 @@ public static function routeProvider()
null,
array('foo' => 'foo bar')
),
+ 'urlencode-flaws-corrected' => array(
+ new Segment('/:foo'),
+ "/!$&'()*,-.:;=@_~",
+ null,
+ array('foo' => "!$&'()*,-.:;=@_~")
+ ),
'empty-matches-are-replaced-with-defaults' => array(
new Segment('/foo[/:bar]/baz-:baz', array(), array('bar' => 'bar')),
'/foo/baz-baz',
Please sign in to comment.
Something went wrong with that request. Please try again.