Skip to content

Commit

Permalink
Fix parsing in Header::normalize() (#476)
Browse files Browse the repository at this point in the history
Co-Authored-By: Tim Düsterhus <209270+TimWolla@users.noreply.github.com>

Co-authored-by: Tim Düsterhus <209270+TimWolla@users.noreply.github.com>
  • Loading branch information
GrahamCampbell and TimWolla committed Mar 13, 2022
1 parent ff76777 commit d55bd56
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 11 deletions.
18 changes: 10 additions & 8 deletions src/Header.php
Expand Up @@ -47,19 +47,21 @@ public static function parse($header): array
*/
public static function normalize($header): array
{
if (!is_array($header)) {
return array_map('trim', explode(',', $header));
}

$result = [];
foreach ($header as $value) {
foreach ((array) $header as $value) {
foreach ((array) $value as $v) {
if (strpos($v, ',') === false) {
$result[] = $v;
$trimmed = trim($v);
if ($trimmed !== '') {
$result[] = $trimmed;
}
continue;
}
foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
$result[] = trim($vv);
foreach (preg_split('/,(?=([^"]*"([^"]|\\\\.)*")*[^"]*$)/', $v) as $vv) {
$trimmed = trim($vv);
if ($trimmed !== '') {
$result[] = $trimmed;
}
}
}
}
Expand Down
87 changes: 84 additions & 3 deletions tests/HeaderTest.php
Expand Up @@ -63,9 +63,90 @@ public function testParseParams($header, $result): void
self::assertSame($result, Psr7\Header::parse($header));
}

public function testParsesArrayHeaders(): void
public function normalizeProvider(): array
{
$header = ['a, b', 'c', 'd, e'];
self::assertSame(['a', 'b', 'c', 'd', 'e'], Psr7\Header::normalize($header));
return [
[
'',
[],
],
[
['a, b', 'c', 'd, e'],
['a', 'b', 'c', 'd', 'e'],
],
// Example 'accept-encoding'
[
'gzip, br',
['gzip', 'br'],
],
// https://httpwg.org/specs/rfc7231.html#rfc.section.5.3.2
[
'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c',
['text/plain; q=0.5', 'text/html', 'text/x-dvi; q=0.8', 'text/x-c'],
],
// Example 'If-None-Match' with comma within an ETag
[
'"foo", "foo,bar", "bar"',
['"foo"', '"foo,bar"', '"bar"'],
],
// https://httpwg.org/specs/rfc7234.html#cache.control.extensions
[
'private, community="UCI"',
['private', 'community="UCI"'],
],
// The Cache-Control example with a comma within a community
[
'private, community="Guzzle,Psr7"',
['private', 'community="Guzzle,Psr7"'],
],
// The Cache-Control example with an escaped space (quoted-pair) within a community
[
'private, community="Guzzle\\ Psr7"',
['private', 'community="Guzzle\\ Psr7"'],
],
// The Cache-Control example with an escaped quote (quoted-pair) within a community
[
'private, community="Guzzle\\"Psr7"',
['private', 'community="Guzzle\\"Psr7"'],
],
// The Cache-Control example with an escaped quote (quoted-pair) and a comma within a community
[
'private, community="Guzzle\\",Psr7"',
['private', 'community="Guzzle\\",Psr7"'],
],
// The Cache-Control example with an escaped backslash (quoted-pair) within a community
[
'private, community="Guzzle\\\\Psr7"',
['private', 'community="Guzzle\\\\Psr7"'],
],
// The Cache-Control example with an escaped backslash (quoted-pair) within a community
[
'private, community="Guzzle\\\\", Psr7',
['private', 'community="Guzzle\\\\"', 'Psr7'],
],
// https://httpwg.org/specs/rfc7230.html#rfc.section.7
[
'foo ,bar,',
['foo', 'bar'],
],
// https://httpwg.org/specs/rfc7230.html#rfc.section.7
[
'foo , ,bar,charlie ',
['foo', 'bar', 'charlie'],
],
[
"<https://example.gitlab.com>; rel=\"first\",\n<https://example.gitlab.com>; rel=\"next\",\n<https://example.gitlab.com>; rel=\"prev\",\n<https://example.gitlab.com>; rel=\"last\",",
['<https://example.gitlab.com>; rel="first"', '<https://example.gitlab.com>; rel="next"', '<https://example.gitlab.com>; rel="prev"', '<https://example.gitlab.com>; rel="last"'],
],
];
}

/**
* @dataProvider normalizeProvider
*/
public function testNormalize($header, $result): void
{
self::assertSame($result, Psr7\Header::normalize([$header]));
self::assertSame($result, Psr7\Header::normalize($header));
}
}

0 comments on commit d55bd56

Please sign in to comment.