mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 11:28:25 +00:00
Fix parsing empty header values.
Replace the complex and somewhat unfixable regexp based parser for a parser that handles each line individually. Normalize multi-line headers to replace multiple spaces with a single one. Section 4.2 of the HTTP1.1 standard states > Any LWS that occurs between field-content MAY be replaced with > a single SP before interpreting the field value or forwarding the > message downstream. This makes me somewhat confident that we can safely normalize multi-line HTTP header values. Refs #8330
This commit is contained in:
parent
fc714a6451
commit
1a170e1eec
2 changed files with 29 additions and 10 deletions
|
@ -268,18 +268,28 @@ class HttpSocketResponse implements ArrayAccess {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match_all("/(.+):(.+)(?:(?<![\t ])\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER);
|
preg_match_all("/(.+):(.+)(?:\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER);
|
||||||
|
$lines = explode("\r\n", $header);
|
||||||
|
|
||||||
$header = array();
|
$header = array();
|
||||||
foreach ($matches as $match) {
|
foreach ($lines as $line) {
|
||||||
list(, $field, $value) = $match;
|
if (strlen($line) === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$continuation = false;
|
||||||
|
$first = substr($line, 0, 1);
|
||||||
|
|
||||||
|
// Multi-line header
|
||||||
|
if ($first === ' ' || $first === "\t") {
|
||||||
|
$value .= preg_replace("/\s+/", ' ', $line);
|
||||||
|
$continuation = true;
|
||||||
|
} elseif (strpos($line, ':') !== false) {
|
||||||
|
list($field, $value) = explode(':', $line, 2);
|
||||||
|
$field = $this->_unescapeToken($field);
|
||||||
|
}
|
||||||
|
|
||||||
$value = trim($value);
|
$value = trim($value);
|
||||||
$value = preg_replace("/[\t ]\r\n/", "\r\n", $value);
|
if (!isset($header[$field]) || $continuation) {
|
||||||
|
|
||||||
$field = $this->_unescapeToken($field);
|
|
||||||
|
|
||||||
if (!isset($header[$field])) {
|
|
||||||
$header[$field] = $value;
|
$header[$field] = $value;
|
||||||
} else {
|
} else {
|
||||||
$header[$field] = array_merge((array)$header[$field], (array)$value);
|
$header[$field] = array_merge((array)$header[$field], (array)$value);
|
||||||
|
|
|
@ -267,10 +267,19 @@ class HttpResponseTest extends CakeTestCase {
|
||||||
);
|
);
|
||||||
$this->assertEquals($expected, $r);
|
$this->assertEquals($expected, $r);
|
||||||
|
|
||||||
$header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
|
$header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nLink: \r\nX-Total-Count: 19\r\n";
|
||||||
$r = $this->HttpResponse->parseHeader($header);
|
$r = $this->HttpResponse->parseHeader($header);
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'Multi-Line' => "I am a\r\nmulti line\r\nfield value.",
|
'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT',
|
||||||
|
'Link' => '',
|
||||||
|
'X-Total-Count' => '19',
|
||||||
|
);
|
||||||
|
$this->assertEquals($expected, $r);
|
||||||
|
|
||||||
|
$header = "Multi-Line: I am a\r\n multi line \r\n\tfield value.\r\nSingle-Line: I am not\r\n";
|
||||||
|
$r = $this->HttpResponse->parseHeader($header);
|
||||||
|
$expected = array(
|
||||||
|
'Multi-Line' => "I am a multi line field value.",
|
||||||
'Single-Line' => 'I am not'
|
'Single-Line' => 'I am not'
|
||||||
);
|
);
|
||||||
$this->assertEquals($expected, $r);
|
$this->assertEquals($expected, $r);
|
||||||
|
|
Loading…
Reference in a new issue