1 /* Copyright information is at end of file. */
3 #include "xmlrpc_config.h"
13 #include "xmlrpc-c/base.h"
14 #include "xmlrpc-c/base_int.h"
15 #include "xmlrpc-c/string_int.h"
16 #include "xmlrpc-c/xmlparser.h"
19 /*=========================================================================
21 **=========================================================================
22 ** An XML-RPC document consists of a single methodCall or methodResponse
25 ** methodCall methodName, params
26 ** methodResponse (params|fault)
30 ** value (i4|int|boolean|string|double|dateTime.iso8601|base64|
37 ** Contain CDATA: methodName, i4, int, boolean, string, double,
38 ** dateTime.iso8601, base64, name
40 ** We attempt to validate the structure of the XML document carefully.
41 ** We also try *very* hard to handle malicious data gracefully, and without
44 ** The CHECK_NAME and CHECK_CHILD_COUNT macros examine an XML element, and
45 ** invoke XMLRPC_FAIL if something looks wrong.
48 #define CHECK_NAME(env,elem,name) \
50 if (!xmlrpc_streq((name), xml_element_name(elem))) \
51 XMLRPC_FAIL2(env, XMLRPC_PARSE_ERROR, \
52 "Expected element of type <%s>, found <%s>", \
53 (name), xml_element_name(elem)); \
56 #define CHECK_CHILD_COUNT(env,elem,count) \
58 if (xml_element_children_size(elem) != (count)) \
59 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, \
60 "Expected <%s> to have %d children, found %d", \
61 xml_element_name(elem), (count), \
62 xml_element_children_size(elem)); \
66 get_child_by_name (xmlrpc_env *env, xml_element *parent, char *name)
68 size_t child_count, i;
69 xml_element **children;
71 children = xml_element_children(parent);
72 child_count = xml_element_children_size(parent);
73 for (i = 0; i < child_count; i++) {
74 if (xmlrpc_streq(xml_element_name(children[i]), name))
78 xmlrpc_env_set_fault_formatted(env, XMLRPC_PARSE_ERROR,
79 "Expected <%s> to have child <%s>",
80 xml_element_name(parent), name);
85 /*=========================================================================
86 ** Number-Parsing Functions
87 **=========================================================================
88 ** These functions mirror atoi, atof, etc., but provide better
89 ** error-handling. These routines may reset errno to zero.
93 xmlrpc_atoi(xmlrpc_env *env, char *str, size_t strlen,
94 xmlrpc_int32 min, xmlrpc_int32 max)
99 XMLRPC_ASSERT_ENV_OK(env);
100 XMLRPC_ASSERT_PTR_OK(str);
102 /* Suppress compiler warnings. */
105 /* Check for leading white space. */
107 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
108 "\"%s\" must not contain whitespace", str);
110 /* Convert the value. */
113 i = strtol(str, &end, 10);
115 /* Look for ERANGE. */
117 /* XXX - Do all operating systems have thread-safe strerror? */
118 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
119 "error parsing \"%s\": %s (%d)",
120 str, strerror(errno), errno);
122 /* Look for out-of-range errors which didn't produce ERANGE. */
123 if (i < min || i > max)
124 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
125 "\"%s\" must be in range %d to %d", str, min, max);
127 /* Check for unused characters. */
128 if (end != str + strlen)
129 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
130 "\"%s\" contained trailing data", str);
134 if (env->fault_occurred)
136 return (xmlrpc_int32) i;
142 xmlrpc_atod(xmlrpc_env *env, char *str, size_t strlen)
147 XMLRPC_ASSERT_ENV_OK(env);
148 XMLRPC_ASSERT_PTR_OK(str);
150 /* Suppress compiler warnings. */
153 /* Check for leading white space. */
155 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
156 "\"%s\" must not contain whitespace", str);
158 /* Convert the value. */
161 d = strtod(str, &end);
163 /* Look for ERANGE. */
165 /* XXX - Do all operating systems have thread-safe strerror? */
166 XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR,
167 "error parsing \"%s\": %s (%d)",
168 str, strerror(errno), errno);
170 /* Check for unused characters. */
171 if (end != str + strlen)
172 XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR,
173 "\"%s\" contained trailing data", str);
177 if (env->fault_occurred)
183 /*=========================================================================
185 **=========================================================================
186 ** Make an XML-RPC string.
188 ** SECURITY: We validate our UTF-8 first. This incurs a performance
189 ** penalty, but ensures that we will never pass maliciously malformed
190 ** UTF-8 data back up to the user layer, where it could wreak untold
191 ** damange. Don't comment out this check unless you know *exactly* what
192 ** you're doing. (Win32 developers who remove this check are *begging*
193 ** to wind up on BugTraq, because many of the Win32 filesystem routines
194 ** rely on an insecure UTF-8 decoder.)
196 ** XXX - This validation is redundant if the user chooses to convert
197 ** UTF-8 data into a wchar_t string.
200 static xmlrpc_value *
201 make_string(xmlrpc_env * const envP,
203 size_t const cdata_size) {
204 #if HAVE_UNICODE_WCHAR
205 xmlrpc_validate_utf8(envP, cdata, cdata_size);
208 if (envP->fault_occurred)
210 return xmlrpc_build_value(envP, "s#", cdata, cdata_size);
215 /* Forward declaration for recursion */
216 static xmlrpc_value *
217 convert_value(xmlrpc_env * const envP,
218 unsigned int const maxRecursion,
219 xml_element * const elemP);
224 convertBase64(xmlrpc_env * const envP,
225 const char * const cdata,
226 size_t const cdata_size,
227 xmlrpc_value ** const valuePP) {
229 xmlrpc_mem_block *decoded;
231 decoded = xmlrpc_base64_decode(envP, cdata, cdata_size);
232 if (!envP->fault_occurred) {
233 unsigned char * const asciiData =
234 XMLRPC_MEMBLOCK_CONTENTS(unsigned char, decoded);
235 size_t const asciiLen =
236 XMLRPC_MEMBLOCK_SIZE(unsigned char, decoded);
238 *valuePP = xmlrpc_build_value(envP, "6", asciiData, asciiLen);
240 XMLRPC_MEMBLOCK_FREE(unsigned char, decoded);
246 /*=========================================================================
248 **=========================================================================
249 ** Convert an XML element representing an array into an xmlrpc_value.
252 static xmlrpc_value *
253 convert_array(xmlrpc_env * const envP,
254 unsigned int const maxRecursion,
255 xml_element * const elemP) {
257 xml_element *data, **values, *value;
258 xmlrpc_value *array, *item;
261 XMLRPC_ASSERT_ENV_OK(envP);
262 XMLRPC_ASSERT(elemP != NULL);
264 /* Set up our error-handling preconditions. */
267 /* Allocate an array to hold our values. */
268 array = xmlrpc_build_value(envP, "()");
269 XMLRPC_FAIL_IF_FAULT(envP);
271 /* We don't need to check our element name--our callers do that. */
272 CHECK_CHILD_COUNT(envP, elemP, 1);
273 data = xml_element_children(elemP)[0];
274 CHECK_NAME(envP, data, "data");
276 /* Iterate over our children. */
277 values = xml_element_children(data);
278 size = xml_element_children_size(data);
279 for (i = 0; i < size; i++) {
281 item = convert_value(envP, maxRecursion-1, value);
282 XMLRPC_FAIL_IF_FAULT(envP);
284 xmlrpc_array_append_item(envP, array, item);
287 XMLRPC_FAIL_IF_FAULT(envP);
293 if (envP->fault_occurred) {
295 xmlrpc_DECREF(array);
303 /*=========================================================================
305 **=========================================================================
306 ** Convert an XML element representing a struct into an xmlrpc_value.
309 static xmlrpc_value *
310 convert_struct(xmlrpc_env * const envP,
311 unsigned int const maxRecursion,
312 xml_element * const elemP) {
314 xmlrpc_value *strct, *key, *value;
315 xml_element **members, *member, *name_elemP, *value_elemP;
320 XMLRPC_ASSERT_ENV_OK(envP);
321 XMLRPC_ASSERT(elemP != NULL);
323 /* Set up our error-handling preconditions. */
324 strct = key = value = NULL;
326 /* Allocate an array to hold our members. */
327 strct = xmlrpc_struct_new(envP);
328 XMLRPC_FAIL_IF_FAULT(envP);
330 /* Iterate over our children, extracting key/value pairs. */
331 /* We don't need to check our element name--our callers do that. */
332 members = xml_element_children(elemP);
333 size = xml_element_children_size(elemP);
334 for (i = 0; i < size; i++) {
336 CHECK_NAME(envP, member, "member");
337 CHECK_CHILD_COUNT(envP, member, 2);
340 name_elemP = get_child_by_name(envP, member, "name");
341 XMLRPC_FAIL_IF_FAULT(envP);
342 CHECK_CHILD_COUNT(envP, name_elemP, 0);
343 cdata = xml_element_cdata(name_elemP);
344 cdata_size = xml_element_cdata_size(name_elemP);
345 key = make_string(envP, cdata, cdata_size);
346 XMLRPC_FAIL_IF_FAULT(envP);
349 value_elemP = get_child_by_name(envP, member, "value");
350 XMLRPC_FAIL_IF_FAULT(envP);
351 value = convert_value(envP, maxRecursion-1, value_elemP);
352 XMLRPC_FAIL_IF_FAULT(envP);
354 /* Add the key/value pair to our struct. */
355 xmlrpc_struct_set_value_v(envP, strct, key, value);
356 XMLRPC_FAIL_IF_FAULT(envP);
358 /* Release our references & memory, and restore our invariants. */
361 xmlrpc_DECREF(value);
369 xmlrpc_DECREF(value);
370 if (envP->fault_occurred) {
372 xmlrpc_DECREF(strct);
380 static xmlrpc_value *
381 convert_value(xmlrpc_env * const envP,
382 unsigned int const maxRecursion,
383 xml_element * const elemP) {
384 /*----------------------------------------------------------------------------
385 Compute the xmlrpc_value represented by the XML <value> element 'elem'.
386 Return that xmlrpc_value.
388 We call convert_array() and convert_struct(), which may ultimately
389 call us recursively. Don't recurse any more than 'maxRecursion'
391 -----------------------------------------------------------------------------*/
393 xmlrpc_value * retval;
395 XMLRPC_ASSERT_ENV_OK(envP);
396 XMLRPC_ASSERT(elemP != NULL);
398 /* Error-handling preconditions.
399 ** If we haven't changed any of these from their default state, we're
400 ** allowed to tail-call xmlrpc_build_value. */
403 /* Assume we'll need to recurse, make sure we're allowed */
404 if (maxRecursion < 1)
405 XMLRPC_FAIL(envP, XMLRPC_PARSE_ERROR,
406 "Nested data structure too deep.");
408 /* Validate our structure, and see whether we have a child element. */
409 CHECK_NAME(envP, elemP, "value");
410 child_count = xml_element_children_size(elemP);
412 if (child_count == 0) {
413 /* We have no type element, so treat the value as a string. */
414 char * const cdata = xml_element_cdata(elemP);
415 size_t const cdata_size = xml_element_cdata_size(elemP);
416 retval = make_string(envP, cdata, cdata_size);
418 /* We should have a type tag inside our value tag. */
420 const char * child_name;
422 CHECK_CHILD_COUNT(envP, elemP, 1);
423 child = xml_element_children(elemP)[0];
425 /* Parse our value-containing element. */
426 child_name = xml_element_name(child);
427 if (xmlrpc_streq(child_name, "struct")) {
428 retval = convert_struct(envP, maxRecursion, child);
429 } else if (xmlrpc_streq(child_name, "array")) {
430 CHECK_CHILD_COUNT(envP, child, 1);
431 retval = convert_array(envP, maxRecursion, child);
436 CHECK_CHILD_COUNT(envP, child, 0);
437 cdata = xml_element_cdata(child);
438 cdata_size = xml_element_cdata_size(child);
439 if (xmlrpc_streq(child_name, "i4") ||
440 xmlrpc_streq(child_name, "int")) {
441 xmlrpc_int32 const i =
442 xmlrpc_atoi(envP, cdata, strlen(cdata),
443 XMLRPC_INT32_MIN, XMLRPC_INT32_MAX);
444 XMLRPC_FAIL_IF_FAULT(envP);
445 retval = xmlrpc_build_value(envP, "i", i);
446 } else if (xmlrpc_streq(child_name, "string")) {
447 retval = make_string(envP, cdata, cdata_size);
448 } else if (xmlrpc_streq(child_name, "boolean")) {
449 xmlrpc_int32 const i =
450 xmlrpc_atoi(envP, cdata, strlen(cdata), 0, 1);
451 XMLRPC_FAIL_IF_FAULT(envP);
452 retval = xmlrpc_build_value(envP, "b", (xmlrpc_bool) i);
453 } else if (xmlrpc_streq(child_name, "double")) {
454 double const d = xmlrpc_atod(envP, cdata, strlen(cdata));
455 XMLRPC_FAIL_IF_FAULT(envP);
456 retval = xmlrpc_build_value(envP, "d", d);
457 } else if (xmlrpc_streq(child_name, "dateTime.iso8601")) {
458 retval = xmlrpc_build_value(envP, "8", cdata);
459 } else if (xmlrpc_streq(child_name, "nil")) {
460 retval = xmlrpc_build_value(envP, "n");
461 } else if (xmlrpc_streq(child_name, "base64")) {
462 /* No more tail calls once we do this! */
464 convertBase64(envP, cdata, cdata_size, &retval);
465 if (envP->fault_occurred)
466 /* Just for cleanup code: */
469 XMLRPC_FAIL1(envP, XMLRPC_PARSE_ERROR,
470 "Unknown value type -- XML element is named "
477 if (envP->fault_occurred) {
479 xmlrpc_DECREF(retval);
487 /*=========================================================================
489 **=========================================================================
490 ** Convert an XML element representing a list of params into an
491 ** xmlrpc_value (of type array).
494 static xmlrpc_value *
495 convert_params(xmlrpc_env * const envP,
496 const xml_element * const elemP) {
497 /*----------------------------------------------------------------------------
498 Convert an XML element representing a list of parameters (i.e. a
499 <params> element) to an xmlrpc_value of type array. Note that an
500 array is normally represented in XML by a <value> element. We use
501 type xmlrpc_value to represent the parameter list just for convenience.
502 -----------------------------------------------------------------------------*/
503 xmlrpc_value *array, *item;
505 xml_element **params, *param, *value;
507 XMLRPC_ASSERT_ENV_OK(envP);
508 XMLRPC_ASSERT(elemP != NULL);
510 /* Set up our error-handling preconditions. */
513 /* Allocate an array to hold our parameters. */
514 array = xmlrpc_build_value(envP, "()");
515 XMLRPC_FAIL_IF_FAULT(envP);
517 /* We're responsible for checking our own element name. */
518 CHECK_NAME(envP, elemP, "params");
520 /* Iterate over our children. */
521 size = xml_element_children_size(elemP);
522 params = xml_element_children(elemP);
523 for (i = 0; i < size; ++i) {
524 unsigned int const maxNest = xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);
527 CHECK_NAME(envP, param, "param");
528 CHECK_CHILD_COUNT(envP, param, 1);
530 value = xml_element_children(param)[0];
531 item = convert_value(envP, maxNest, value);
532 XMLRPC_FAIL_IF_FAULT(envP);
534 xmlrpc_array_append_item(envP, array, item);
537 XMLRPC_FAIL_IF_FAULT(envP);
541 if (envP->fault_occurred) {
543 xmlrpc_DECREF(array);
554 parseCallXml(xmlrpc_env * const envP,
555 const char * const xmlData,
557 xml_element ** const callElemPP) {
559 xml_element * callElemP;
562 xmlrpc_env_init(&env);
563 xml_parse(&env, xmlData, xmlLen, &callElemP);
564 if (env.fault_occurred)
565 xmlrpc_env_set_fault_formatted(
566 envP, env.fault_code, "Call is not valid XML. %s",
569 if (!xmlrpc_streq(xml_element_name(callElemP), "methodCall"))
570 xmlrpc_env_set_fault_formatted(
571 envP, XMLRPC_PARSE_ERROR,
572 "XML-RPC call should be a <methodCall> element. "
573 "Instead, we have a <%s> element.",
574 xml_element_name(callElemP));
576 if (!envP->fault_occurred)
577 *callElemPP = callElemP;
579 if (envP->fault_occurred)
580 xml_element_free(callElemP);
582 xmlrpc_env_clean(&env);
588 parseMethodNameElement(xmlrpc_env * const envP,
589 xml_element * const nameElemP,
590 const char ** const methodNameP) {
592 XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(nameElemP), "methodName"));
594 if (xml_element_children_size(nameElemP) > 0)
595 xmlrpc_env_set_fault_formatted(
596 envP, XMLRPC_PARSE_ERROR,
597 "A <methodName> element should not have children. "
598 "This one has %u of them.", xml_element_children_size(nameElemP));
600 const char * const cdata = xml_element_cdata(nameElemP);
602 xmlrpc_validate_utf8(envP, cdata, strlen(cdata));
604 if (!envP->fault_occurred) {
605 *methodNameP = strdup(cdata);
606 if (*methodNameP == NULL)
608 "Could not allocate memory for method name");
616 parseCallChildren(xmlrpc_env * const envP,
617 xml_element * const callElemP,
618 const char ** const methodNameP,
619 xmlrpc_value ** const paramArrayPP ) {
620 /*----------------------------------------------------------------------------
621 Parse the children of a <methodCall> XML element *callElemP. They should
622 be <methodName> and <params>.
623 -----------------------------------------------------------------------------*/
624 size_t const callChildCount = xml_element_children_size(callElemP);
626 xml_element * nameElemP;
628 XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall"));
630 nameElemP = get_child_by_name(envP, callElemP, "methodName");
632 if (!envP->fault_occurred) {
633 parseMethodNameElement(envP, nameElemP, methodNameP);
635 if (!envP->fault_occurred) {
636 /* Convert our parameters. */
637 if (callChildCount > 1) {
638 xml_element * paramsElemP;
640 paramsElemP = get_child_by_name(envP, callElemP, "params");
642 if (!envP->fault_occurred)
643 *paramArrayPP = convert_params(envP, paramsElemP);
645 /* Workaround for Ruby XML-RPC and old versions of
646 xmlrpc-epi. Future improvement: Instead of looking
647 at child count, we should just check for existence
650 *paramArrayPP = xmlrpc_array_new(envP);
652 if (!envP->fault_occurred) {
653 if (callChildCount > 2)
654 xmlrpc_env_set_fault_formatted(
655 envP, XMLRPC_PARSE_ERROR,
656 "<methodCall> has extraneous children, other than "
657 "<methodName> and <params>. Total child count = %u",
660 if (envP->fault_occurred)
661 xmlrpc_DECREF(*paramArrayPP);
663 if (envP->fault_occurred)
664 xmlrpc_strfree(*methodNameP);
671 /*=========================================================================
673 **=========================================================================
674 ** Given some XML text, attempt to parse it as an XML-RPC call. Return
675 ** a newly allocated xmlrpc_call structure (or NULL, if an error occurs).
676 ** The two output variables will contain either valid values (which
677 ** must free() and xmlrpc_DECREF(), respectively) or NULLs (if an error
682 xmlrpc_parse_call(xmlrpc_env * const envP,
683 const char * const xmlData,
685 const char ** const methodNameP,
686 xmlrpc_value ** const paramArrayPP) {
688 XMLRPC_ASSERT_ENV_OK(envP);
689 XMLRPC_ASSERT(xmlData != NULL);
690 XMLRPC_ASSERT(methodNameP != NULL && paramArrayPP != NULL);
692 /* SECURITY: Last-ditch attempt to make sure our content length is
693 legal. XXX - This check occurs too late to prevent an attacker
694 from creating an enormous memory block, so you should try to
695 enforce it *before* reading any data off the network.
697 if (xmlLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
698 xmlrpc_env_set_fault_formatted(
699 envP, XMLRPC_LIMIT_EXCEEDED_ERROR,
700 "XML-RPC request too large. Max allowed is %u bytes",
701 xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID));
703 xml_element * callElemP;
704 parseCallXml(envP, xmlData, xmlLen, &callElemP);
705 if (!envP->fault_occurred) {
706 parseCallChildren(envP, callElemP, methodNameP, paramArrayPP);
708 xml_element_free(callElemP);
711 if (envP->fault_occurred) {
713 *paramArrayPP = NULL;
720 interpretFaultValue(xmlrpc_env * const envP,
721 xmlrpc_value * const faultVP,
722 int * const faultCodeP,
723 const char ** const faultStringP) {
725 if (faultVP->_type != XMLRPC_TYPE_STRUCT)
726 xmlrpc_env_set_fault(
727 envP, XMLRPC_PARSE_ERROR,
728 "<value> element of <fault> response contains is not "
729 "of structure type");
731 xmlrpc_value * faultCodeVP;
734 xmlrpc_env_init(&fvEnv);
736 xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP);
737 if (!fvEnv.fault_occurred) {
738 xmlrpc_read_int(&fvEnv, faultCodeVP, faultCodeP);
739 if (!fvEnv.fault_occurred) {
740 xmlrpc_value * faultStringVP;
742 xmlrpc_struct_read_value(&fvEnv, faultVP, "faultString",
744 if (!fvEnv.fault_occurred) {
745 xmlrpc_read_string(&fvEnv, faultStringVP, faultStringP);
746 xmlrpc_DECREF(faultStringVP);
749 xmlrpc_DECREF(faultCodeVP);
751 if (fvEnv.fault_occurred)
752 xmlrpc_env_set_fault_formatted(
753 envP, XMLRPC_PARSE_ERROR,
754 "Invalid struct for <fault> value. %s", fvEnv.fault_string);
756 xmlrpc_env_clean(&fvEnv);
763 parseFaultElement(xmlrpc_env * const envP,
764 const xml_element * const faultElement,
765 int * const faultCodeP,
766 const char ** const faultStringP) {
768 unsigned int const maxRecursion =
769 xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);
771 XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(faultElement), "fault"));
773 if (xml_element_children_size(faultElement) != 1)
774 xmlrpc_env_set_fault_formatted(
775 envP, XMLRPC_PARSE_ERROR,
776 "<fault> element should have 1 child, but it has %u.",
777 xml_element_children_size(faultElement));
779 xml_element * const faultValueP =
780 xml_element_children(faultElement)[0];
782 xmlrpc_value * faultVP;
784 faultVP = convert_value(envP, maxRecursion, faultValueP);
786 if (!envP->fault_occurred) {
787 interpretFaultValue(envP, faultVP, faultCodeP, faultStringP);
789 xmlrpc_DECREF(faultVP);
797 parseParamsElement(xmlrpc_env * const envP,
798 const xml_element * const paramsElementP,
799 xmlrpc_value ** const resultPP) {
801 xmlrpc_value * paramsVP;
804 xmlrpc_env_init(&env);
806 XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(paramsElementP), "params"));
808 paramsVP = convert_params(envP, paramsElementP);
810 if (!envP->fault_occurred) {
814 XMLRPC_ASSERT_ARRAY_OK(paramsVP);
816 xmlrpc_env_init(&sizeEnv);
818 arraySize = xmlrpc_array_size(&sizeEnv, paramsVP);
819 /* Since it's a valid array, as asserted above, can't fail */
820 XMLRPC_ASSERT(!sizeEnv.fault_occurred);
823 xmlrpc_env_set_fault_formatted(
824 &env, XMLRPC_PARSE_ERROR,
825 "Contains %d items. It should have 1.",
828 xmlrpc_array_read_item(envP, paramsVP, 0, resultPP);
830 xmlrpc_DECREF(paramsVP);
831 xmlrpc_env_clean(&sizeEnv);
833 if (env.fault_occurred)
834 xmlrpc_env_set_fault_formatted(
835 envP, env.fault_code,
836 "Invalid <params> element. %s", env.fault_string);
838 xmlrpc_env_clean(&env);
844 parseMethodResponseElt(xmlrpc_env * const envP,
845 const xml_element * const methodResponseEltP,
846 xmlrpc_value ** const resultPP,
847 int * const faultCodeP,
848 const char ** const faultStringP) {
850 XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(methodResponseEltP),
853 if (xml_element_children_size(methodResponseEltP) == 1) {
854 xml_element * const child =
855 xml_element_children(methodResponseEltP)[0];
857 if (xmlrpc_streq(xml_element_name(child), "params")) {
858 /* It's a successful response */
859 parseParamsElement(envP, child, resultPP);
860 *faultStringP = NULL;
861 } else if (xmlrpc_streq(xml_element_name(child), "fault")) {
862 /* It's a failure response */
863 parseFaultElement(envP, child, faultCodeP, faultStringP);
865 xmlrpc_env_set_fault_formatted(
866 envP, XMLRPC_PARSE_ERROR,
867 "<methodResponse> must contain <params> or <fault>, "
868 "but contains <%s>.", xml_element_name(child));
870 xmlrpc_env_set_fault_formatted(
871 envP, XMLRPC_PARSE_ERROR,
872 "<methodResponse> has %u children, should have 1.",
873 xml_element_children_size(methodResponseEltP));
879 xmlrpc_parse_response2(xmlrpc_env * const envP,
880 const char * const xmlData,
881 size_t const xmlDataLen,
882 xmlrpc_value ** const resultPP,
883 int * const faultCodeP,
884 const char ** const faultStringP) {
885 /*----------------------------------------------------------------------------
886 Given some XML text, attempt to parse it as an XML-RPC response.
888 If the response is a regular, valid response, return a new reference
889 to the appropriate value as *resultP and return NULL as
890 *faultStringP and nothing as *faultCodeP.
892 If the response valid, but indicates a failure of the RPC, return the
893 fault string in newly malloc'ed space as *faultStringP and the fault
894 code as *faultCodeP and nothing as *resultP.
896 If the XML text is not a valid response or something prevents us from
897 parsing it, return a description of the error as *envP and nothing else.
898 -----------------------------------------------------------------------------*/
899 xml_element * response;
901 XMLRPC_ASSERT_ENV_OK(envP);
902 XMLRPC_ASSERT(xmlData != NULL);
904 /* SECURITY: Last-ditch attempt to make sure our content length is legal.
905 ** XXX - This check occurs too late to prevent an attacker from creating
906 ** an enormous memory block, so you should try to enforce it
907 ** *before* reading any data off the network. */
908 if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
909 xmlrpc_env_set_fault_formatted(
910 envP, XMLRPC_LIMIT_EXCEEDED_ERROR,
911 "XML-RPC response too large. Our limit is %u characters. "
912 "We got %u characters",
913 xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), xmlDataLen);
915 xml_parse(envP, xmlData, xmlDataLen, &response);
916 if (!envP->fault_occurred) {
917 /* Pick apart and verify our structure. */
918 if (xmlrpc_streq(xml_element_name(response), "methodResponse")) {
919 parseMethodResponseElt(envP, response,
920 resultPP, faultCodeP, faultStringP);
922 xmlrpc_env_set_fault_formatted(
923 envP, XMLRPC_PARSE_ERROR,
924 "XML-RPC response must consist of a "
925 "<methodResponse> element. This has a <%s> instead.",
926 xml_element_name(response));
928 xml_element_free(response);
936 xmlrpc_parse_response(xmlrpc_env * const envP,
937 const char * const xmlData,
938 size_t const xmlDataLen) {
939 /*----------------------------------------------------------------------------
940 This exists for backward compatibility. It is like
941 xmlrpc_parse_response2(), except that it merges the concepts of a
942 failed RPC and an error in executing the RPC.
943 -----------------------------------------------------------------------------*/
944 xmlrpc_value * retval;
945 xmlrpc_value * result;
946 const char * faultString;
949 xmlrpc_parse_response2(envP, xmlData, xmlDataLen,
950 &result, &faultCode, &faultString);
952 if (envP->fault_occurred)
956 xmlrpc_env_set_fault(envP, faultCode, faultString);
957 xmlrpc_strfree(faultString);
960 retval = result; /* transfer reference */
967 /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
969 ** Redistribution and use in source and binary forms, with or without
970 ** modification, are permitted provided that the following conditions
972 ** 1. Redistributions of source code must retain the above copyright
973 ** notice, this list of conditions and the following disclaimer.
974 ** 2. Redistributions in binary form must reproduce the above copyright
975 ** notice, this list of conditions and the following disclaimer in the
976 ** documentation and/or other materials provided with the distribution.
977 ** 3. The name of the author may not be used to endorse or promote products
978 ** derived from this software without specific prior written permission.
980 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
981 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
982 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
983 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
984 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
985 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
986 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
987 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
988 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
989 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF