Skip to content

Commit 89cb586

Browse files
committed
Update responseparser
1 parent d0aa7e0 commit 89cb586

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ php:
55
- 7.0
66
- 7.1
77
- hhvm
8+
- nightly
89

910
# This triggers builds to run on the new TravisCI infrastructure.
1011
# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/

src/Omnipay/Common/Http/ResponseParser.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ private static function toString($response)
3333
public static function json($response)
3434
{
3535
$body = static::toString($response);
36+
3637
$data = json_decode($body, true);
3738
if (JSON_ERROR_NONE !== json_last_error()) {
3839
throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error());
3940
}
41+
4042
return $data === null ? [] : $data;
4143
}
4244

@@ -59,21 +61,22 @@ public static function json($response)
5961
public static function xml($response)
6062
{
6163
$body = static::toString($response);
64+
6265
$errorMessage = null;
6366
$internalErrors = libxml_use_internal_errors(true);
6467
$disableEntities = libxml_disable_entity_loader(true);
6568
libxml_clear_errors();
69+
6670
try {
6771
$xml = new \SimpleXMLElement((string) $body ?: '<root />', LIBXML_NONET);
68-
if ($error = libxml_get_last_error()) {
69-
$errorMessage = $error->message;
70-
}
7172
} catch (\Exception $e) {
7273
$errorMessage = $e->getMessage();
7374
}
75+
7476
libxml_clear_errors();
7577
libxml_use_internal_errors($internalErrors);
7678
libxml_disable_entity_loader($disableEntities);
79+
7780
if ($errorMessage) {
7881
throw new RuntimeException('Unable to parse response body into XML: ' . $errorMessage);
7982
}

tests/Omnipay/Common/Http/ResponseParserTest.php

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,80 @@
88

99
class ResponseParserTest extends TestCase
1010
{
11-
public function testParsesXmlString()
11+
public function testParsesJsonString()
1212
{
13-
$data = ResponseParser::xml('<Foo><Baz>Bar</Baz></Foo>');
13+
$data = ResponseParser::json('{"Baz":"Bar"}');
1414

15-
$this->assertInstanceOf('SimpleXMLElement', $data);
16-
$this->assertEquals('Bar', (string) $data->Baz);
15+
$this->assertEquals(array('Baz' => 'Bar'), $data);
1716
}
1817

19-
public function testParsesXmlResponse()
18+
public function testParsesJsonResponse()
2019
{
21-
$response = new Response(200, [], '<Foo><Baz>Bar</Baz></Foo>');
20+
$response = new Response(200, [], '{"Baz":"Bar"}');
2221

23-
$data = ResponseParser::xml($response);
22+
$data = ResponseParser::json($response);
2423

25-
$this->assertInstanceOf('SimpleXMLElement', $data);
26-
$this->assertEquals('Bar', (string) $data->Baz);
24+
$this->assertEquals(array('Baz' => 'Bar'), $data);
2725
}
2826

29-
public function testParsesXmlResponseException()
27+
/**
28+
* @expectedException RuntimeException
29+
* @expectedExceptionMessage Unable to parse response body into JSON: 4
30+
*/
31+
public function testParsesJsonResponseException()
3032
{
3133
$this->expectException(RuntimeException::class);
3234

3335
$response = new Response(200, [], 'FooBar');
3436

35-
ResponseParser::xml($response);
37+
ResponseParser::json($response);
3638
}
3739

38-
public function testParsesJsonString()
40+
public function testParsesXmlString()
3941
{
40-
$data = ResponseParser::json('{"Baz":"Bar"}');
42+
$data = ResponseParser::xml('<Foo><Baz>Bar</Baz></Foo>');
4143

42-
$this->assertEquals(array('Baz' => 'Bar'), $data);
44+
$this->assertInstanceOf('SimpleXMLElement', $data);
45+
$this->assertEquals('Bar', (string) $data->Baz);
4346
}
4447

45-
public function testParsesJsonResponse()
48+
public function testParsesXmlResponse()
4649
{
47-
$response = new Response(200, [], '{"Baz":"Bar"}');
50+
$response = new Response(200, [], '<Foo><Baz>Bar</Baz></Foo>');
4851

49-
$data = ResponseParser::json($response);
52+
$data = ResponseParser::xml($response);
5053

51-
$this->assertEquals(array('Baz' => 'Bar'), $data);
54+
$this->assertInstanceOf('SimpleXMLElement', $data);
55+
$this->assertEquals('Bar', (string) $data->Baz);
5256
}
5357

54-
public function testParsesJsonResponseException()
58+
/**
59+
* @expectedException RuntimeException
60+
* @expectedExceptionMessage Unable to parse response body into XML: String could not be parsed as XML
61+
*/
62+
public function testParsesXmlResponseException()
5563
{
56-
$this->expectException(RuntimeException::class);
64+
$response = new Response(200, [], '<abc');
5765

58-
$response = new Response(200, [], 'FooBar');
66+
ResponseParser::xml($response);
67+
}
5968

60-
ResponseParser::json($response);
69+
/**
70+
* Based on https://github.com/guzzle/guzzle3/blob/v3.9.3/tests/Guzzle/Tests/Http/Message/ResponseTest.php#L662-L676
71+
*/
72+
public function testPreventsComplexExternalEntities()
73+
{
74+
$xml = '<?xml version="1.0"?><!DOCTYPE scan[<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=ResponseTest.php">]><scan>&test;</scan>';
75+
$response = new Response(200, [], $xml);
76+
$oldCwd = getcwd();
77+
chdir(__DIR__);
78+
try {
79+
$xml = ResponseParser::xml($response);
80+
chdir($oldCwd);
81+
$this->markTestIncomplete('Did not throw the expected exception! XML resolved as: ' . $xml->asXML());
82+
} catch (\Exception $e) {
83+
chdir($oldCwd);
84+
}
6185
}
6286

6387
}

0 commit comments

Comments
 (0)