From 18fd8915823bd9ca4156e84849e18970057dc7e4 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 17 Apr 2023 16:33:27 +0100 Subject: [PATCH] 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 0ac8663d..0bbd63e0 100644 --- a/src/MessageTrait.php +++ b/src/MessageTrait.php @@ -226,12 +226,9 @@ private function assertHeader($header) throw new \InvalidArgumentException('Header name can not be empty.'); } - 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) ); } } @@ -263,8 +260,10 @@ private function assertValue($value) // 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 3e0ebce9..baba7b5e 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -269,6 +269,10 @@ public function provideHeaderValuesContainingNotAllowedChars() // 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++) { @@ -286,6 +290,7 @@ public function provideHeaderValuesContainingNotAllowedChars() } $tests[] = ["foo" . \chr($i) . "bar"]; + $tests[] = ["foo" . \chr($i)]; } return $tests; diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index c9f06034..204015a9 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -284,6 +284,15 @@ public function invalidWithHeaderProvider() [[], 'foo', 'Header name must be a string but array provided.'], [false, 'foo', 'Header name must be a string but boolean provided.'], [new \stdClass(), 'foo', 'Header name must be a string but stdClass provided.'], + ["", 'foo', "Header name can not be empty."], + ["Content-Type\r\n\r\n", 'foo', "\"Content-Type\r\n\r\n\" is not valid header name."], + ["Content-Type\r\n", 'foo', "\"Content-Type\r\n\" is not valid header name."], + ["Content-Type\n", 'foo', "\"Content-Type\n\" is not valid header name."], + ["\r\nContent-Type", 'foo', "\"\r\nContent-Type\" is not valid header name."], + ["\nContent-Type", 'foo', "\"\nContent-Type\" is not valid header name."], + ["\n", 'foo', "\"\n\" is not valid header name."], + ["\r\n", 'foo', "\"\r\n\" is not valid header name."], + ["\t", 'foo', "\"\t\" is not valid header name."], ]); }