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
|
|
|
return; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$m = $this->newRequest('dummy'); |
110
|
|
|
$fp = |
111
|
|
|
'<?xml version="1.0"?> |
112
|
|
|
<methodResponse> |
113
|
|
|
<params> |
114
|
|
|
<param> |
115
|
|
|
<value> |
116
|
|
|
<struct> |
117
|
|
|
<member> |
118
|
|
|
<name>integer1</name> |
119
|
|
|
<value><i8>1</i8></value> |
120
|
|
|
</member> |
121
|
|
|
<member> |
122
|
|
|
<name>integer2</name> |
123
|
|
|
<value><ex:i8>1</ex:i8></value> |
124
|
|
|
</member> |
125
|
|
|
</struct> |
126
|
|
|
</value> |
127
|
|
|
</param> |
128
|
|
|
</params> |
129
|
|
|
</methodResponse>'; |
130
|
|
|
$r = $m->parseResponse($fp); |
131
|
|
|
$v = $r->value(); |
132
|
|
|
$s = $v->structmem('integer1'); |
|
|
|
|
133
|
|
|
$this->assertEquals(1, $s->scalarval()); |
134
|
|
|
$s = $v->structmem('integer2'); |
|
|
|
|
135
|
|
|
$this->assertEquals(1, $s->scalarval()); |
136
|
|
|
$this->assertEquals('i8', $s->scalartyp()); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
// struct with value before name, with no name, with no value, etc... |
140
|
|
|
public function testQuirkyStruct() |
141
|
|
|
{ |
142
|
|
|
$m = $this->newRequest('dummy'); |
143
|
|
|
$fp = |
144
|
|
|
'<?xml version="1.0"?> |
145
|
|
|
<methodResponse> |
146
|
|
|
<params> |
147
|
|
|
<param> |
148
|
|
|
<value> |
149
|
|
|
<struct> |
150
|
|
|
<member> |
151
|
|
|
<value><int>1</int></value> |
152
|
|
|
<name>Gollum</name> |
153
|
|
|
</member> |
154
|
|
|
<member> |
155
|
|
|
<name>Bilbo</name> |
156
|
|
|
</member> |
157
|
|
|
<member> |
158
|
|
|
<value><int>9</int></value> |
159
|
|
|
</member> |
160
|
|
|
<member> |
161
|
|
|
<value><int>1</int></value> |
162
|
|
|
</member> |
163
|
|
|
</struct> |
164
|
|
|
</value> |
165
|
|
|
</param> |
166
|
|
|
</params> |
167
|
|
|
</methodResponse>'; |
168
|
|
|
$r = $m->parseResponse($fp); |
169
|
|
|
$v = $r->value(); |
170
|
|
|
$this->assertEquals(2, count($v)); |
|
|
|
|
171
|
|
|
$s = $v['Gollum']; |
172
|
|
|
$this->assertEquals(1, $s->scalarval()); |
|
|
|
|
173
|
|
|
$s = $v['']; |
174
|
|
|
$this->assertEquals(1, $s->scalarval()); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
public function testUnicodeInMemberName() |
178
|
|
|
{ |
179
|
|
|
$str = "G" . chr(252) . "nter, El" . chr(232) . "ne"; |
180
|
|
|
$v = array($str => new xmlrpcval(1)); |
181
|
|
|
$r = new xmlrpcresp(new xmlrpcval($v, 'struct')); |
182
|
|
|
$r = $r->serialize(); |
183
|
|
|
$m = $this->newRequest('dummy'); |
184
|
|
|
$r = $m->parseResponse($r); |
185
|
|
|
$v = $r->value(); |
186
|
|
|
$this->assertEquals(true, $v->structmemexists($str)); |
|
|
|
|
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
public function testUnicodeInErrorString() |
190
|
|
|
{ |
191
|
|
|
// the warning suppression is due to utf8_decode being deprecated in php 8.2 |
192
|
|
|
$response = @utf8_encode( |
193
|
|
|
'<?xml version="1.0"?> |
194
|
|
|
<!-- covers what happens when lib receives UTF8 chars in response text and comments --> |
195
|
|
|
<!-- ' . chr(224) . chr(252) . chr(232) . 'àüè --> |
196
|
|
|
<methodResponse> |
197
|
|
|
<fault> |
198
|
|
|
<value> |
199
|
|
|
<struct> |
200
|
|
|
<member> |
201
|
|
|
<name>faultCode</name> |
202
|
|
|
<value><int>888</int></value> |
203
|
|
|
</member> |
204
|
|
|
<member> |
205
|
|
|
<name>faultString</name> |
206
|
|
|
<value><string>' . chr(224) . chr(252) . chr(232) . 'àüè</string></value> |
207
|
|
|
</member> |
208
|
|
|
</struct> |
209
|
|
|
</value> |
210
|
|
|
</fault> |
211
|
|
|
</methodResponse>'); |
212
|
|
|
$m = $this->newRequest('dummy'); |
213
|
|
|
$r = $m->parseResponse($response); |
214
|
|
|
$v = $r->faultString(); |
215
|
|
|
$this->assertEquals(chr(224) . chr(252) . chr(232) . chr(224) . chr(252) . chr(232), $v); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
public function testBrokenRequests() |
219
|
|
|
{ |
220
|
|
|
$s = new xmlrpc_server(); |
221
|
|
|
|
222
|
|
|
// omitting the 'methodName' tag: not tolerated by the lib anymore |
223
|
|
|
$f = '<?xml version="1.0"?> |
224
|
|
|
<methodCall> |
225
|
|
|
<params> |
226
|
|
|
<value><string>system.methodHelp</string></value> |
227
|
|
|
</params> |
228
|
|
|
</methodCall>'; |
229
|
|
|
$r = $s->parserequest($f); |
230
|
|
|
$this->assertEquals(15, $r->faultCode()); |
231
|
|
|
|
232
|
|
|
// omitting the 'params' tag: not tolerated by the lib anymore |
233
|
|
|
$f = '<?xml version="1.0"?> |
234
|
|
|
<methodCall> |
235
|
|
|
<methodName>system.methodHelp</methodName> |
236
|
|
|
<param> |
237
|
|
|
<value><string>system.methodHelp</string></value> |
238
|
|
|
</param> |
239
|
|
|
</methodCall>'; |
240
|
|
|
$r = $s->parserequest($f); |
241
|
|
|
$this->assertEquals(15, $r->faultCode()); |
242
|
|
|
|
243
|
|
|
// omitting a 'param' tag |
244
|
|
|
$f = '<?xml version="1.0"?> |
245
|
|
|
<methodCall> |
246
|
|
|
<methodName>system.methodHelp</methodName> |
247
|
|
|
<params> |
248
|
|
|
<value><string>system.methodHelp</string></value> |
249
|
|
|
</params> |
250
|
|
|
</methodCall>'; |
251
|
|
|
$r = $s->parserequest($f); |
252
|
|
|
$this->assertEquals(15, $r->faultCode()); |
253
|
|
|
|
254
|
|
|
// omitting a 'value' tag |
255
|
|
|
$f = '<?xml version="1.0"?> |
256
|
|
|
<methodCall> |
257
|
|
|
<methodName>system.methodHelp</methodName> |
258
|
|
|
<params> |
259
|
|
|
<param><string>system.methodHelp</string></param> |
260
|
|
|
</params> |
261
|
|
|
</methodCall>'; |
262
|
|
|
$r = $s->parserequest($f); |
263
|
|
|
$this->assertEquals(15, $r->faultCode()); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
public function testBrokenResponses() |
267
|
|
|
{ |
268
|
|
|
$m = $this->newRequest('dummy'); |
269
|
|
|
|
270
|
|
|
// omitting the 'params' tag: no more tolerated by the lib... |
271
|
|
|
$f = '<?xml version="1.0"?> |
272
|
|
|
<methodResponse> |
273
|
|
|
</methodResponse>'; |
274
|
|
|
$r = $m->parseResponse($f); |
275
|
|
|
$this->assertEquals(2, $r->faultCode()); |
276
|
|
|
$f = '<?xml version="1.0"?> |
277
|
|
|
<methodResponse> |
278
|
|
|
<param> |
279
|
|
|
<value><string>system.methodHelp</string></value> |
280
|
|
|
</param> |
281
|
|
|
</methodResponse>'; |
282
|
|
|
$r = $m->parseResponse($f); |
283
|
|
|
$this->assertEquals(2, $r->faultCode()); |
284
|
|
|
|
285
|
|
|
// omitting the 'param' tag: no more tolerated by the lib... |
286
|
|
|
$f = '<?xml version="1.0"?> |
287
|
|
|
<methodResponse> |
288
|
|
|
<params> |
289
|
|
|
</params> |
290
|
|
|
</methodResponse>'; |
291
|
|
|
$r = $m->parseResponse($f); |
292
|
|
|
$this->assertEquals(2, $r->faultCode()); |
293
|
|
|
$f = '<?xml version="1.0"?> |
294
|
|
|
<methodResponse> |
295
|
|
|
<params> |
296
|
|
|
<value><string>system.methodHelp</string></value> |
297
|
|
|
</params> |
298
|
|
|
</methodResponse>'; |
299
|
|
|
$r = $m->parseResponse($f); |
300
|
|
|
$this->assertEquals(2, $r->faultCode()); |
301
|
|
|
|
302
|
|
|
// omitting a 'value' tag: KO |
303
|
|
|
$f = '<?xml version="1.0"?> |
304
|
|
|
<methodResponse> |
305
|
|
|
<params> |
306
|
|
|
<param><string>system.methodHelp</string></param> |
307
|
|
|
</params> |
308
|
|
|
</methodResponse>'; |
309
|
|
|
$r = $m->parseResponse($f); |
310
|
|
|
$this->assertEquals(2, $r->faultCode()); |
311
|
|
|
|
312
|
|
|
// having both 'params' and 'fault' |
313
|
|
|
$f = '<?xml version="1.0"?> |
314
|
|
|
<methodResponse> |
315
|
|
|
<params> |
316
|
|
|
<param><value><string>system.methodHelp</string></value></param> |
317
|
|
|
</params> |
318
|
|
|
<fault><value><struct> |
319
|
|
|
<member><name>faultCode</name><value><int>888</int></value></member> |
320
|
|
|
<member><name>faultString</name><value><string>yolo</string></value></member> |
321
|
|
|
</struct></value></fault> |
322
|
|
|
</methodResponse>'; |
323
|
|
|
$r = $m->parseResponse($f); |
324
|
|
|
$this->assertEquals(2, $r->faultCode()); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
public function testBuggyXML() |
328
|
|
|
{ |
329
|
|
|
$m = $this->newRequest('dummy'); |
330
|
|
|
$r = $m->parseResponse("<\000\000\000\au\006"); |
331
|
|
|
$this->assertEquals(2, $r->faultCode()); |
332
|
|
|
//$this->assertStringContainsString('XML error', $r->faultString()); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
public function testBuggyHttp() |
336
|
|
|
{ |
337
|
|
|
$s = $this->newRequest('dummy'); |
338
|
|
|
$f = 'HTTP/1.1 100 Welcome to the jungle |
339
|
|
|
|
340
|
|
|
HTTP/1.0 200 OK |
341
|
|
|
X-Content-Marx-Brothers: Harpo |
342
|
|
|
Chico and Groucho |
343
|
|
|
Content-Length: who knows? |
344
|
|
|
|
345
|
|
|
|
346
|
|
|
|
347
|
|
|
<?xml version="1.0"?> |
348
|
|
|
<!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... --> |
349
|
|
|
<methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member> |
350
|
|
|
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow |
351
|
|
|
|
352
|
|
|
|
353
|
|
|
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse> |
354
|
|
|
<script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script> |
355
|
|
|
'; |
356
|
|
|
$r = $s->parseResponse($f); |
357
|
|
|
$v = $r->value(); |
358
|
|
|
$s = $v->structmem('content'); |
|
|
|
|
359
|
|
|
$this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval()); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
public function testStringBug() |
363
|
|
|
{ |
364
|
|
|
$s = $this->newRequest('dummy'); |
365
|
|
|
$f = '<?xml version="1.0"?> |
366
|
|
|
<!-- found by [email protected], amongst others covers what happens when there\'s character data after </string> |
367
|
|
|
and before </value> --> |
368
|
|
|
<methodResponse> |
369
|
|
|
<params> |
370
|
|
|
<param> |
371
|
|
|
<value> |
372
|
|
|
<struct> |
373
|
|
|
<member> |
374
|
|
|
<name>success</name> |
375
|
|
|
<value> |
376
|
|
|
<boolean>1</boolean> |
377
|
|
|
</value> |
378
|
|
|
</member> |
379
|
|
|
<member> |
380
|
|
|
<name>sessionID</name> |
381
|
|
|
<value> |
382
|
|
|
<string>S300510007I</string> |
383
|
|
|
</value> |
384
|
|
|
</member> |
385
|
|
|
</struct> |
386
|
|
|
</value> |
387
|
|
|
</param> |
388
|
|
|
</params> |
389
|
|
|
</methodResponse> '; |
390
|
|
|
$r = $s->parseResponse($f); |
391
|
|
|
$v = $r->value(); |
392
|
|
|
$s = $v->structmem('sessionID'); |
|
|
|
|
393
|
|
|
$this->assertEquals('S300510007I', $s->scalarval()); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
public function testBase64() |
397
|
|
|
{ |
398
|
|
|
$s = $this->newRequest('dummy'); |
399
|
|
|
$f = '<?xml version="1.0"?><methodResponse><params><param><value><base64> |
400
|
|
|
aGk= |
401
|
|
|
</base64></value></param></params></methodResponse> '; |
402
|
|
|
$r = $s->parseResponse($f); |
403
|
|
|
$v = $r->value(); |
404
|
|
|
$this->assertEquals('hi', $v->scalarval()); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
public function testInvalidValues() |
408
|
|
|
{ |
409
|
|
|
$s = $this->newRequest('dummy'); |
410
|
|
|
$f = '<?xml version="1.0"?><methodResponse><params><param><value><struct> |
411
|
|
|
<member> |
412
|
|
|
<name>bool</name> |
413
|
|
|
<value><boolean> |
414
|
|
|
yes |
415
|
|
|
</boolean></value> |
416
|
|
|
</member> |
417
|
|
|
<member> |
418
|
|
|
<name>double</name> |
419
|
|
|
<value><double> |
420
|
|
|
1.01 |
421
|
|
|
</double></value> |
422
|
|
|
</member> |
423
|
|
|
<member> |
424
|
|
|
<name>int</name> |
425
|
|
|
<value><int> |
426
|
|
|
1 |
427
|
|
|
</int></value> |
428
|
|
|
</member> |
429
|
|
|
<member> |
430
|
|
|
<name>date</name> |
431
|
|
|
<value><dateTime.iso8601> |
432
|
|
|
20011126T09:17:52 |
433
|
|
|
</dateTime.iso8601></value> |
434
|
|
|
</member> |
435
|
|
|
<member> |
436
|
|
|
<name>base64</name> |
437
|
|
|
<value><base64> |
438
|
|
|
! |
439
|
|
|
</base64></value> |
440
|
|
|
</member> |
441
|
|
|
</struct></value></param></params></methodResponse> '; |
442
|
|
|
$r = $s->parseResponse($f); |
443
|
|
|
$v = $r->value(); |
444
|
|
|
// NB: this is the status-quo of the xml parser, rather than something we want the library to always be returning... |
445
|
|
|
$this->assertEquals(false, $v['bool']->scalarval()); |
|
|
|
|
446
|
|
|
$this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['double']->scalarval()); |
|
|
|
|
447
|
|
|
$this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['int']->scalarval()); |
|
|
|
|
448
|
|
|
$this->assertEquals("\n20011126T09:17:52\n", $v['date']->scalarval()); |
|
|
|
|
449
|
|
|
$this->assertEquals("", $v['base64']->scalarval()); |
|
|
|
|
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
public function testInvalidValuesStrictMode() |
453
|
|
|
{ |
454
|
|
|
$s = $this->newRequest('dummy'); |
455
|
|
|
|
456
|
|
|
$values = array( |
457
|
|
|
'<boolean>x</boolean>', |
458
|
|
|
'<double>x</double>', |
459
|
|
|
'<double>1..</double>', |
460
|
|
|
'<double>..1</double>', |
461
|
|
|
'<double>1.0.1</double>', |
462
|
|
|
'<int>x</int>', |
463
|
|
|
'<int>1.0</int>', |
464
|
|
|
'<dateTime.iso8601> 20011126T09:17:52</dateTime.iso8601>', |
465
|
|
|
'<dateTime.iso8601>20011126T09:17:52 </dateTime.iso8601>', |
466
|
|
|
'<base64>!</base64>' |
467
|
|
|
); |
468
|
|
|
|
469
|
|
|
$i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values; |
470
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true; |
471
|
|
|
|
472
|
|
|
foreach($values as $value) { |
473
|
|
|
$f = '<?xml version="1.0"?><methodResponse><params><param><value>' . $value . '</value></param></params></methodResponse> '; |
474
|
|
|
$r = $s->parseResponse($f); |
475
|
|
|
$v = $r->faultCode(); |
476
|
|
|
$this->assertEquals(2, $v, "Testing $value"); |
477
|
|
|
} |
478
|
|
|
|
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(); |
|
|
|
|
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
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o; |
647
|
|
|
} |
648
|
|
|
|
649
|
|
|
public function testCustomDatetimeFormat() |
650
|
|
|
{ |
651
|
|
|
$s = $this->newRequest('dummy'); |
652
|
|
|
$f = '<?xml version="1.0"?> |
653
|
|
|
<methodResponse><params><param><value> |
654
|
|
|
<dateTime.iso8601>20011126T09:17:52+01:00</dateTime.iso8601> |
655
|
|
|
</value></param></params></methodResponse>'; |
656
|
|
|
|
657
|
|
|
$o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes; |
658
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true; |
659
|
|
|
$i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values; |
660
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true; |
661
|
|
|
|
662
|
|
|
$r = $s->parseResponse($f); |
663
|
|
|
$v = $r->faultCode(); |
664
|
|
|
$this->assertNotEquals(0, $v); |
665
|
|
|
|
666
|
|
|
$d = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format; |
667
|
|
|
\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})?)?$/'; |
668
|
|
|
|
669
|
|
|
$r = $s->parseResponse($f); |
670
|
|
|
$v = $r->value(); |
671
|
|
|
$this->assertInstanceOf('\DateTime', $v->scalarval()); |
672
|
|
|
|
673
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o; |
674
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i; |
675
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = $d; |
676
|
|
|
} |
677
|
|
|
|
678
|
|
|
/// @todo can we change this test to purely using the Value class ? |
679
|
|
|
/// @todo move test to its own class |
680
|
|
|
public function testNilSupport() |
681
|
|
|
{ |
682
|
|
|
// default case: we do not accept nil values received |
683
|
|
|
$v = new xmlrpcval('hello', 'null'); |
684
|
|
|
$r = new xmlrpcresp($v); |
685
|
|
|
$s = $r->serialize(); |
686
|
|
|
$m = $this->newRequest('dummy'); |
687
|
|
|
$r = $m->parseresponse($s); |
688
|
|
|
$this->assertequals(2, $r->faultCode()); |
689
|
|
|
// enable reception of nil values |
690
|
|
|
$GLOBALS['xmlrpc_null_extension'] = true; |
691
|
|
|
\PhpXmlRpc\PhpXmlRpc::importGlobals(); |
|
|
|
|
692
|
|
|
$r = $m->parseresponse($s); |
693
|
|
|
$v = $r->value(); |
694
|
|
|
$this->assertequals('null', $v->scalartyp()); |
695
|
|
|
// test with the apache version: EX:NIL |
696
|
|
|
$GLOBALS['xmlrpc_null_apache_encoding'] = true; |
697
|
|
|
\PhpXmlRpc\PhpXmlRpc::importGlobals(); |
|
|
|
|
698
|
|
|
// serialization |
699
|
|
|
$v = new xmlrpcval('hello', 'null'); |
700
|
|
|
$s = $v->serialize(); |
701
|
|
|
$this->assertequals(1, preg_match('#<value><ex:nil/></value>#', $s)); |
702
|
|
|
// deserialization |
703
|
|
|
$r = new xmlrpcresp($v); |
704
|
|
|
$s = $r->serialize(); |
705
|
|
|
$r = $m->parseresponse($s); |
706
|
|
|
$v = $r->value(); |
707
|
|
|
$this->assertequals('null', $v->scalartyp()); |
708
|
|
|
$GLOBALS['xmlrpc_null_extension'] = false; |
709
|
|
|
\PhpXmlRpc\PhpXmlRpc::importGlobals(); |
|
|
|
|
710
|
|
|
$r = $m->parseresponse($s); |
711
|
|
|
$this->assertequals(2, $r->faultCode()); |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
public function testXXE() |
715
|
|
|
{ |
716
|
|
|
$xml = '<?xml version="1.0" encoding="UTF-8"?> |
717
|
|
|
<!DOCTYPE foo [ |
718
|
|
|
<!ENTITY xxe SYSTEM "https://www.google.com/favicon.ico"> |
719
|
|
|
]> |
720
|
|
|
<methodResponse> |
721
|
|
|
<params> |
722
|
|
|
<param> |
723
|
|
|
<value><string>&xxe;</string></value> |
724
|
|
|
</param> |
725
|
|
|
</params> |
726
|
|
|
</methodResponse> |
727
|
|
|
'; |
728
|
|
|
$req = new \PhpXmlRpc\Request('hi'); |
729
|
|
|
$resp = $req->parseResponse($xml, true); |
730
|
|
|
$val = $resp->value(); |
731
|
|
|
$this->assertequals('', $val->scalarVal()); |
732
|
|
|
} |
733
|
|
|
} |
734
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.