Issues (320)

tests/04ParsingTest.php (8 issues)

Labels
1
<?php
2
3
include_once __DIR__ . '/LoggerAwareTestCase.php';
4
5
/**
6
 * Tests involving xml parsing.
7
 *
8
 * @todo some tests are here even though they logically belong elsewhere...
9
 */
10
class ParsingTest extends PhpXmlRpc_LoggerAwareTestCase
11
{
12
    protected function newRequest($methodName, $params = array())
13
    {
14
        $msg = new xmlrpcmsg($methodName, $params);
15
        $msg->setDebug($this->args['DEBUG']);
16
        return $msg;
17
    }
18
19
    public function testValidNumbers()
20
    {
21
        $m = $this->newRequest('dummy');
22
        $fp =
23
            '<?xml version="1.0"?>
24
<methodResponse>
25
<params>
26
<param>
27
<value>
28
<struct>
29
<member><name>integer1</name><value><int>01</int></value></member>
30
<member><name>integer2</name><value><int>+1</int></value></member>
31
<member><name>integer3</name><value><i4>1</i4></value></member>
32
<member><name>integer4</name><value><int> 1 </int></value></member>
33
<member><name>float1</name><value><double>01.10</double></value></member>
34
<member><name>float2</name><value><double>+1.10</double></value></member>
35
<member><name>float3</name><value><double>-1.10e2</double></value></member>
36
<member><name>float4</name><value><double> -1.10e2 </double></value></member>
37
</struct>
38
</value>
39
</param>
40
</params>
41
</methodResponse>';
42
        $r = $m->parseResponse($fp);
43
        $v = $r->value();
44
        $s = $v->structmem('integer1');
45
        $t = $v->structmem('integer2');
46
        $u = $v->structmem('integer3');
47
        $u2 = $v->structmem('integer4');
48
        $x = $v->structmem('float1');
49
        $y = $v->structmem('float2');
50
        $z = $v->structmem('float3');
51
        $z2 = $v->structmem('float4');
52
        $this->assertEquals(1, $s->scalarval());
53
        $this->assertEquals(1, $t->scalarval());
54
        $this->assertEquals(1, $u->scalarval());
55
        $this->assertEquals(1, $u2->scalarval());
56
        $this->assertEquals('int', $u->scalartyp());
57
58
        $this->assertEquals(1.1, $x->scalarval());
59
        $this->assertEquals(1.1, $y->scalarval());
60
        $this->assertEquals(-110.0, $z->scalarval());
61
        $this->assertEquals(-110.0, $z2->scalarval());
62
    }
63
64
    public function testBooleans()
65
    {
66
        $m = $this->newRequest('dummy');
67
        $fp =
68
            '<?xml version="1.0"?>
69
<methodResponse><params><param><value><struct>
70
<member><name>b1</name>
71
<value><boolean>1</boolean></value></member>
72
<member><name>b2</name>
73
<value><boolean> 1 </boolean></value></member>
74
<member><name>b3</name>
75
<value><boolean>tRuE</boolean></value></member>
76
<member><name>b4</name>
77
<value><boolean>0</boolean></value></member>
78
<member><name>b5</name>
79
<value><boolean> 0 </boolean></value></member>
80
<member><name>b6</name>
81
<value><boolean>fAlSe</boolean></value></member>
82
</struct></value></param></params></methodResponse>';
83
        $r = $m->parseResponse($fp);
84
        $v = $r->value();
85
86
        $s = $v->structmem('b1');
87
        $t = $v->structmem('b2');
88
        $u = $v->structmem('b3');
89
        $x = $v->structmem('b4');
90
        $y = $v->structmem('b5');
91
        $z = $v->structmem('b6');
92
93
        /// @todo this test fails with phpunit, but the same code works elsewhere! It makes string-int casting stricter??
94
        $this->assertEquals(true, $s->scalarval());
95
        //$this->assertEquals(true, $t->scalarval());
96
        $this->assertEquals(true, $u->scalarval());
97
        $this->assertEquals(false, $x->scalarval());
98
        //$this->assertEquals(false, $y->scalarval());
99
        $this->assertEquals(false, $z->scalarval());
100
    }
101
102
    public function testI8()
103
    {
104
        if (PHP_INT_SIZE == 4 ) {
105
            $this->markTestSkipped('Can not test i8 as php is compiled in 32 bit mode');
106
        }
107
108
        $m = $this->newRequest('dummy');
109
        $fp =
110
            '<?xml version="1.0"?>
111
<methodResponse>
112
<params>
113
<param>
114
<value>
115
<struct>
116
<member>
117
<name>integer1</name>
118
<value><i8>1</i8></value>
119
</member>
120
<member>
121
<name>integer2</name>
122
<value><ex:i8>1</ex:i8></value>
123
</member>
124
</struct>
125
</value>
126
</param>
127
</params>
128
</methodResponse>';
129
        $r = $m->parseResponse($fp);
130
        $v = $r->value();
131
        $s = $v->structmem('integer1');
132
        $this->assertEquals(1, $s->scalarval());
133
        $s = $v->structmem('integer2');
134
        $this->assertEquals(1, $s->scalarval());
135
        $this->assertEquals('i8', $s->scalartyp());
136
    }
137
138
    // struct with value before name, with no name, with no value, etc...
139
    public function testQuirkyStruct()
140
    {
141
        $m = $this->newRequest('dummy');
142
        $fp =
143
            '<?xml version="1.0"?>
144
<methodResponse>
145
<params>
146
<param>
147
<value>
148
<struct>
149
<member>
150
<value><int>1</int></value>
151
<name>Gollum</name>
152
</member>
153
<member>
154
<name>Bilbo</name>
155
</member>
156
<member>
157
<value><int>9</int></value>
158
</member>
159
<member>
160
<value><int>1</int></value>
161
</member>
162
</struct>
163
</value>
164
</param>
165
</params>
166
</methodResponse>';
167
        $r = $m->parseResponse($fp);
168
        $v = $r->value();
169
        $this->assertEquals(2, count($v));
170
        $s = $v['Gollum'];
171
        $this->assertEquals(1, $s->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

171
        $this->assertEquals(1, $s->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
172
        $s = $v[''];
173
        $this->assertEquals(1, $s->scalarval());
174
    }
175
176
    public function testUnicodeInMemberName()
177
    {
178
        $str = "G" . chr(252) . "nter, El" . chr(232) . "ne";
179
        $v = array($str => new xmlrpcval(1));
180
        $r = new xmlrpcresp(new xmlrpcval($v, 'struct'));
181
        $r = $r->serialize();
182
        $m = $this->newRequest('dummy');
183
        $r = $m->parseResponse($r);
184
        $v = $r->value();
185
        $this->assertEquals(true, $v->structmemexists($str));
186
    }
187
188
    public function testUnicodeInErrorString()
189
    {
190
        // the warning suppression is due to utf8_decode being deprecated in php 8.2
191
        $response = @utf8_encode(
192
            '<?xml version="1.0"?>
193
<!-- covers what happens when lib receives UTF8 chars in response text and comments -->
194
<!-- ' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232; -->
195
<methodResponse>
196
<fault>
197
<value>
198
<struct>
199
<member>
200
<name>faultCode</name>
201
<value><int>888</int></value>
202
</member>
203
<member>
204
<name>faultString</name>
205
<value><string>' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232;</string></value>
206
</member>
207
</struct>
208
</value>
209
</fault>
210
</methodResponse>');
211
        $m = $this->newRequest('dummy');
212
        $r = $m->parseResponse($response);
213
        $v = $r->faultString();
214
        $this->assertEquals(chr(224) . chr(252) . chr(232) . chr(224) . chr(252) . chr(232), $v);
215
    }
216
217
    public function testBrokenRequests()
218
    {
219
        $s = new xmlrpc_server();
220
221
        // omitting the 'methodName' tag: not tolerated by the lib anymore
222
        $f = '<?xml version="1.0"?>
223
<methodCall>
224
<params>
225
<value><string>system.methodHelp</string></value>
226
</params>
227
</methodCall>';
228
        $r = $s->parserequest($f);
229
        $this->assertEquals(15, $r->faultCode());
230
231
        // omitting the 'params' tag: not tolerated by the lib anymore
232
        $f = '<?xml version="1.0"?>
233
<methodCall>
234
<methodName>system.methodHelp</methodName>
235
<param>
236
<value><string>system.methodHelp</string></value>
237
</param>
238
</methodCall>';
239
        $r = $s->parserequest($f);
240
        $this->assertEquals(15, $r->faultCode());
241
242
        // omitting a 'param' tag
243
        $f = '<?xml version="1.0"?>
244
<methodCall>
245
<methodName>system.methodHelp</methodName>
246
<params>
247
<value><string>system.methodHelp</string></value>
248
</params>
249
</methodCall>';
250
        $r = $s->parserequest($f);
251
        $this->assertEquals(15, $r->faultCode());
252
253
        // omitting a 'value' tag
254
        $f = '<?xml version="1.0"?>
255
<methodCall>
256
<methodName>system.methodHelp</methodName>
257
<params>
258
<param><string>system.methodHelp</string></param>
259
</params>
260
</methodCall>';
261
        $r = $s->parserequest($f);
262
        $this->assertEquals(15, $r->faultCode());
263
    }
264
265
    public function testBrokenResponses()
266
    {
267
        $m = $this->newRequest('dummy');
268
269
        // omitting the 'params' tag: no more tolerated by the lib...
270
        $f = '<?xml version="1.0"?>
271
<methodResponse>
272
</methodResponse>';
273
        $r = $m->parseResponse($f);
274
        $this->assertEquals(2, $r->faultCode());
275
        $f = '<?xml version="1.0"?>
276
<methodResponse>
277
<param>
278
<value><string>system.methodHelp</string></value>
279
</param>
280
</methodResponse>';
281
        $r = $m->parseResponse($f);
282
        $this->assertEquals(2, $r->faultCode());
283
284
        // omitting the 'param' tag: no more tolerated by the lib...
285
        $f = '<?xml version="1.0"?>
286
<methodResponse>
287
<params>
288
</params>
289
</methodResponse>';
290
        $r = $m->parseResponse($f);
291
        $this->assertEquals(2, $r->faultCode());
292
        $f = '<?xml version="1.0"?>
293
<methodResponse>
294
<params>
295
<value><string>system.methodHelp</string></value>
296
</params>
297
</methodResponse>';
298
        $r = $m->parseResponse($f);
299
        $this->assertEquals(2, $r->faultCode());
300
301
        // omitting a 'value' tag: KO
302
        $f = '<?xml version="1.0"?>
303
<methodResponse>
304
<params>
305
<param><string>system.methodHelp</string></param>
306
</params>
307
</methodResponse>';
308
        $r = $m->parseResponse($f);
309
        $this->assertEquals(2, $r->faultCode());
310
311
        // having both 'params' and 'fault'
312
        $f = '<?xml version="1.0"?>
313
<methodResponse>
314
<params>
315
<param><value><string>system.methodHelp</string></value></param>
316
</params>
317
<fault><value><struct>
318
<member><name>faultCode</name><value><int>888</int></value></member>
319
<member><name>faultString</name><value><string>yolo</string></value></member>
320
</struct></value></fault>
321
</methodResponse>';
322
        $r = $m->parseResponse($f);
323
        $this->assertEquals(2, $r->faultCode());
324
    }
325
326
    public function testBuggyXML()
327
    {
328
        $m = $this->newRequest('dummy');
329
        $r = $m->parseResponse("<\000\000\000\au\006");
330
        $this->assertEquals(2, $r->faultCode());
331
        //$this->assertStringContainsString('XML error', $r->faultString());
332
    }
333
334
    public function testBuggyHttp()
335
    {
336
        $s = $this->newRequest('dummy');
337
        $f = 'HTTP/1.1 100 Welcome to the jungle
338
339
HTTP/1.0 200 OK
340
X-Content-Marx-Brothers: Harpo
341
        Chico and Groucho
342
Content-Length: who knows?
343
344
345
346
<?xml version="1.0"?>
347
<!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... -->
348
<methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
349
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
350
351
352
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
353
<script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script>
354
 ';
355
        $r = $s->parseResponse($f);
356
        $v = $r->value();
357
        $s = $v->structmem('content');
358
        $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
359
    }
360
361
    public function testStringBug()
362
    {
363
        $s = $this->newRequest('dummy');
364
        $f = '<?xml version="1.0"?>
365
<!-- found by [email protected], amongst others covers what happens when there\'s character data after </string>
366
 and before </value> -->
367
<methodResponse>
368
<params>
369
<param>
370
<value>
371
<struct>
372
<member>
373
<name>success</name>
374
<value>
375
<boolean>1</boolean>
376
</value>
377
</member>
378
<member>
379
<name>sessionID</name>
380
<value>
381
<string>S300510007I</string>
382
</value>
383
</member>
384
</struct>
385
</value>
386
</param>
387
</params>
388
</methodResponse> ';
389
        $r = $s->parseResponse($f);
390
        $v = $r->value();
391
        $s = $v->structmem('sessionID');
392
        $this->assertEquals('S300510007I', $s->scalarval());
393
    }
394
395
    public function testBase64()
396
    {
397
        $s = $this->newRequest('dummy');
398
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><base64>
399
aGk=
400
</base64></value></param></params></methodResponse> ';
401
        $r = $s->parseResponse($f);
402
        $v = $r->value();
403
        $this->assertEquals('hi', $v->scalarval());
404
    }
405
406
    public function testInvalidValues()
407
    {
408
        $s = $this->newRequest('dummy');
409
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct>
410
<member>
411
<name>bool</name>
412
<value><boolean>
413
yes
414
</boolean></value>
415
</member>
416
<member>
417
<name>double</name>
418
<value><double>
419
1.01
420
</double></value>
421
</member>
422
<member>
423
<name>int</name>
424
<value><int>
425
1
426
</int></value>
427
</member>
428
<member>
429
<name>date</name>
430
<value><dateTime.iso8601>
431
20011126T09:17:52
432
</dateTime.iso8601></value>
433
</member>
434
<member>
435
<name>base64</name>
436
<value><base64>
437
!
438
</base64></value>
439
</member>
440
</struct></value></param></params></methodResponse> ';
441
        $r = $s->parseResponse($f);
442
        $v = $r->value();
443
        // NB: this is the status-quo of the xml parser, rather than something we want the library to always be returning...
444
        $this->assertEquals(false, $v['bool']->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

444
        $this->assertEquals(false, $v['bool']->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
445
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['double']->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

445
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['double']->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
446
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['int']->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

446
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['int']->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
447
        $this->assertEquals("\n20011126T09:17:52\n", $v['date']->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

447
        $this->assertEquals("\n20011126T09:17:52\n", $v['date']->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
448
        $this->assertEquals("", $v['base64']->scalarval());
0 ignored issues
show
The method scalarval() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

448
        $this->assertEquals("", $v['base64']->/** @scrutinizer ignore-call */ scalarval());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
449
    }
450
451
    public function testInvalidValuesStrictMode()
452
    {
453
        $s = $this->newRequest('dummy');
454
455
        $values = array(
456
            '<boolean>x</boolean>',
457
            '<double>x</double>',
458
            '<double>1..</double>',
459
            '<double>..1</double>',
460
            '<double>1.0.1</double>',
461
            '<int>x</int>',
462
            '<int>1.0</int>',
463
            '<dateTime.iso8601> 20011126T09:17:52</dateTime.iso8601>',
464
            '<dateTime.iso8601>20011126T09:17:52 </dateTime.iso8601>',
465
            '<base64>!</base64>'
466
        );
467
468
        $i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values;
469
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true;
470
471
        foreach($values as $value) {
472
            $f = '<?xml version="1.0"?><methodResponse><params><param><value>' . $value . '</value></param></params></methodResponse> ';
473
            $r = $s->parseResponse($f);
474
            $v = $r->faultCode();
475
            $this->assertEquals(2, $v, "Testing $value");
476
        }
477
478
        /// @todo move to tear_down(), so that we reset this even in case of test failure
479
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i;
480
    }
481
482
    public function testNewlines()
483
    {
484
        $s = $this->newRequest('dummy');
485
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
486
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
487
488
489
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
490
';
491
        $r = $s->parseResponse($f);
492
        $v = $r->value();
493
        $s = $v->structmem('content');
494
        $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
495
    }
496
497
    public function testDoubleDataInArrayTag()
498
    {
499
        $s = $this->newRequest('dummy');
500
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
501
<data></data>
502
<data></data>
503
</array></value></param></params></methodResponse>
504
';
505
        $r = $s->parseResponse($f);
506
        $v = $r->faultCode();
507
        $this->assertEquals(2, $v);
508
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
509
<data><value>Hello world</value></data>
510
<data></data>
511
</array></value></param></params></methodResponse>
512
';
513
        $r = $s->parseResponse($f);
514
        $v = $r->faultCode();
515
        $this->assertEquals(2, $v);
516
    }
517
518
    public function testDoubleStuffInValueTag()
519
    {
520
        $s = $this->newRequest('dummy');
521
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
522
<string>hello world</string>
523
<array><data></data></array>
524
</value></param></params></methodResponse>
525
';
526
        $r = $s->parseResponse($f);
527
        $v = $r->faultCode();
528
        $this->assertEquals(2, $v);
529
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
530
<string>hello</string>
531
<string>world</string>
532
</value></param></params></methodResponse>
533
';
534
        $r = $s->parseResponse($f);
535
        $v = $r->faultCode();
536
        $this->assertEquals(2, $v);
537
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
538
<string>hello</string>
539
<struct><member><name>hello><value>world</value></member></struct>
540
</value></param></params></methodResponse>
541
';
542
        $r = $s->parseResponse($f);
543
        $v = $r->faultCode();
544
        $this->assertEquals(2, $v);
545
    }
546
547
    public function testAutoDecodeResponse()
548
    {
549
        $s = $this->newRequest('dummy');
550
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
551
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 3 newlines follow
552
553
554
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
555
';
556
        $r = $s->parseResponse($f, true, 'phpvals');
557
        $v = $r->value();
558
        $s = $v['content'];
559
        $this->assertEquals("hello world. 3 newlines follow\n\n\nand there they were.", $s);
560
    }
561
562
    public function testNoDecodeResponse()
563
    {
564
        $s = $this->newRequest('dummy');
565
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
566
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 3 newlines follow
567
568
569
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>';
570
        $r = $s->parseResponse($f, true, 'xml');
571
        $v = $r->value();
572
        $this->assertEquals($f, $v);
573
    }
574
575
    public function testUTF8Response()
576
    {
577
        $string = chr(224) . chr(252) . chr(232);
578
579
        $s = $this->newRequest('dummy');
580
        $f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=UTF-8\r\n\r\n" . '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
581
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . @utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
582
';
583
        $r = $s->parseResponse($f, false, 'phpvals');
584
        $v = $r->value();
585
        $v = $v['content'];
586
        $this->assertEquals($string, $v);
587
588
        $f = '<?xml version="1.0" encoding="UTF-8"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
589
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . @utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
590
';
591
        $r = $s->parseResponse($f, false, 'phpvals');
592
        $v = $r->value();
593
        $v = $v['content'];
594
        $this->assertEquals($string, $v);
595
596
        /// @todo move to EncoderTest
597
        $r = php_xmlrpc_decode_xml($f);
598
        $v = $r->value();
0 ignored issues
show
The method value() does not exist on PhpXmlRpc\Request. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

598
        /** @scrutinizer ignore-call */ 
599
        $v = $r->value();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method value() does not exist on PhpXmlRpc\Value. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

598
        /** @scrutinizer ignore-call */ 
599
        $v = $r->value();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
599
        $v = $v->structmem('content')->scalarval();
600
        $this->assertEquals($string, $v);
601
    }
602
603
    public function testLatin1Response()
604
    {
605
        $string = chr(224) . chr(252) . chr(232);
606
607
        $s = $this->newRequest('dummy');
608
        $f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=ISO-8859-1\r\n\r\n" . '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
609
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
610
';
611
        $r = $s->parseResponse($f, false, 'phpvals');
612
        $v = $r->value();
613
        $v = $v['content'];
614
        $this->assertEquals($string, $v);
615
616
        $f = '<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
617
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
618
';
619
        $r = $s->parseResponse($f, false, 'phpvals');
620
        $v = $r->value();
621
        $v = $v['content'];
622
        $this->assertEquals($string, $v);
623
624
        /// @todo move to EncoderTest
625
        $r = php_xmlrpc_decode_xml($f);
626
        $v = $r->value();
627
        $v = $v->structmem('content')->scalarval();
628
        $this->assertEquals($string, $v);
629
    }
630
631
    public function testDatetimeAsObject()
632
    {
633
        $s = $this->newRequest('dummy');
634
        $f = '<?xml version="1.0"?>
635
<methodResponse><params><param><value>
636
<dateTime.iso8601>20011126T09:17:52</dateTime.iso8601>
637
</value></param></params></methodResponse>';
638
639
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
640
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
641
642
        $r = $s->parseResponse($f);
643
        $v = $r->value();
644
        $this->assertInstanceOf('\DateTime', $v->scalarval());
645
646
        /// @todo move to tear_down(), so that we reset this even in case of test failure
647
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
648
    }
649
650
    public function testCustomDatetimeFormat()
651
    {
652
        $s = $this->newRequest('dummy');
653
        $f = '<?xml version="1.0"?>
654
<methodResponse><params><param><value>
655
<dateTime.iso8601>20011126T09:17:52+01:00</dateTime.iso8601>
656
</value></param></params></methodResponse>';
657
658
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
659
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
660
        $i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values;
661
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true;
662
663
        $r = $s->parseResponse($f);
664
        $v = $r->faultCode();
665
        $this->assertNotEquals(0, $v);
666
667
        $d = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format;
668
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = '/^([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-4]):([0-5][0-9]):([0-5][0-9]|60)(Z|[+-][0-9]{2}(:?[0-9]{2})?)?$/';
669
670
        $r = $s->parseResponse($f);
671
        $v = $r->value();
672
        $this->assertInstanceOf('\DateTime', $v->scalarval());
673
674
        /// @todo move to tear_down(), so that we reset these even in case of test failure
675
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
676
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i;
677
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = $d;
678
    }
679
680
    /// @todo can we change this test to purely using the Value class ?
681
    /// @todo move test to its own class
682
    public function testNilSupport()
683
    {
684
        // default case: we do not accept nil values received
685
        $v = new xmlrpcval('hello', 'null');
686
        $r = new xmlrpcresp($v);
687
        $s = $r->serialize();
688
        $m = $this->newRequest('dummy');
689
        $r = $m->parseresponse($s);
690
        $this->assertequals(2, $r->faultCode());
691
        // enable reception of nil values
692
        $GLOBALS['xmlrpc_null_extension'] = true;
693
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
694
        $r = $m->parseresponse($s);
695
        $v = $r->value();
696
        $this->assertequals('null', $v->scalartyp());
697
        // test with the apache version: EX:NIL
698
        $GLOBALS['xmlrpc_null_apache_encoding'] = true;
699
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
700
        // serialization
701
        $v = new xmlrpcval('hello', 'null');
702
        $s = $v->serialize();
703
        $this->assertequals(1, preg_match('#<value><ex:nil/></value>#', $s));
704
        // deserialization
705
        $r = new xmlrpcresp($v);
706
        $s = $r->serialize();
707
        $r = $m->parseresponse($s);
708
        $v = $r->value();
709
        $this->assertequals('null', $v->scalartyp());
710
        $GLOBALS['xmlrpc_null_extension'] = false;
711
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
712
        $r = $m->parseresponse($s);
713
        $this->assertequals(2, $r->faultCode());
714
    }
715
716
    public function testXXE()
717
    {
718
        $xml = '<?xml version="1.0" encoding="UTF-8"?>
719
<!DOCTYPE foo [
720
    <!ENTITY xxe SYSTEM "https://www.google.com/favicon.ico">
721
]>
722
<methodResponse>
723
    <params>
724
        <param>
725
            <value><string>&xxe;</string></value>
726
        </param>
727
    </params>
728
</methodResponse>
729
';
730
        $req = new \PhpXmlRpc\Request('hi');
731
        $resp = $req->parseResponse($xml, true);
732
        $val = $resp->value();
733
        if (version_compare(PHP_VERSION, '5.6.0', '>=')) {
734
            $this->assertequals('', $val->scalarVal());
735
        } else {
736
            $this->assertequals('&xxe;', $val->scalarVal());
737
        }
738
    }
739
}
740