Merge pull request #5196 from cakephp/issue-5140

Gracefully handle invalid chunks in HttpSocket
This commit is contained in:
Mark Story 2014-11-18 21:58:41 -05:00
commit 5dab175aa9
2 changed files with 15 additions and 14 deletions

View file

@ -221,28 +221,29 @@ class HttpSocketResponse implements ArrayAccess {
$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"));
}
}

View file

@ -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');
/**
@ -453,12 +452,13 @@ class HttpResponseTest extends CakeTestCase {
/**
* 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']);
}
/**