diff --git a/src/Symfony/Component/HttpFoundation/HeaderUtils.php b/src/Symfony/Component/HttpFoundation/HeaderUtils.php index f4add930eb22b..fddf2512c4b59 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderUtils.php +++ b/src/Symfony/Component/HttpFoundation/HeaderUtils.php @@ -193,17 +193,23 @@ public static function makeDisposition(string $disposition, string $filename, st return $disposition.'; '.self::toString($params, ';'); } - private static function groupParts(array $matches, string $separators): array + private static function groupParts(array $matches, string $separators, bool $first = true): array { $separator = $separators[0]; $partSeparators = substr($separators, 1); $i = 0; $partMatches = []; + $previousMatchWasSeparator = false; foreach ($matches as $match) { - if (isset($match['separator']) && $match['separator'] === $separator) { + if (!$first && $previousMatchWasSeparator && isset($match['separator']) && $match['separator'] === $separator) { + $previousMatchWasSeparator = true; + $partMatches[$i][] = $match; + } elseif (isset($match['separator']) && $match['separator'] === $separator) { + $previousMatchWasSeparator = true; ++$i; } else { + $previousMatchWasSeparator = false; $partMatches[$i][] = $match; } } @@ -211,12 +217,19 @@ private static function groupParts(array $matches, string $separators): array $parts = []; if ($partSeparators) { foreach ($partMatches as $matches) { - $parts[] = self::groupParts($matches, $partSeparators); + $parts[] = self::groupParts($matches, $partSeparators, false); } } else { foreach ($partMatches as $matches) { $parts[] = self::unquote($matches[0][0]); } + + if (!$first && 2 < \count($parts)) { + $parts = [ + $parts[0], + implode($separator, \array_slice($parts, 1)), + ]; + } } return $parts; diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index 55287e082d996..e39ca673e0d74 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -227,6 +227,12 @@ public function testFromString() $cookie = Cookie::fromString('foo', true); $this->assertEquals(Cookie::create('foo', null, 0, '/', null, false, false, false, null), $cookie); + + $cookie = Cookie::fromString('foo_cookie=foo=1&bar=2&baz=3; expires=Tue, 22-Sep-2020 06:27:09 GMT; path=/'); + $this->assertEquals(Cookie::create('foo_cookie', 'foo=1&bar=2&baz=3', strtotime('Tue, 22-Sep-2020 06:27:09 GMT'), '/', null, false, false, true, null), $cookie); + + $cookie = Cookie::fromString('foo_cookie=foo==; expires=Tue, 22-Sep-2020 06:27:09 GMT; path=/'); + $this->assertEquals(Cookie::create('foo_cookie', 'foo==', strtotime('Tue, 22-Sep-2020 06:27:09 GMT'), '/', null, false, false, true, null), $cookie); } public function testFromStringWithHttpOnly() diff --git a/src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php b/src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php index d2b19ca84d1c6..eafcd9311b08f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/HeaderUtilsTest.php @@ -16,33 +16,47 @@ class HeaderUtilsTest extends TestCase { - public function testSplit() + /** + * @dataProvider provideHeaderToSplit + */ + public function testSplit(array $expected, string $header, string $separator) + { + $this->assertSame($expected, HeaderUtils::split($header, $separator)); + } + + public function provideHeaderToSplit(): array { - $this->assertSame(['foo=123', 'bar'], HeaderUtils::split('foo=123,bar', ',')); - $this->assertSame(['foo=123', 'bar'], HeaderUtils::split('foo=123, bar', ',')); - $this->assertSame([['foo=123', 'bar']], HeaderUtils::split('foo=123; bar', ',;')); - $this->assertSame([['foo=123'], ['bar']], HeaderUtils::split('foo=123, bar', ',;')); - $this->assertSame(['foo', '123, bar'], HeaderUtils::split('foo=123, bar', '=')); - $this->assertSame(['foo', '123, bar'], HeaderUtils::split(' foo = 123, bar ', '=')); - $this->assertSame([['foo', '123'], ['bar']], HeaderUtils::split('foo=123, bar', ',=')); - $this->assertSame([[['foo', '123']], [['bar'], ['foo', '456']]], HeaderUtils::split('foo=123, bar; foo=456', ',;=')); - $this->assertSame([[['foo', 'a,b;c=d']]], HeaderUtils::split('foo="a,b;c=d"', ',;=')); - - $this->assertSame(['foo', 'bar'], HeaderUtils::split('foo,,,, bar', ',')); - $this->assertSame(['foo', 'bar'], HeaderUtils::split(',foo, bar,', ',')); - $this->assertSame(['foo', 'bar'], HeaderUtils::split(' , foo, bar, ', ',')); - $this->assertSame(['foo bar'], HeaderUtils::split('foo "bar"', ',')); - $this->assertSame(['foo bar'], HeaderUtils::split('"foo" bar', ',')); - $this->assertSame(['foo bar'], HeaderUtils::split('"foo" "bar"', ',')); - - // These are not a valid header values. We test that they parse anyway, - // and that both the valid and invalid parts are returned. - $this->assertSame([], HeaderUtils::split('', ',')); - $this->assertSame([], HeaderUtils::split(',,,', ',')); - $this->assertSame(['foo', 'bar', 'baz'], HeaderUtils::split('foo, "bar", "baz', ',')); - $this->assertSame(['foo', 'bar, baz'], HeaderUtils::split('foo, "bar, baz', ',')); - $this->assertSame(['foo', 'bar, baz\\'], HeaderUtils::split('foo, "bar, baz\\', ',')); - $this->assertSame(['foo', 'bar, baz\\'], HeaderUtils::split('foo, "bar, baz\\\\', ',')); + return [ + [['foo=123', 'bar'], 'foo=123,bar', ','], + [['foo=123', 'bar'], 'foo=123, bar', ','], + [[['foo=123', 'bar']], 'foo=123; bar', ',;'], + [[['foo=123'], ['bar']], 'foo=123, bar', ',;'], + [['foo', '123, bar'], 'foo=123, bar', '='], + [['foo', '123, bar'], ' foo = 123, bar ', '='], + [[['foo', '123'], ['bar']], 'foo=123, bar', ',='], + [[[['foo', '123']], [['bar'], ['foo', '456']]], 'foo=123, bar; foo=456', ',;='], + [[[['foo', 'a,b;c=d']]], 'foo="a,b;c=d"', ',;='], + + [['foo', 'bar'], 'foo,,,, bar', ','], + [['foo', 'bar'], ',foo, bar,', ','], + [['foo', 'bar'], ' , foo, bar, ', ','], + [['foo bar'], 'foo "bar"', ','], + [['foo bar'], '"foo" bar', ','], + [['foo bar'], '"foo" "bar"', ','], + + [[['foo_cookie', 'foo=1&bar=2&baz=3'], ['expires', 'Tue, 22-Sep-2020 06:27:09 GMT'], ['path', '/']], 'foo_cookie=foo=1&bar=2&baz=3; expires=Tue, 22-Sep-2020 06:27:09 GMT; path=/', ';='], + [[['foo_cookie', 'foo=='], ['expires', 'Tue, 22-Sep-2020 06:27:09 GMT'], ['path', '/']], 'foo_cookie=foo==; expires=Tue, 22-Sep-2020 06:27:09 GMT; path=/', ';='], + [[['foo_cookie', 'foo=a=b'], ['expires', 'Tue, 22-Sep-2020 06:27:09 GMT'], ['path', '/']], 'foo_cookie=foo="a=b"; expires=Tue, 22-Sep-2020 06:27:09 GMT; path=/', ';='], + + // These are not a valid header values. We test that they parse anyway, + // and that both the valid and invalid parts are returned. + [[], '', ','], + [[], ',,,', ','], + [['foo', 'bar', 'baz'], 'foo, "bar", "baz', ','], + [['foo', 'bar, baz'], 'foo, "bar, baz', ','], + [['foo', 'bar, baz\\'], 'foo, "bar, baz\\', ','], + [['foo', 'bar, baz\\'], 'foo, "bar, baz\\\\', ','], + ]; } public function testCombine()
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: