diff --git a/src/OAuth/OAuth1/Signature/Signature.php b/src/OAuth/OAuth1/Signature/Signature.php index 2e13eb37..06b0d417 100644 --- a/src/OAuth/OAuth1/Signature/Signature.php +++ b/src/OAuth/OAuth1/Signature/Signature.php @@ -56,13 +56,13 @@ public function setTokenSecret($token) */ public function getSignature(UriInterface $uri, array $params, $method = 'POST') { - parse_str($uri->getQuery(), $queryStringData); + $queryStringData = $this->parseQueryString($uri->getQuery()); foreach (array_merge($queryStringData, $params) as $key => $value) { - $signatureData[rawurlencode($key)] = rawurlencode($value); + $signatureData[rawurlencode($key)] = rawurlencode(strtr($value, ' ', '+')); } - ksort($signatureData); + uksort($signatureData, 'strnatcmp'); // determine base uri $baseUri = $uri->getScheme() . '://' . $uri->getRawAuthority(); @@ -80,6 +80,27 @@ public function getSignature(UriInterface $uri, array $params, $method = 'POST') return base64_encode($this->hash($baseString)); } + /** + * A userland implementation of parse_str that treats arrays as string keys + * + * @param string $query + * + * @return array + */ + protected function parseQueryString($query) + { + $result = []; + $params = explode('&', $query); + foreach ($params as $param) { + if ($param === '') { + continue; + } + $parts = explode('=', $param, 2); + $result[rawurldecode($parts[0])] = isset($parts[1]) ? urldecode($parts[1]) : ''; + } + return $result; + } + /** * @param array $signatureData *