Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Utilities / cmxmlrpc / xmlrpc_parse.c
blob0999eb6811d58a605d949791afae15e8be2444b9
1 /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
2 **
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
5 ** are met:
6 ** 1. Redistributions of source code must retain the above copyright
7 ** notice, this list of conditions and the following disclaimer.
8 ** 2. Redistributions in binary form must reproduce the above copyright
9 ** notice, this list of conditions and the following disclaimer in the
10 ** documentation and/or other materials provided with the distribution.
11 ** 3. The name of the author may not be used to endorse or promote products
12 ** derived from this software without specific prior written permission.
13 **
14 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 ** SUCH DAMAGE. */
26 #include "xmlrpc_config.h"
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <ctype.h>
34 #include "xmlrpc.h"
35 #include "xmlrpc_int.h"
36 #include "xmlrpc_xmlparser.h"
39 /*=========================================================================
40 ** Data Format
41 **=========================================================================
42 ** All XML-RPC documents contain a single methodCall or methodResponse
43 ** element.
45 ** methodCall methodName, params
46 ** methodResponse (params|fault)
47 ** params param*
48 ** param value
49 ** fault value
50 ** value (i4|int|boolean|string|double|dateTime.iso8601|base64|
51 ** struct|array)
52 ** array data
53 ** data value*
54 ** struct member*
55 ** member name, value
57 ** Contain CDATA: methodName, i4, int, boolean, string, double,
58 ** dateTime.iso8601, base64, name
60 ** We attempt to validate the structure of the XML document carefully.
61 ** We also try *very* hard to handle malicious data gracefully, and without
62 ** leaking memory.
64 ** The CHECK_NAME and CHECK_CHILD_COUNT macros examine an XML element, and
65 ** invoke XMLRPC_FAIL if something looks wrong.
68 #define CHECK_NAME(env,elem,name) \
69 do \
70 if (strcmp((name), xml_element_name(elem)) != 0) \
71 XMLRPC_FAIL2(env, XMLRPC_PARSE_ERROR, \
72 "Expected element of type <%s>, found <%s>", \
73 (name), xml_element_name(elem)); \
74 while (0)
76 #define CHECK_CHILD_COUNT(env,elem,count) \
77 do \
78 if (xml_element_children_size(elem) != (count)) \
79 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, \
80 "Expected <%s> to have %d children, found %d", \
81 xml_element_name(elem), (count), \
82 xml_element_children_size(elem)); \
83 while (0)
85 static xml_element *
86 get_child_by_name (xmlrpc_env *env, xml_element *parent, char *name)
88 size_t child_count, i;
89 xml_element **children;
91 children = xml_element_children(parent);
92 child_count = xml_element_children_size(parent);
93 for (i = 0; i < child_count; i++) {
94 if (0 == strcmp(xml_element_name(children[i]), name))
95 return children[i];
98 xmlrpc_env_set_fault_formatted(env, XMLRPC_PARSE_ERROR,
99 "Expected <%s> to have child <%s>",
100 xml_element_name(parent), name);
101 return NULL;
105 /*=========================================================================
106 ** Number-Parsing Functions
107 **=========================================================================
108 ** These functions mirror atoi, atof, etc., but provide better
109 ** error-handling. These routines may reset errno to zero.
112 static xmlrpc_int32
113 xmlrpc_atoi(xmlrpc_env *env, char *str, size_t stringLength,
114 xmlrpc_int32 min, xmlrpc_int32 max)
116 long i;
117 char *end;
119 XMLRPC_ASSERT_ENV_OK(env);
120 XMLRPC_ASSERT_PTR_OK(str);
122 /* Suppress compiler warnings. */
123 i = 0;
125 /* Check for leading white space. */
126 if (isspace((int)(str[0])))
127 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
128 "\"%s\" must not contain whitespace", str);
130 /* Convert the value. */
131 end = str + stringLength;
132 errno = 0;
133 i = strtol(str, &end, 10);
135 /* Look for ERANGE. */
136 if (errno != 0)
137 /* XXX - Do all operating systems have thread-safe strerror? */
138 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
139 "error parsing \"%s\": %s (%d)",
140 str, strerror(errno), errno);
142 /* Look for out-of-range errors which didn't produce ERANGE. */
143 if (i < min || i > max)
144 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
145 "\"%s\" must be in range %d to %d", str, min, max);
147 /* Check for unused characters. */
148 if (end != str + stringLength)
149 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
150 "\"%s\" contained trailing data", str);
152 cleanup:
153 errno = 0;
154 if (env->fault_occurred)
155 return 0;
156 return (xmlrpc_int32) i;
161 static double
162 xmlrpc_atod(xmlrpc_env *env, char *str, size_t stringLength)
164 double d;
165 char *end;
167 XMLRPC_ASSERT_ENV_OK(env);
168 XMLRPC_ASSERT_PTR_OK(str);
170 /* Suppress compiler warnings. */
171 d = 0.0;
173 /* Check for leading white space. */
174 if (isspace((int)(str[0])))
175 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
176 "\"%s\" must not contain whitespace", str);
178 /* Convert the value. */
179 end = str + stringLength;
180 errno = 0;
181 d = strtod(str, &end);
183 /* Look for ERANGE. */
184 if (errno != 0)
185 /* XXX - Do all operating systems have thread-safe strerror? */
186 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
187 "error parsing \"%s\": %s (%d)",
188 str, strerror(errno), errno);
190 /* Check for unused characters. */
191 if (end != str + stringLength)
192 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
193 "\"%s\" contained trailing data", str);
195 cleanup:
196 errno = 0;
197 if (env->fault_occurred)
198 return 0.0;
199 return d;
203 /*=========================================================================
204 ** make_string
205 **=========================================================================
206 ** Make an XML-RPC string.
208 ** SECURITY: We validate our UTF-8 first. This incurs a performance
209 ** penalty, but ensures that we will never pass maliciously malformed
210 ** UTF-8 data back up to the user layer, where it could wreak untold
211 ** damange. Don't comment out this check unless you know *exactly* what
212 ** you're doing. (Win32 developers who remove this check are *begging*
213 ** to wind up on BugTraq, because many of the Win32 filesystem routines
214 ** rely on an insecure UTF-8 decoder.)
216 ** XXX - This validation is redundant if the user chooses to convert
217 ** UTF-8 data into a wchar_t string.
220 static xmlrpc_value *
221 make_string(xmlrpc_env *env, char *cdata, size_t cdata_size)
223 #ifdef HAVE_UNICODE_WCHAR
224 xmlrpc_validate_utf8(env, cdata, cdata_size);
225 #endif
227 if (env->fault_occurred)
228 return NULL;
229 return xmlrpc_build_value(env, "s#", cdata, cdata_size);
234 /*=========================================================================
235 ** convert_value
236 **=========================================================================
237 ** Convert an XML element representing a value into an xmlrpc_value.
240 static xmlrpc_value *
241 convert_array (xmlrpc_env *env, unsigned *depth, xml_element *elem);
242 static xmlrpc_value *
243 convert_struct(xmlrpc_env *env, unsigned *depth, xml_element *elem);
247 static xmlrpc_value *
248 convert_value(xmlrpc_env *env, unsigned *depth, xml_element *elem)
250 xml_element *child;
251 size_t child_count;
252 char *cdata, *child_name;
253 size_t cdata_size, ascii_len;
254 xmlrpc_mem_block *decoded;
255 unsigned char *ascii_data;
256 xmlrpc_value *retval;
257 xmlrpc_int32 i;
258 double d;
260 XMLRPC_ASSERT_ENV_OK(env);
261 XMLRPC_ASSERT(elem != NULL);
263 /* Error-handling precoditions.
264 ** If we haven't changed any of these from their default state, we're
265 ** allowed to tail-call xmlrpc_build_value. */
266 retval = NULL;
267 decoded = NULL;
269 /* Make sure we haven't recursed too deeply. */
270 if (*depth > xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID))
271 XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR,
272 "Nested data structure too deep.");
274 /* Validate our structure, and see whether we have a child element. */
275 CHECK_NAME(env, elem, "value");
276 child_count = xml_element_children_size(elem);
278 if (child_count == 0) {
279 /* We have no type element, so treat the value as a string. */
280 cdata = xml_element_cdata(elem);
281 cdata_size = xml_element_cdata_size(elem);
282 return make_string(env, cdata, cdata_size);
283 } else {
284 /* We should have a type tag inside our value tag. */
285 CHECK_CHILD_COUNT(env, elem, 1);
286 child = xml_element_children(elem)[0];
288 /* Parse our value-containing element. */
289 child_name = xml_element_name(child);
290 if (strcmp(child_name, "struct") == 0) {
291 return convert_struct(env, depth, child);
292 } else if (strcmp(child_name, "array") == 0) {
293 CHECK_CHILD_COUNT(env, child, 1);
294 return convert_array(env, depth, child);
295 } else {
296 CHECK_CHILD_COUNT(env, child, 0);
297 cdata = xml_element_cdata(child);
298 cdata_size = xml_element_cdata_size(child);
299 if (strcmp(child_name, "i4") == 0 ||
300 strcmp(child_name, "int") == 0)
302 i = xmlrpc_atoi(env, cdata, strlen(cdata),
303 XMLRPC_INT32_MIN, XMLRPC_INT32_MAX);
304 XMLRPC_FAIL_IF_FAULT(env);
305 return xmlrpc_build_value(env, "i", i);
306 } else if (strcmp(child_name, "string") == 0) {
307 return make_string(env, cdata, cdata_size);
308 } else if (strcmp(child_name, "boolean") == 0) {
309 i = xmlrpc_atoi(env, cdata, strlen(cdata), 0, 1);
310 XMLRPC_FAIL_IF_FAULT(env);
311 return xmlrpc_build_value(env, "b", (xmlrpc_bool) i);
312 } else if (strcmp(child_name, "double") == 0) {
313 d = xmlrpc_atod(env, cdata, strlen(cdata));
314 XMLRPC_FAIL_IF_FAULT(env);
315 return xmlrpc_build_value(env, "d", d);
316 } else if (strcmp(child_name, "dateTime.iso8601") == 0) {
317 return xmlrpc_build_value(env, "8", cdata);
318 } else if (strcmp(child_name, "base64") == 0) {
319 /* No more tail calls once we do this! */
320 decoded = xmlrpc_base64_decode(env, cdata, cdata_size);
321 XMLRPC_FAIL_IF_FAULT(env);
322 ascii_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char,
323 decoded);
324 ascii_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(unsigned char,
325 decoded);
326 retval = xmlrpc_build_value(env, "6", ascii_data, ascii_len);
327 XMLRPC_FAIL_IF_FAULT(env);
328 } else {
329 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
330 "Unknown value type <%s>", child_name);
335 cleanup:
336 if (decoded)
337 xmlrpc_mem_block_free(decoded);
338 if (env->fault_occurred) {
339 if (retval)
340 xmlrpc_DECREF(retval);
341 return NULL;
343 return retval;
348 /*=========================================================================
349 ** convert_array
350 **=========================================================================
351 ** Convert an XML element representing an array into an xmlrpc_value.
354 static xmlrpc_value *
355 convert_array(xmlrpc_env *env, unsigned *depth, xml_element *elem)
357 xml_element *data, **values, *value;
358 xmlrpc_value *array, *item;
359 size_t size, i;
361 XMLRPC_ASSERT_ENV_OK(env);
362 XMLRPC_ASSERT(elem != NULL);
364 /* Set up our error-handling preconditions. */
365 item = NULL;
366 (*depth)++;
368 /* Allocate an array to hold our values. */
369 array = xmlrpc_build_value(env, "()");
370 XMLRPC_FAIL_IF_FAULT(env);
372 /* We don't need to check our element name--our callers do that. */
373 CHECK_CHILD_COUNT(env, elem, 1);
374 data = xml_element_children(elem)[0];
375 CHECK_NAME(env, data, "data");
377 /* Iterate over our children. */
378 values = xml_element_children(data);
379 size = xml_element_children_size(data);
380 for (i = 0; i < size; i++) {
381 value = values[i];
382 item = convert_value(env, depth, value);
383 XMLRPC_FAIL_IF_FAULT(env);
385 xmlrpc_array_append_item(env, array, item);
386 xmlrpc_DECREF(item);
387 item = NULL;
388 XMLRPC_FAIL_IF_FAULT(env);
391 cleanup:
392 (*depth)--;
393 if (item)
394 xmlrpc_DECREF(item);
395 if (env->fault_occurred) {
396 if (array)
397 xmlrpc_DECREF(array);
398 return NULL;
400 return array;
405 /*=========================================================================
406 ** convert_struct
407 **=========================================================================
408 ** Convert an XML element representing a struct into an xmlrpc_value.
411 static xmlrpc_value *
412 convert_struct(xmlrpc_env *env, unsigned *depth, xml_element *elem)
414 xmlrpc_value *strct, *key, *value;
415 xml_element **members, *member, *name_elem, *value_elem;
416 size_t size, i;
417 char *cdata;
418 size_t cdata_size;
420 XMLRPC_ASSERT_ENV_OK(env);
421 XMLRPC_ASSERT(elem != NULL);
423 /* Set up our error-handling preconditions. */
424 key = value = NULL;
425 (*depth)++;
427 /* Allocate an array to hold our members. */
428 strct = xmlrpc_struct_new(env);
429 XMLRPC_FAIL_IF_FAULT(env);
431 /* Iterate over our children, extracting key/value pairs. */
432 /* We don't need to check our element name--our callers do that. */
433 members = xml_element_children(elem);
434 size = xml_element_children_size(elem);
435 for (i = 0; i < size; i++) {
436 member = members[i];
437 CHECK_NAME(env, member, "member");
438 CHECK_CHILD_COUNT(env, member, 2);
440 /* Get our key. */
441 name_elem = get_child_by_name(env, member, "name");
442 XMLRPC_FAIL_IF_FAULT(env);
443 CHECK_CHILD_COUNT(env, name_elem, 0);
444 cdata = xml_element_cdata(name_elem);
445 cdata_size = xml_element_cdata_size(name_elem);
446 key = make_string(env, cdata, cdata_size);
447 XMLRPC_FAIL_IF_FAULT(env);
449 /* Get our value. */
450 value_elem = get_child_by_name(env, member, "value");
451 XMLRPC_FAIL_IF_FAULT(env);
452 value = convert_value(env, depth, value_elem);
453 XMLRPC_FAIL_IF_FAULT(env);
455 /* Add the key/value pair to our struct. */
456 xmlrpc_struct_set_value_v(env, strct, key, value);
457 XMLRPC_FAIL_IF_FAULT(env);
459 /* Release our references & memory, and restore our invariants. */
460 xmlrpc_DECREF(key);
461 key = NULL;
462 xmlrpc_DECREF(value);
463 value = NULL;
466 cleanup:
467 (*depth)--;
468 if (key)
469 xmlrpc_DECREF(key);
470 if (value)
471 xmlrpc_DECREF(value);
472 if (env->fault_occurred) {
473 if (strct)
474 xmlrpc_DECREF(strct);
475 return NULL;
477 return strct;
482 /*=========================================================================
483 ** convert_params
484 **=========================================================================
485 ** Convert an XML element representing a list of params into an
486 ** xmlrpc_value (of type array).
489 static xmlrpc_value *
490 convert_params(xmlrpc_env *env, unsigned *depth, xml_element *elem)
492 xmlrpc_value *array, *item;
493 size_t size, i;
494 xml_element **params, *param, *value;
496 XMLRPC_ASSERT_ENV_OK(env);
497 XMLRPC_ASSERT(elem != NULL);
499 /* Set up our error-handling preconditions. */
500 item = NULL;
502 /* Allocate an array to hold our parameters. */
503 array = xmlrpc_build_value(env, "()");
504 XMLRPC_FAIL_IF_FAULT(env);
506 /* We're responsible for checking our own element name. */
507 CHECK_NAME(env, elem, "params");
509 /* Iterate over our children. */
510 size = xml_element_children_size(elem);
511 params = xml_element_children(elem);
512 for (i = 0; i < size; i++) {
513 param = params[i];
514 CHECK_NAME(env, param, "param");
515 CHECK_CHILD_COUNT(env, param, 1);
517 value = xml_element_children(param)[0];
518 item = convert_value(env, depth, value);
519 XMLRPC_FAIL_IF_FAULT(env);
521 xmlrpc_array_append_item(env, array, item);
522 xmlrpc_DECREF(item);
523 item = NULL;
524 XMLRPC_FAIL_IF_FAULT(env);
527 cleanup:
528 if (env->fault_occurred) {
529 if (array)
530 xmlrpc_DECREF(array);
531 if (item)
532 xmlrpc_DECREF(item);
533 return NULL;
535 return array;
540 static void
541 parseCallXml(xmlrpc_env * const envP,
542 const char * const xmlData,
543 size_t const xmlLen,
544 xml_element ** const callElemP) {
546 xmlrpc_env env;
548 xmlrpc_env_init(&env);
549 *callElemP = xml_parse(&env, xmlData, (int)xmlLen);
550 if (env.fault_occurred)
551 xmlrpc_env_set_fault_formatted(
552 envP, env.fault_code, "Call is not valid XML. %s",
553 env.fault_string);
554 xmlrpc_env_clean(&env);
559 /*=========================================================================
560 ** xmlrpc_parse_call
561 **=========================================================================
562 ** Given some XML text, attempt to parse it as an XML-RPC call. Return
563 ** a newly allocated xmlrpc_call structure (or NULL, if an error occurs).
564 ** The two output variables will contain either valid values (which
565 ** must free() and xmlrpc_DECREF(), respectively) or NULLs (if an error
566 ** occurs).
569 void
570 xmlrpc_parse_call(xmlrpc_env * const envP,
571 const char * const xml_data,
572 size_t const xml_len,
573 const char ** const out_method_nameP,
574 xmlrpc_value ** const out_param_arrayPP) {
576 xml_element *call_elem, *name_elem, *params_elem;
577 char *cdata;
578 unsigned depth;
579 size_t call_child_count;
580 char * outMethodName;
581 xmlrpc_value * outParamArrayP;
583 XMLRPC_ASSERT_ENV_OK(envP);
584 XMLRPC_ASSERT(xml_data != NULL);
585 XMLRPC_ASSERT(out_method_nameP != NULL && out_param_arrayPP != NULL);
587 /* Set up our error-handling preconditions. */
588 outMethodName = NULL;
589 outParamArrayP = NULL;
590 call_elem = NULL;
592 /* SECURITY: Last-ditch attempt to make sure our content length is legal.
593 ** XXX - This check occurs too late to prevent an attacker from creating
594 ** an enormous memory block in RAM, so you should try to enforce it
595 ** *before* reading any data off the network. */
596 if (xml_len > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
597 XMLRPC_FAIL(envP, XMLRPC_LIMIT_EXCEEDED_ERROR,
598 "XML-RPC request too large");
600 parseCallXml(envP, xml_data, xml_len, &call_elem);
601 XMLRPC_FAIL_IF_FAULT(envP);
603 /* Pick apart and verify our structure. */
604 CHECK_NAME(envP, call_elem, "methodCall");
605 call_child_count = xml_element_children_size(call_elem);
606 if (call_child_count != 2 && call_child_count != 1)
607 XMLRPC_FAIL1(envP, XMLRPC_PARSE_ERROR,
608 "Expected <methodCall> to have 1 or 2 children, found %d",
609 call_child_count);
611 /* Extract the method name.
612 ** SECURITY: We make sure the method name is valid UTF-8. */
613 name_elem = get_child_by_name(envP, call_elem, "methodName");
614 XMLRPC_FAIL_IF_FAULT(envP);
615 CHECK_CHILD_COUNT(envP, name_elem, 0);
616 cdata = xml_element_cdata(name_elem);
617 #ifdef HAVE_UNICODE_WCHAR
618 xmlrpc_validate_utf8(envP, cdata, strlen(cdata));
619 XMLRPC_FAIL_IF_FAULT(envP);
620 #endif /* HAVE_UNICODE_WCHAR */
621 outMethodName = malloc(strlen(cdata) + 1);
622 XMLRPC_FAIL_IF_NULL(outMethodName, envP, XMLRPC_INTERNAL_ERROR,
623 "Could not allocate memory for method name");
624 strcpy(outMethodName, cdata);
626 /* Convert our parameters. */
627 if (call_child_count == 1) {
628 /* Workaround for Ruby XML-RPC and old versions of xmlrpc-epi. */
629 outParamArrayP = xmlrpc_build_value(envP, "()");
630 XMLRPC_FAIL_IF_FAULT(envP);
631 } else {
632 params_elem = get_child_by_name(envP, call_elem, "params");
633 XMLRPC_FAIL_IF_FAULT(envP);
634 depth = 0;
635 outParamArrayP = convert_params(envP, &depth, params_elem);
636 XMLRPC_ASSERT(depth == 0);
637 XMLRPC_FAIL_IF_FAULT(envP);
640 cleanup:
641 if (call_elem)
642 xml_element_free(call_elem);
643 if (envP->fault_occurred) {
644 if (outMethodName)
645 free(outMethodName);
646 if (outParamArrayP)
647 xmlrpc_DECREF(outParamArrayP);
648 outMethodName = NULL;
649 outParamArrayP = NULL;
651 *out_method_nameP = outMethodName;
652 *out_param_arrayPP = outParamArrayP;
657 /*=========================================================================
658 ** xmlrpc_parse_response
659 **=========================================================================
660 ** Given some XML text, attempt to parse it as an XML-RPC response.
661 ** If the response is a regular, valid response, return a new reference
662 ** to the appropriate value. If the response is a fault, or an error
663 ** occurs during processing, return NULL and set up env appropriately.
666 xmlrpc_value *
667 xmlrpc_parse_response(xmlrpc_env *env,
668 const char *xml_data,
669 size_t xml_len) {
671 xml_element *response, *child, *value;
672 unsigned depth;
673 xmlrpc_value *params, *retval, *fault;
674 int retval_incremented;
676 xmlrpc_value *fault_code_value, *fault_str_value;
677 xmlrpc_int32 fault_code;
678 char *fault_str;
680 XMLRPC_ASSERT_ENV_OK(env);
681 XMLRPC_ASSERT(xml_data != NULL);
683 /* Set up our error-handling preconditions. */
684 response = NULL;
685 params = fault = NULL;
686 retval_incremented = 0;
688 /* SECURITY: Last-ditch attempt to make sure our content length is legal.
689 ** XXX - This check occurs too late to prevent an attacker from creating
690 ** an enormous memory block in RAM, so you should try to enforce it
691 ** *before* reading any data off the network. */
692 if (xml_len > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
693 XMLRPC_FAIL(env, XMLRPC_LIMIT_EXCEEDED_ERROR,
694 "XML-RPC response too large");
696 /* SECURITY: Set up our recursion depth counter. */
697 depth = 0;
699 /* Parse our XML data. */
700 response = xml_parse(env, xml_data, (int)xml_len);
701 XMLRPC_FAIL_IF_FAULT(env);
703 /* Pick apart and verify our structure. */
704 CHECK_NAME(env, response, "methodResponse");
705 CHECK_CHILD_COUNT(env, response, 1);
706 child = xml_element_children(response)[0];
708 /* Parse the response itself. */
709 if (strcmp("params", xml_element_name(child)) == 0) {
711 /* Convert our parameter list. */
712 params = convert_params(env, &depth, child);
713 XMLRPC_FAIL_IF_FAULT(env);
715 /* Extract the return value, and jiggle our reference counts. */
716 xmlrpc_parse_value(env, params, "(V)", &retval);
717 XMLRPC_FAIL_IF_FAULT(env);
718 xmlrpc_INCREF(retval);
719 retval_incremented = 1;
721 } else if (strcmp("fault", xml_element_name(child)) == 0) {
723 /* Convert our fault structure. */
724 CHECK_CHILD_COUNT(env, child, 1);
725 value = xml_element_children(child)[0];
726 fault = convert_value(env, &depth, value);
727 XMLRPC_FAIL_IF_FAULT(env);
728 XMLRPC_TYPE_CHECK(env, fault, XMLRPC_TYPE_STRUCT);
730 /* Get our fault code. */
731 fault_code_value = xmlrpc_struct_get_value(env, fault, "faultCode");
732 XMLRPC_FAIL_IF_FAULT(env);
733 xmlrpc_parse_value(env, fault_code_value, "i", &fault_code);
734 XMLRPC_FAIL_IF_FAULT(env);
736 /* Get our fault string. */
737 fault_str_value = xmlrpc_struct_get_value(env, fault, "faultString");
738 XMLRPC_FAIL_IF_FAULT(env);
739 xmlrpc_parse_value(env, fault_str_value, "s", &fault_str);
740 XMLRPC_FAIL_IF_FAULT(env);
742 /* Return our fault. */
743 XMLRPC_FAIL(env, fault_code, fault_str);
745 } else {
746 XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR,
747 "Expected <params> or <fault> in <methodResponse>");
750 /* Sanity-check our depth-counting code. */
751 XMLRPC_ASSERT(depth == 0);
753 cleanup:
754 if (response)
755 xml_element_free(response);
756 if (params)
757 xmlrpc_DECREF(params);
758 if (fault)
759 xmlrpc_DECREF(fault);
761 if (env->fault_occurred) {
762 if (retval_incremented)
763 xmlrpc_DECREF(retval);
764 return NULL;
766 return retval;