1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
From: Graham Campbell <GrahamCampbell@users.noreply.github.com>
Date: Sun, 20 Mar 2022 13:44:44 +0000
Subject: Release 1.8.4 (#486)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
Origin: backport, https://github.com/guzzle/psr7/commit/902db15a551a4a415e732b622282e21ce1b508b4
---
src/MessageTrait.php | 56 +++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 49 insertions(+), 7 deletions(-)
diff --git a/src/MessageTrait.php b/src/MessageTrait.php
index 1e4da64..f5f61db 100644
--- a/src/MessageTrait.php
+++ b/src/MessageTrait.php
@@ -70,7 +70,7 @@ trait MessageTrait
$value = [$value];
}
- $value = $this->trimHeaderValues($value);
+ $value = $this->trimAndValidateHeaderValues($value);
$normalized = strtolower($header);
$new = clone $this;
@@ -89,7 +89,7 @@ trait MessageTrait
$value = [$value];
}
- $value = $this->trimHeaderValues($value);
+ $value = $this->trimAndValidateHeaderValues($value);
$normalized = strtolower($header);
$new = clone $this;
@@ -148,7 +148,7 @@ trait MessageTrait
$value = [$value];
}
- $value = $this->trimHeaderValues($value);
+ $value = $this->trimAndValidateHeaderValues($value);
$normalized = strtolower($header);
if (isset($this->headerNames[$normalized])) {
$header = $this->headerNames[$normalized];
@@ -168,16 +168,58 @@ trait MessageTrait
* header-field = field-name ":" OWS field-value OWS
* OWS = *( SP / HTAB )
*
- * @param string[] $values Header values
+ * @param mixed[] $values Header values
*
* @return string[] Trimmed header values
*
* @see https://tools.ietf.org/html/rfc7230#section-3.2.4
*/
- private function trimHeaderValues(array $values)
+ private function trimAndValidateHeaderValues(array $values)
{
return array_map(function ($value) {
- return trim($value, " \t");
- }, $values);
+ if (!is_scalar($value) && null !== $value) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Header value must be scalar or null but %s provided.',
+ is_object($value) ? get_class($value) : gettype($value)
+ ));
+ }
+
+ $trimmed = trim((string) $value, " \t");
+ $this->assertValue($trimmed);
+
+ return $trimmed;
+ }, array_values($values));
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return void
+ *
+ * @see https://tools.ietf.org/html/rfc7230#section-3.2
+ *
+ * field-value = *( field-content / obs-fold )
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+ * field-vchar = VCHAR / obs-text
+ * VCHAR = %x21-7E
+ * obs-text = %x80-FF
+ * obs-fold = CRLF 1*( SP / HTAB )
+ */
+ private function assertValue($value)
+ {
+ // The regular expression intentionally does not support the obs-fold production, because as
+ // per RFC 7230#3.2.4:
+ //
+ // A sender MUST NOT generate a message that includes
+ // line folding (i.e., that has any field-value that contains a match to
+ // the obs-fold rule) unless the message is intended for packaging
+ // within the message/http media type.
+ //
+ // 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('/^(?:[\x21-\x7E\x80-\xFF](?:[\x20\x09]+[\x21-\x7E\x80-\xFF])?)*$/', $value)) {
+ throw new \InvalidArgumentException(sprintf('"%s" is not valid header value', $value));
+ }
}
}
|