Skip to content

Commit

Permalink
Merge pull request #236 from stephenharris/bugfix/rfc2616-chunk-decod…
Browse files Browse the repository at this point in the history
…ing-bug

Fixes bug in rfc2616 #3.6.1 implementation.
  • Loading branch information
rmccue authored Sep 18, 2016
2 parents 1c39a78 + 2f1b5dc commit ea359d3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
6 changes: 4 additions & 2 deletions library/Requests.php
Original file line number Diff line number Diff line change
Expand Up @@ -749,15 +749,17 @@ public static function parse_multiple(&$response, $request) {
* @return string Decoded body
*/
protected static function decode_chunked($data) {
if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($data))) {
if (!preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', trim($data))) {
return $data;
}



$decoded = '';
$encoded = $data;

while (true) {
$is_chunked = (bool) preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches);
$is_chunked = (bool) preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', $encoded, $matches);
if (!$is_chunked) {
// Looks like it's not chunked after all
return $data;
Expand Down
29 changes: 27 additions & 2 deletions tests/ChunkedEncoding.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ public static function chunkedProvider() {
"02\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n",
"abra\ncadabra\nall we got\n"
),
array(
"02;foo=bar;hello=world\r\nab\r\n04;foo=baz\r\nra\nc\r\n06;justfoo\r\nadabra\r\n0c\r\n\nall we got\n",
"abra\ncadabra\nall we got\n"
),
array(
"02;foo=\"quoted value\"\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n",
"abra\ncadabra\nall we got\n"
),
array(
"02;foo-bar=baz\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n",
"abra\ncadabra\nall we got\n"
),
);
}

Expand All @@ -34,12 +46,24 @@ public function testChunked($body, $expected){
$this->assertEquals($expected, $response->body);
}

public static function notChunkedProvider() {
return array(
'invalid chunk size' => array( 'Hello! This is a non-chunked response!' ),
'invalid chunk extension' => array( '1BNot chunked\r\nLooks chunked but it is not\r\n' ),
'unquoted chunk-ext-val with space' => array( "02;foo=unquoted with space\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n" ),
'unquoted chunk-ext-val with forbidden character' => array( "02;foo={unquoted}\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n" ),
'invalid chunk-ext-name' => array( "02;{foo}=bar\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n" ),
'incomplete quote for chunk-ext-value' => array( "02;foo=\"no end quote\r\nab\r\n04\r\nra\nc\r\n06\r\nadabra\r\n0c\r\n\nall we got\n" ),
);
}

/**
* Response says it's chunked, but actually isn't
* @dataProvider notChunkedProvider
*/
public function testNotActuallyChunked() {
public function testNotActuallyChunked($body) {
$transport = new MockTransport();
$transport->body = 'Hello! This is a non-chunked response!';
$transport->body = $body;
$transport->chunked = true;

$options = array(
Expand All @@ -50,6 +74,7 @@ public function testNotActuallyChunked() {
$this->assertEquals($transport->body, $response->body);
}


/**
* Response says it's chunked and starts looking like it is, but turns out
* that they're lying to us
Expand Down

0 comments on commit ea359d3

Please sign in to comment.