initial load of upstream version 1.06.32
[xmlrpc-c] / src / test / parse_xml.c
1 #include <limits.h>
2 #include <stdlib.h>
3
4 #include "xmlrpc_config.h"
5
6 #include "girstring.h"
7 #include "casprintf.h"
8 #include "xmlrpc-c/base.h"
9 #include "xmlrpc-c/xmlparser.h"
10
11 #include "test.h"
12 #include "xml_data.h"
13 #include "parse_xml.h"
14
15
16
17 static void test_expat (void)
18 {
19     xmlrpc_env env;
20     xml_element *elem, *array, *data, *value1, *i4;
21     char *cdata;
22     size_t size;
23
24     xmlrpc_env_init(&env);
25
26     /* Parse a moderately complex XML document. */
27     xml_parse(&env, expat_data, strlen(expat_data), &elem);
28     TEST_NO_FAULT(&env);
29     TEST(elem != NULL);
30
31     /* Verify our results. */
32     TEST(streq(xml_element_name(elem), "value"));
33     TEST(xml_element_children_size(elem) == 1);
34     array = xml_element_children(elem)[0];
35     TEST(streq(xml_element_name(array), "array"));
36     TEST(xml_element_children_size(array) == 1);
37     data = xml_element_children(array)[0];
38     TEST(streq(xml_element_name(data), "data"));
39     TEST(xml_element_children_size(data) > 1);
40     value1 = xml_element_children(data)[0];
41     TEST(streq(xml_element_name(value1), "value"));
42     TEST(xml_element_children_size(value1) == 1);
43     i4 = xml_element_children(value1)[0];
44     TEST(streq(xml_element_name(i4), "i4"));
45     TEST(xml_element_children_size(i4) == 0);
46     cdata = xml_element_cdata(i4);
47     size = xml_element_cdata_size(i4);
48     TEST(size == strlen("2147483647"));
49     TEST(memcmp(cdata, "2147483647", strlen("2147483647")) == 0);
50
51     /* Test cleanup code (w/memprof). */
52     xml_element_free(elem);
53
54     /* Test broken XML */
55     xml_parse(&env, expat_error_data, strlen(expat_error_data), &elem);
56     TEST(env.fault_occurred);
57
58     xmlrpc_env_clean(&env);
59 }
60
61
62
63 static void
64 validateParseResponseResult(xmlrpc_value * const valueP) {
65
66     xmlrpc_env env;
67
68     xmlrpc_value * s;
69     xmlrpc_int32 int_max;
70     xmlrpc_int32 int_min;
71     xmlrpc_int32 int_one;
72     xmlrpc_bool bool_false;
73     xmlrpc_bool bool_true;
74     char * str_hello;
75     char * str_untagged;
76     char * datetime;
77     unsigned char * b64_data;
78     size_t b64_len;
79     double negone;
80     double zero;
81     double one;
82
83     xmlrpc_env_init(&env);
84
85     xmlrpc_decompose_value(
86         &env, valueP, "((iibbs68())idddSs)", 
87         &int_max, &int_min,
88         &bool_false, &bool_true, &str_hello,
89         &b64_data, &b64_len, &datetime,
90         &int_one, &negone, &zero, &one, &s, &str_untagged);
91
92     TEST_NO_FAULT(&env);
93     TEST(int_max == INT_MAX);
94     TEST(int_min == INT_MIN);
95     TEST(!bool_false);
96     TEST(bool_true);
97     TEST(strlen(str_hello) == strlen("Hello, world! <&>"));
98     TEST(streq(str_hello, "Hello, world! <&>"));
99     TEST(b64_len == 11);
100     TEST(memcmp(b64_data, "base64 data", b64_len) == 0);
101     TEST(streq(datetime, "19980717T14:08:55"));
102     TEST(int_one == 1);
103     TEST(negone == -1.0);
104     TEST(zero == 0.0);
105     TEST(one == 1.0);
106     TEST(streq(str_untagged, "Untagged string"));
107     free(str_hello);
108     free(b64_data);
109     free(datetime);
110     free(str_untagged);
111
112     {
113         /* Analyze the contents of our struct. */
114
115         xmlrpc_value * sval;
116         int size, sval_int;
117
118         TEST(s != NULL);
119         size = xmlrpc_struct_size(&env, s);
120         TEST_NO_FAULT(&env);
121         TEST(size == 2);
122         sval = xmlrpc_struct_get_value(&env, s, "ten <&>");
123         TEST_NO_FAULT(&env);
124         xmlrpc_decompose_value(&env, sval, "i", &sval_int);
125         TEST_NO_FAULT(&env);
126         TEST(sval_int == 10);
127         sval = xmlrpc_struct_get_value(&env, s, "twenty");
128         TEST_NO_FAULT(&env);
129         xmlrpc_decompose_value(&env, sval, "i", &sval_int);
130         TEST_NO_FAULT(&env);
131         TEST(sval_int == 20);
132         xmlrpc_DECREF(s);
133     }    
134
135     xmlrpc_env_clean(&env);
136 }
137
138
139
140 static void
141 testParseGoodResponse(void) {
142
143     xmlrpc_env env;
144     xmlrpc_value * valueP;
145     int faultCode;
146     const char * faultString;
147
148     xmlrpc_env_init(&env);
149
150     xmlrpc_parse_response2(&env, good_response_xml, strlen(good_response_xml),
151                            &valueP, &faultCode, &faultString);
152
153     TEST_NO_FAULT(&env);
154     TEST(faultString == NULL);
155
156     validateParseResponseResult(valueP);
157
158     xmlrpc_DECREF(valueP);
159
160     /* Try it again with old interface */
161
162     valueP = xmlrpc_parse_response(&env,
163                                    good_response_xml,
164                                    strlen(good_response_xml));
165     TEST_NO_FAULT(&env);
166     TEST(valueP != NULL);
167
168     validateParseResponseResult(valueP);
169
170     xmlrpc_DECREF(valueP);
171
172     xmlrpc_env_clean(&env);
173
174 }    
175
176
177
178 static void
179 testParseBadResponse(void) {
180 /*----------------------------------------------------------------------------
181    Test parsing of data that is supposed to be a response, but is not
182    valid.  Either not valid XML or not valid XML-RPC.
183 -----------------------------------------------------------------------------*/
184     unsigned int i;
185
186     {
187         xmlrpc_env env;
188         xmlrpc_value * valueP;
189         int faultCode;
190         const char * faultString;
191
192         /* First, test some poorly-formed XML data. */
193         xmlrpc_env_init(&env);
194        
195         xmlrpc_parse_response2(&env,
196                                unparseable_value, strlen(unparseable_value),
197                                &valueP, &faultCode, &faultString);
198         
199         TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
200         xmlrpc_env_clean(&env);
201
202         xmlrpc_env_init(&env);
203
204         /* And again with the old interface */
205         valueP = xmlrpc_parse_response(&env, unparseable_value,
206                                        strlen(unparseable_value));
207         TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
208         xmlrpc_env_clean(&env);
209         TEST(valueP == NULL);
210     }
211
212     /* Try with good XML, but bad XML-RPC.  For this test, we test up to
213        but not including the <value> in a successful RPC response.
214     */
215
216     /* Next, check for bogus responses. These are all well-formed XML, but
217     ** they aren't legal XML-RPC. */
218     for (i = 15; bad_responses[i] != NULL; ++i) {
219         const char * const bad_resp = bad_responses[i];
220         xmlrpc_env env;
221         xmlrpc_value * v;
222         xml_element *elem;
223
224         xmlrpc_env_init(&env);
225     
226         /* First, check to make sure that our test case is well-formed XML.
227         ** (It's easy to make mistakes when writing the test cases!) */
228         xml_parse(&env, bad_resp, strlen(bad_resp), &elem);
229         TEST_NO_FAULT(&env);
230         xml_element_free(elem);
231     
232         /* Now, make sure the higher-level routine barfs appropriately. */
233         v = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp));
234         TEST(env.fault_occurred);
235         TEST(env.fault_code != 0); /* We use 0 as a code in our bad faults. */
236         TEST(v == NULL);
237         xmlrpc_env_clean(&env);
238     }
239     
240     /* Try with good XML, good XML-RPC response, except that the value
241        isn't valid XML-RPC
242     */
243     for (i = 0; bad_values[i] != NULL; ++i) {
244         const char * const bad_resp = bad_values[i];
245         xmlrpc_env env;
246         xmlrpc_value * valueP;
247         xml_element *elem;
248         int faultCode;
249         const char * faultString;
250     
251         xmlrpc_env_init(&env);
252
253         /* First, check to make sure that our test case is well-formed XML.
254         ** (It's easy to make mistakes when writing the test cases!) */
255         xml_parse(&env, bad_resp, strlen(bad_resp), &elem);
256         TEST_NO_FAULT(&env);
257         xml_element_free(elem);
258     
259         /* Now, make sure the higher-level routine barfs appropriately. */
260         
261         xmlrpc_parse_response2(&env, bad_resp, strlen(bad_resp),
262                                &valueP, &faultCode, &faultString);
263
264         TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
265         xmlrpc_env_clean(&env);
266
267         xmlrpc_env_init(&env);
268
269         /* And again with the old interface */
270
271         valueP = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp));
272         TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
273         TEST(valueP == NULL);
274         xmlrpc_env_clean(&env);
275     }
276 }
277
278
279
280 static void
281 testParseFaultResponse(void) {
282 /*----------------------------------------------------------------------------
283    Test parsing of a valid response that indicates the RPC failed.
284 -----------------------------------------------------------------------------*/
285     xmlrpc_env env;
286
287     xmlrpc_env_init(&env);
288
289     {
290         xmlrpc_value * resultP;
291         int faultCode;
292         const char * faultString;
293             
294         xmlrpc_parse_response2(&env,
295                                serialized_fault, strlen(serialized_fault),
296                                &resultP, &faultCode, &faultString);
297
298         TEST_NO_FAULT(&env);
299         TEST(faultString != NULL);
300         TEST(faultCode == 6);
301         TEST(streq(faultString, "A fault occurred"));
302         strfree(faultString);
303     }
304     /* Now with the old interface */
305     {
306         xmlrpc_value * valueP;
307         xmlrpc_env fault;
308
309         /* Parse a valid fault. */
310         xmlrpc_env_init(&fault);
311         valueP = xmlrpc_parse_response(&fault, serialized_fault,
312                                        strlen(serialized_fault));
313
314         TEST(fault.fault_occurred);
315         TEST(fault.fault_code == 6);
316         TEST(streq(fault.fault_string, "A fault occurred"));
317         xmlrpc_env_clean(&fault);
318     }
319
320     xmlrpc_env_clean(&env);
321 }
322
323
324
325 static void
326 test_parse_xml_call(void) {
327
328     xmlrpc_env env;
329     const char *method_name;
330     xmlrpc_value *params;
331     int i1, i2;
332     const char **bad_call;
333     xml_element *elem;
334
335     xmlrpc_env_init(&env);
336
337     /* Parse a valid call. */
338     xmlrpc_parse_call(&env, serialized_call, strlen(serialized_call),
339                       &method_name, &params);
340     TEST_NO_FAULT(&env);
341     TEST(params != NULL);
342     xmlrpc_decompose_value(&env, params, "(ii)", &i1, &i2);
343     xmlrpc_DECREF(params);    
344     TEST_NO_FAULT(&env);
345     TEST(streq(method_name, "gloom&doom"));
346     TEST(i1 == 10 && i2 == 20);
347     strfree(method_name);
348
349     /* Test some poorly-formed XML data. */
350     xmlrpc_parse_call(&env, unparseable_value, strlen(unparseable_value),
351                       &method_name, &params);
352     TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
353     TEST(method_name == NULL && params == NULL);
354
355     /* Next, check for bogus values. These are all well-formed XML, but
356        they aren't legal XML-RPC.
357     */
358     for (bad_call = bad_calls; *bad_call != NULL; ++bad_call) {
359     
360         /* First, check to make sure that our test case is well-formed XML.
361         ** (It's easy to make mistakes when writing the test cases!) */
362         xml_parse(&env, *bad_call, strlen(*bad_call), &elem);
363         TEST_NO_FAULT(&env);
364         xml_element_free(elem);
365
366         /* Now, make sure the higher-level routine barfs appropriately. */
367         xmlrpc_parse_call(&env, *bad_call, strlen(*bad_call),
368                           &method_name, &params);
369         TEST_FAULT(&env, XMLRPC_PARSE_ERROR);
370         TEST(method_name == NULL && params == NULL);
371     }
372     xmlrpc_env_clean(&env);    
373 }
374
375
376
377 void
378 test_parse_xml(void) {
379
380     printf("Running XML parsing tests.\n");
381     test_expat();
382     testParseGoodResponse();
383     testParseFaultResponse();
384     testParseBadResponse();
385     test_parse_xml_call();
386     printf("\n");
387     printf("XML parsing tests done.\n");
388 }