From c81a3a7a33b328d2b141493d9b2d11adcae0d85a Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 17 Apr 2023 16:34:07 +0100 Subject: [PATCH 1/2] Patch header validation issue --- src/MessageTrait.php | 13 ++++++------- tests/RequestTest.php | 5 +++++ tests/ResponseTest.php | 9 +++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/MessageTrait.php b/src/MessageTrait.php index d2dc28b6..464bdfaa 100644 --- a/src/MessageTrait.php +++ b/src/MessageTrait.php @@ -224,12 +224,9 @@ private function assertHeader($header): void )); } - if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $header)) { + if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) { throw new \InvalidArgumentException( - sprintf( - '"%s" is not valid header name', - $header - ) + sprintf('"%s" is not valid header name.', $header) ); } } @@ -257,8 +254,10 @@ private function assertValue(string $value): void // Clients must not send a request with line folding and a server sending folded headers is // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting // folding is not likely to break any legitimate use case. - if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/', $value)) { - throw new \InvalidArgumentException(sprintf('"%s" is not valid header value', $value)); + if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) { + throw new \InvalidArgumentException( + sprintf('"%s" is not valid header value.', $value) + ); } } } diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 71d90b21..6ae03e83 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -332,6 +332,10 @@ public function provideHeaderValuesContainingNotAllowedChars(): iterable // Line folding is technically allowed, but deprecated. // We don't support it. ["new\r\n line"], + ["newline\n"], + ["\nnewline"], + ["newline\r\n"], + ["\r\nnewline"], ]; for ($i = 0; $i <= 0xff; $i++) { @@ -349,6 +353,7 @@ public function provideHeaderValuesContainingNotAllowedChars(): iterable } $tests[] = ["foo" . \chr($i) . "bar"]; + $tests[] = ["foo" . \chr($i)]; } return $tests; diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 9accb4f8..00798198 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -288,6 +288,15 @@ public function invalidWithHeaderProvider(): iterable yield [[], 'foo', 'Header name must be a string but array provided.']; yield [false, 'foo', 'Header name must be a string but boolean provided.']; yield [new \stdClass(), 'foo', 'Header name must be a string but stdClass provided.']; + yield ['', 'foo', "\"\" is not valid header name."]; + yield ["Content-Type\r\n\r\n", 'foo', "\"Content-Type\r\n\r\n\" is not valid header name."]; + yield ["Content-Type\r\n", 'foo', "\"Content-Type\r\n\" is not valid header name."]; + yield ["Content-Type\n", 'foo', "\"Content-Type\n\" is not valid header name."]; + yield ["\r\nContent-Type", 'foo', "\"\r\nContent-Type\" is not valid header name."]; + yield ["\nContent-Type", 'foo', "\"\nContent-Type\" is not valid header name."]; + yield ["\n", 'foo', "\"\n\" is not valid header name."]; + yield ["\r\n", 'foo', "\"\r\n\" is not valid header name."]; + yield ["\t", 'foo', "\"\t\" is not valid header name."]; } public function testHeaderValuesAreTrimmed(): void From 920f4cb7e402155a729bd823a30d3fbd8f0175f3 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 17 Apr 2023 16:38:23 +0100 Subject: [PATCH 2/2] Release 2.4.5 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eabd304..49e0c12a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## 2.4.5 - 2023-04-17 + +### Fixed + +- Prevent possible warnings on unset variables in `ServerRequest::normalizeNestedFileSpec` +- Fixed `Message::bodySummary` when `preg_match` fails +- Fixed header validation issue + ## 2.4.4 - 2023-03-09 ### Changed