Skip to content

Commit c186627

Browse files
Merge branch '5.4' into 6.3
* 5.4: [Form] Fix merging params & files when "multiple" is enabled [HttpFoundation] Do not swallow trailing `=` in cookie value Handle Sendinblue error responses without a message key [Serializer] Fix collecting only first missing constructor argument [Messenger] Fix DoctrineOpenTransactionLoggerMiddleware [Translation] Add missing return type [Validator] add missing catalan translations
2 parents a27c541 + 2213955 commit c186627

File tree

3 files changed

+39
-33
lines changed

3 files changed

+39
-33
lines changed

HeaderUtils.php

+32-31
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,21 @@ private function __construct()
3333
*
3434
* Example:
3535
*
36-
* HeaderUtils::split("da, en-gb;q=0.8", ",;")
36+
* HeaderUtils::split('da, en-gb;q=0.8', ',;')
3737
* // => ['da'], ['en-gb', 'q=0.8']]
3838
*
3939
* @param string $separators List of characters to split on, ordered by
40-
* precedence, e.g. ",", ";=", or ",;="
40+
* precedence, e.g. ',', ';=', or ',;='
4141
*
4242
* @return array Nested array with as many levels as there are characters in
4343
* $separators
4444
*/
4545
public static function split(string $header, string $separators): array
4646
{
47+
if ('' === $separators) {
48+
throw new \InvalidArgumentException('At least one separator must be specified.');
49+
}
50+
4751
$quotedSeparators = preg_quote($separators, '/');
4852

4953
preg_match_all('
@@ -77,8 +81,8 @@ public static function split(string $header, string $separators): array
7781
*
7882
* Example:
7983
*
80-
* HeaderUtils::combine([["foo", "abc"], ["bar"]])
81-
* // => ["foo" => "abc", "bar" => true]
84+
* HeaderUtils::combine([['foo', 'abc'], ['bar']])
85+
* // => ['foo' => 'abc', 'bar' => true]
8286
*/
8387
public static function combine(array $parts): array
8488
{
@@ -95,13 +99,13 @@ public static function combine(array $parts): array
9599
/**
96100
* Joins an associative array into a string for use in an HTTP header.
97101
*
98-
* The key and value of each entry are joined with "=", and all entries
102+
* The key and value of each entry are joined with '=', and all entries
99103
* are joined with the specified separator and an additional space (for
100104
* readability). Values are quoted if necessary.
101105
*
102106
* Example:
103107
*
104-
* HeaderUtils::toString(["foo" => "abc", "bar" => true, "baz" => "a b c"], ",")
108+
* HeaderUtils::toString(['foo' => 'abc', 'bar' => true, 'baz' => 'a b c'], ',')
105109
* // => 'foo=abc, bar, baz="a b c"'
106110
*/
107111
public static function toString(array $assoc, string $separator): string
@@ -252,40 +256,37 @@ public static function parseQuery(string $query, bool $ignoreBrackets = false, s
252256
private static function groupParts(array $matches, string $separators, bool $first = true): array
253257
{
254258
$separator = $separators[0];
255-
$partSeparators = substr($separators, 1);
256-
259+
$separators = substr($separators, 1);
257260
$i = 0;
261+
262+
if ('' === $separators && !$first) {
263+
$parts = [''];
264+
265+
foreach ($matches as $match) {
266+
if (!$i && isset($match['separator'])) {
267+
$i = 1;
268+
$parts[1] = '';
269+
} else {
270+
$parts[$i] .= self::unquote($match[0]);
271+
}
272+
}
273+
274+
return $parts;
275+
}
276+
277+
$parts = [];
258278
$partMatches = [];
259-
$previousMatchWasSeparator = false;
279+
260280
foreach ($matches as $match) {
261-
if (!$first && $previousMatchWasSeparator && isset($match['separator']) && $match['separator'] === $separator) {
262-
$previousMatchWasSeparator = true;
263-
$partMatches[$i][] = $match;
264-
} elseif (isset($match['separator']) && $match['separator'] === $separator) {
265-
$previousMatchWasSeparator = true;
281+
if (($match['separator'] ?? null) === $separator) {
266282
++$i;
267283
} else {
268-
$previousMatchWasSeparator = false;
269284
$partMatches[$i][] = $match;
270285
}
271286
}
272287

273-
$parts = [];
274-
if ($partSeparators) {
275-
foreach ($partMatches as $matches) {
276-
$parts[] = self::groupParts($matches, $partSeparators, false);
277-
}
278-
} else {
279-
foreach ($partMatches as $matches) {
280-
$parts[] = self::unquote($matches[0][0]);
281-
}
282-
283-
if (!$first && 2 < \count($parts)) {
284-
$parts = [
285-
$parts[0],
286-
implode($separator, \array_slice($parts, 1)),
287-
];
288-
}
288+
foreach ($partMatches as $matches) {
289+
$parts[] = '' === $separators ? self::unquote($matches[0][0]) : self::groupParts($matches, $separators, false);
289290
}
290291

291292
return $parts;

Tests/CookieTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ public function testFromString()
313313
$cookie = Cookie::fromString('foo=bar', true);
314314
$this->assertEquals(Cookie::create('foo', 'bar', 0, '/', null, false, false, false, null), $cookie);
315315

316+
$cookie = Cookie::fromString('foo=bar=', true);
317+
$this->assertEquals(Cookie::create('foo', 'bar=', 0, '/', null, false, false, false, null), $cookie);
318+
316319
$cookie = Cookie::fromString('foo', true);
317320
$this->assertEquals(Cookie::create('foo', null, 0, '/', null, false, false, false, null), $cookie);
318321

Tests/HeaderUtilsTest.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static function provideHeaderToSplit(): array
3434
[['foo', '123, bar'], 'foo=123, bar', '='],
3535
[['foo', '123, bar'], ' foo = 123, bar ', '='],
3636
[[['foo', '123'], ['bar']], 'foo=123, bar', ',='],
37-
[[[['foo', '123']], [['bar'], ['foo', '456']]], 'foo=123, bar; foo=456', ',;='],
37+
[[[['foo', '123']], [['bar'], ['foo', '456']]], 'foo=123, bar;; foo=456', ',;='],
3838
[[[['foo', 'a,b;c=d']]], 'foo="a,b;c=d"', ',;='],
3939

4040
[['foo', 'bar'], 'foo,,,, bar', ','],
@@ -46,13 +46,15 @@ public static function provideHeaderToSplit(): array
4646

4747
[[['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=/', ';='],
4848
[[['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=/', ';='],
49+
[[['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=/', ';='],
4950
[[['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=/', ';='],
5051

5152
// These are not a valid header values. We test that they parse anyway,
5253
// and that both the valid and invalid parts are returned.
5354
[[], '', ','],
5455
[[], ',,,', ','],
55-
[['foo', 'bar', 'baz'], 'foo, "bar", "baz', ','],
56+
[[['', 'foo'], ['bar', '']], '=foo,bar=', ',='],
57+
[['foo', 'foobar', 'baz'], 'foo, foo"bar", "baz', ','],
5658
[['foo', 'bar, baz'], 'foo, "bar, baz', ','],
5759
[['foo', 'bar, baz\\'], 'foo, "bar, baz\\', ','],
5860
[['foo', 'bar, baz\\'], 'foo, "bar, baz\\\\', ','],

0 commit comments

Comments
 (0)