Skip to content

Commit

Permalink
Gracefully handle invalid chunks in HttpSocket
Browse files Browse the repository at this point in the history
When invalid chunks are detected we should assume the server is
incorrect and handle the remaining content as a single large chunk.

Refs #5140
  • Loading branch information
markstory committed Nov 18, 2014
1 parent f570f93 commit 8cbf975
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 14 deletions.
23 changes: 12 additions & 11 deletions lib/Cake/Network/Http/HttpSocketResponse.php
Expand Up @@ -221,28 +221,29 @@ protected function _decodeChunkedBody($body) {
$chunkLength = null;

while ($chunkLength !== 0) {
if (!preg_match('/^([0-9a-f]+) *(?:;(.+)=(.+))?(?:\r\n|\n)/iU', $body, $match)) {
throw new SocketException(__d('cake_dev', 'HttpSocket::_decodeChunkedBody - Could not parse malformed chunk.'));
if (!preg_match('/^([0-9a-f]+)[ ]*(?:;(.+)=(.+))?(?:\r\n|\n)/iU', $body, $match)) {
// Handle remaining invalid data as one big chunk.
preg_match('/^(.*?)\r\n/', $body, $invalidMatch);
$length = isset($invalidMatch[1]) ? strlen($invalidMatch[1]) : 0;
$match = array(
0 => '',
1 => dechex($length)
);
}

$chunkSize = 0;
$hexLength = 0;
$chunkExtensionValue = '';
if (isset($match[0])) {
$chunkSize = $match[0];
}
if (isset($match[1])) {
$hexLength = $match[1];
}
if (isset($match[3])) {
$chunkExtensionValue = $match[3];
}

$body = substr($body, strlen($chunkSize));
$chunkLength = hexdec($hexLength);
$chunk = substr($body, 0, $chunkLength);
$decodedBody .= $chunk;
if ($chunkLength !== 0) {
$body = substr($body, strlen($chunkSize));

$decodedBody .= substr($body, 0, $chunkLength);
if ($chunkLength) {
$body = substr($body, $chunkLength + strlen("\r\n"));
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Cake/Test/Case/Network/Http/HttpResponseTest.php
Expand Up @@ -15,7 +15,6 @@
* @since CakePHP(tm) v 1.2.0.4206
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/

App::uses('HttpResponse', 'Network/Http');

/**
Expand Down Expand Up @@ -453,12 +452,13 @@ public function testDecodeChunkedBody() {
/**
* testDecodeChunkedBodyError method
*
* @expectedException SocketException
* @return void
*/
public function testDecodeChunkedBodyError() {
$encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
$this->HttpResponse->decodeChunkedBody($encoded);
$result = $this->HttpResponse->decodeChunkedBody($encoded);
$expected = "This is a chunked message\nThat is cool\n";
$this->assertEquals($expected, $result['body']);
}

/**
Expand Down

0 comments on commit 8cbf975

Please sign in to comment.