Exemple #1
0
static void
parseMethodResponseElt(xmlrpc_env *        const envP,
                       const xml_element * const methodResponseEltP,
                       xmlrpc_value **     const resultPP,
                       int *               const faultCodeP,
                       const char **       const faultStringP) {
    
    XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(methodResponseEltP),
                               "methodResponse"));

    if (xml_element_children_size(methodResponseEltP) == 1) {
        xml_element * const child =
            xml_element_children(methodResponseEltP)[0];
        
        if (xmlrpc_streq(xml_element_name(child), "params")) {
            /* It's a successful response */
            parseParamsElement(envP, child, resultPP);
            *faultStringP = NULL;
        } else if (xmlrpc_streq(xml_element_name(child), "fault")) {
            /* It's a failure response */
            parseFaultElement(envP, child, faultCodeP, faultStringP);
        } else
            setParseFault(envP,
                          "<methodResponse> must contain <params> or <fault>, "
                          "but contains <%s>.", xml_element_name(child));
    } else
        setParseFault(envP,
                      "<methodResponse> has %u children, should have 1.",
                      xml_element_children_size(methodResponseEltP));
}
void
xmlrpc_parse_response2(xmlrpc_env *    const envP,
                       const char *    const xmlData,
                       size_t          const xmlDataLen,
                       xmlrpc_value ** const resultPP,
                       int *           const faultCodeP,
                       const char **   const faultStringP) {
/*----------------------------------------------------------------------------
  Given some XML text, attempt to parse it as an XML-RPC response.

  If the response is a regular, valid response, return a new reference
  to the appropriate value as *resultP and return NULL as
  *faultStringP and nothing as *faultCodeP.

  If the response is valid, but indicates a failure of the RPC, return the
  fault string in newly malloc'ed space as *faultStringP and the fault
  code as *faultCodeP and nothing as *resultP.

  If the XML text is not a valid response or something prevents us from
  parsing it, return a description of the error as *envP and nothing else.
-----------------------------------------------------------------------------*/
    xml_element * response;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(xmlData != NULL);

    /* SECURITY: Last-ditch attempt to make sure our content length is legal.
    ** XXX - This check occurs too late to prevent an attacker from creating
    ** an enormous memory block, so you should try to enforce it
    ** *before* reading any data off the network. */
    if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
        xmlrpc_env_set_fault_formatted(
            envP, XMLRPC_LIMIT_EXCEEDED_ERROR,
            "XML-RPC response too large.  Our limit is %u characters.  "
            "We got %u characters",
            xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), xmlDataLen);
    else {
        xmlrpc_env env;
        xmlrpc_env_init(&env);

        xml_parse(&env, xmlData, xmlDataLen, &response);

        if (env.fault_occurred)
            setParseFault(envP, "Not valid XML.  %s", env.fault_string);
        else {
            /* Pick apart and verify our structure. */
            if (xmlrpc_streq(xml_element_name(response), "methodResponse")) {
                parseMethodResponseElt(envP, response,
                                       resultPP, faultCodeP, faultStringP);
            } else
                setParseFault(envP, "XML-RPC response must consist of a "
                              "<methodResponse> element.  "
                              "This has a <%s> instead.",
                              xml_element_name(response));
            
            xml_element_free(response);
        }
        xmlrpc_env_clean(&env);
    }
}
static void
parseDoubleString(xmlrpc_env *  const envP,
                  const char *  const string,
                  double *      const valueP) {
/*----------------------------------------------------------------------------
   Turn e.g. "4.3" into 4.3 .
-----------------------------------------------------------------------------*/
    /* strtod() is no good for this because it is designed for human
       interfaces; it parses according to locale.  As a practical
       matter that sometimes means that it does not recognize "." as a
       decimal point.  In XML-RPC, "." is a decimal point.

       Design note: in my experiments, using strtod() was 10 times
       slower than using this function.
    */
    const char * mantissa;
    const char * mantissaEnd;
    const char * fraction;
    const char * fractionEnd;

    scanAndValidateDoubleString(envP, string, &mantissa, &mantissaEnd,
                                &fraction, &fractionEnd);

    if (!envP->fault_occurred) {
        double accum;

        accum = 0.0;

        if (mantissa == mantissaEnd && fraction == fractionEnd) {
            setParseFault(envP, "No digits");
            return;
        }
        {
            /* Add in the whole part */
            const char * p;

            for (p = mantissa; p < mantissaEnd; ++p) {
                accum *= 10;
                accum += (*p - '0');
            }
        }
        {
            /* Add in the fractional part */
            double significance;
            const char * p;
            for (significance = 0.1, p = fraction;
                 p < fractionEnd;
                 ++p, significance *= 0.1) {
                
                accum += (*p - '0') * significance;
            }
        }
        if (isInfinite(accum))
            setParseFault(envP, "Value exceeds the size allowed by XML-RPC");
        else
            *valueP = string[0] == '-' ? (- accum) : accum;
    }
}
Exemple #4
0
void
xmlrpc_parse_value_xml(xmlrpc_env *    const envP,
                       const char *    const xmlData,
                       size_t          const xmlDataLen,
                       xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Compute the xmlrpc_value represented by the XML document 'xmlData' (of
   length 'xmlDataLen' characters), which must consist of a single <value>
   element.  Return that xmlrpc_value.

   We call convert_array() and convert_struct(), which may ultimately
   call us recursively.  Don't recurse any more than 'maxRecursion'
   times.

   This isn't generally useful in XML-RPC programs, because such programs
   parse a whole XML-RPC call or response document, and never see the XML text
   of just a <value> element.  But a program may do some weird form of XML-RPC
   processing or just borrow Xmlrpc-c's value serialization facilities for
   something unrelated to XML-RPC.  In any case, it makes sense to have an
   inverse of xmlrpc_serialize_value2(), which generates XML text from an
   xmlrpc_value.
-----------------------------------------------------------------------------*/
    xmlrpc_env env;

    xml_element * valueEltP;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(xmlData != NULL);

    xmlrpc_env_init(&env);

    xml_parse(&env, xmlData, xmlDataLen, &valueEltP);

    if (env.fault_occurred) {
        setParseFault(envP, "Not valid XML.  %s", env.fault_string);
    } else {
        if (xmlrpc_streq(xml_element_name(valueEltP), "value")) {
            unsigned int const maxRecursion = (unsigned int)
                xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);
            xmlrpc_parseValue(envP, maxRecursion, valueEltP, valuePP);
        } else
            setParseFault(envP, "XML-RPC value XML document must consist of "
                          "a <value> element.  This has a <%s> instead.",
                          xml_element_name(valueEltP));
        xml_element_free(valueEltP);
    }
    xmlrpc_env_clean(&env);
}
Exemple #5
0
static void
parseCallXml(xmlrpc_env *   const envP,
             const char *   const xmlData,
             size_t         const xmlDataLen,
             xml_element ** const callElemPP) {
/*----------------------------------------------------------------------------
   Parse the XML of an XML-RPC call.
-----------------------------------------------------------------------------*/
    xml_element * callElemP;
    xmlrpc_env env;

    xmlrpc_env_init(&env);
    xml_parse(&env, xmlData, xmlDataLen, &callElemP);
    if (env.fault_occurred)
        xmlrpc_env_set_fault_formatted(
            envP, env.fault_code, "Call is not valid XML.  %s",
            env.fault_string);
    else {
        if (!xmlrpc_streq(xml_element_name(callElemP), "methodCall"))
            setParseFault(envP,
                          "XML-RPC call should be a <methodCall> element.  "
                          "Instead, we have a <%s> element.",
                          xml_element_name(callElemP));

        if (envP->fault_occurred)
            xml_element_free(callElemP);
    }
    *callElemPP = callElemP;

    xmlrpc_env_clean(&env);
}
static void
parseArray(xmlrpc_env *    const envP,
           unsigned int    const maxRecursion,
           xml_element *   const arrayElemP,
           xmlrpc_value ** const arrayPP) {

    xmlrpc_value * arrayP;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(arrayElemP != NULL);

    arrayP = xmlrpc_array_new(envP);
    if (!envP->fault_occurred) {
        unsigned int const childCount = xml_element_children_size(arrayElemP);

        if (childCount != 1)
            setParseFault(envP,
                          "<array> element has %u children.  Only one <data> "
                          "makes sense.", childCount);
        else {
            xml_element * const dataElemP =
                xml_element_children(arrayElemP)[0];
            const char * const elemName = xml_element_name(dataElemP);

            if (!xmlrpc_streq(elemName, "data"))
                setParseFault(envP,
                              "<array> element has <%s> child.  Only <data> "
                              "makes sense.", elemName);
            else {
                xml_element ** const values = xml_element_children(dataElemP);
                unsigned int const size = xml_element_children_size(dataElemP);

                unsigned int i;

                for (i = 0; i < size && !envP->fault_occurred; ++i)
                    parseArrayDataChild(envP, values[i], maxRecursion, arrayP);
            }
        }
        if (envP->fault_occurred)
            xmlrpc_DECREF(arrayP);
        else
            *arrayPP = arrayP;
    }
}
static void
parseInt(xmlrpc_env *    const envP,
         const char *    const str,
         xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Parse the content of a <int> XML-RPC XML element, e.g. "34".

   'str' is that content.
-----------------------------------------------------------------------------*/
    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT_PTR_OK(str);

    if (str[0] == '\0')
        setParseFault(envP, "<int> XML element content is empty");
    else if (isspace(str[0]))
        setParseFault(envP, "<int> content '%s' starts with white space",
                      str);
    else {
        long i;
        char * tail;

        errno = 0;
        i = strtol(str, &tail, 10);

        /* Look for ERANGE. */
        if (errno == ERANGE)
            setParseFault(envP, "<int> XML element value '%s' represents a "
                          "number beyond the range that "
                          "XML-RPC allows (%d - %d)", str,
                          XMLRPC_INT32_MIN, XMLRPC_INT32_MAX);
        else if (errno != 0)
            setParseFault(envP, "unexpected error parsing <int> XML element "
                          "value '%s'.  strtol() failed with errno %d (%s)",
                          str, errno, strerror(errno));
        else {
            /* Look for out-of-range errors which didn't produce ERANGE. */
            if (i < XMLRPC_INT32_MIN)
                setParseFault(envP,
                              "<int> value %ld is below the range allowed "
                              "by XML-RPC (minimum is %d)",
                              i, XMLRPC_INT32_MIN);
            else if (i > XMLRPC_INT32_MAX)
                setParseFault(envP,
                              "<int> value %ld is above the range allowed "
                              "by XML-RPC (maximum is %d)",
                              i, XMLRPC_INT32_MAX);
            else {
                if (tail[0] != '\0')
                    setParseFault(envP,
                                  "<int> value '%s' contains non-numerical "
                                  "junk: '%s'", str, tail);
                else
                    *valuePP = xmlrpc_int_new(envP, i);
            }
        }
    }
}
static void
scanAndValidateDoubleString(xmlrpc_env *  const envP,
                            const char *  const string,
                            const char ** const mantissaP,
                            const char ** const mantissaEndP,
                            const char ** const fractionP,
                            const char ** const fractionEndP) {

    const char * mantissa;
    const char * dp;
    const char * p;

    if (string[0] == '-' || string[0] == '+')
        mantissa = &string[1];
    else
        mantissa = &string[0];

    for (p = mantissa, dp = NULL; *p; ++p) {
        char const c = *p;
        if (c == '.') {
            if (dp) {
                setParseFault(envP, "Two decimal points");
                return;
            } else
                dp = p;
        } else if (c < '0' || c > '9') {
            setParseFault(envP, "Garbage (not sign, digit, or period) "
                          "starting at '%s'", p);
            return;
        }
    }
    *mantissaP = mantissa;
    if (dp) {
        *mantissaEndP = dp;
        *fractionP    = dp+1;
        *fractionEndP = p;
    } else {
        *mantissaEndP = p;
        *fractionP    = p;
        *fractionEndP = p;
    }
}
Exemple #9
0
static void
interpretFaultValue(xmlrpc_env *   const envP,
                    xmlrpc_value * const faultVP,
                    int *          const faultCodeP,
                    const char **  const faultStringP) {
                
    if (faultVP->_type != XMLRPC_TYPE_STRUCT)
        setParseFault(envP,
                      "<value> element of <fault> response is not "
                      "of structure type");
    else {
        xmlrpc_value * faultCodeVP;
        xmlrpc_env fvEnv;

        xmlrpc_env_init(&fvEnv);

        xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP);
        if (!fvEnv.fault_occurred) {
            interpretFaultCode(&fvEnv, faultCodeVP, faultCodeP);
            
            if (!fvEnv.fault_occurred) {
                xmlrpc_value * faultStringVP;

                xmlrpc_struct_read_value(&fvEnv, faultVP, "faultString",
                                         &faultStringVP);
                if (!fvEnv.fault_occurred) {
                    interpretFaultString(&fvEnv, faultStringVP, faultStringP);

                    xmlrpc_DECREF(faultStringVP);
                }
            }
            xmlrpc_DECREF(faultCodeVP);
        }
        if (fvEnv.fault_occurred)
            setParseFault(envP, "Invalid struct for <fault> value.  %s",
                          fvEnv.fault_string);

        xmlrpc_env_clean(&fvEnv);
    }
}
Exemple #10
0
static void
parseCallChildren(xmlrpc_env *    const envP,
                  xml_element *   const callElemP,
                  const char **   const methodNameP,
                  xmlrpc_value ** const paramArrayPP ) {
/*----------------------------------------------------------------------------
  Parse the children of a <methodCall> XML element *callElemP.  They should
  be <methodName> and <params>.
-----------------------------------------------------------------------------*/
    size_t const callChildCount = xml_element_children_size(callElemP);

    xml_element * nameElemP;
        
    XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall"));
    
    nameElemP = getChildByName(envP, callElemP, "methodName");
    
    if (!envP->fault_occurred) {
        parseMethodNameElement(envP, nameElemP, methodNameP);
            
        if (!envP->fault_occurred) {
            /* Convert our parameters. */
            if (callChildCount > 1) {
                xml_element * paramsElemP;

                paramsElemP = getChildByName(envP, callElemP, "params");
                    
                if (!envP->fault_occurred)
                    *paramArrayPP = convertParams(envP, paramsElemP);
            } else {
                /* Workaround for Ruby XML-RPC and old versions of
                   xmlrpc-epi.  Future improvement: Instead of looking
                   at child count, we should just check for existence
                   of <params>.
                */
                *paramArrayPP = xmlrpc_array_new(envP);
            }
            if (!envP->fault_occurred) {
                if (callChildCount > 2)
                    setParseFault(envP, "<methodCall> has extraneous "
                                  "children, other than <methodName> and "
                                  "<params>.  Total child count = %u",
                                  callChildCount);
                    
                if (envP->fault_occurred)
                    xmlrpc_DECREF(*paramArrayPP);
            }
            if (envP->fault_occurred)
                xmlrpc_strfree(*methodNameP);
        }
    }
}
Exemple #11
0
static void
parseFaultElement(xmlrpc_env *        const envP,
                  const xml_element * const faultElement,
                  int *               const faultCodeP,
                  const char **       const faultStringP) {
                  
    unsigned int const maxRecursion = (unsigned int)
        xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);

    XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(faultElement), "fault"));

    if (xml_element_children_size(faultElement) != 1)
        setParseFault(envP, "<fault> element should have 1 child, "
                      "but it has %u.",
                      xml_element_children_size(faultElement));
    else {
        xml_element * const faultValueP =
            xml_element_children(faultElement)[0];
        const char * const elemName = xml_element_name(faultValueP);

        if (!xmlrpc_streq(elemName, "value"))
            setParseFault(envP,
                          "<fault> contains a <%s> element.  "
                          "Only <value> makes sense.",
                          elemName);
        else {
            xmlrpc_value * faultVP;

            xmlrpc_parseValue(envP, maxRecursion, faultValueP, &faultVP);
        
            if (!envP->fault_occurred) {
                interpretFaultValue(envP, faultVP, faultCodeP, faultStringP);
                
                xmlrpc_DECREF(faultVP);
            }
        }
    }
}
static void
parseStruct(xmlrpc_env *    const envP,
            unsigned int    const maxRecursion,
            xml_element *   const elemP,
            xmlrpc_value ** const structPP) {
/*----------------------------------------------------------------------------
   Parse the <struct> element 'elemP'.
-----------------------------------------------------------------------------*/
    xmlrpc_value * structP;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT(elemP != NULL);

    structP = xmlrpc_struct_new(envP);
    if (!envP->fault_occurred) {
        /* Iterate over our children, extracting key/value pairs. */

        xml_element ** const members = xml_element_children(elemP);
        unsigned int const size = xml_element_children_size(elemP);

        unsigned int i;

        for (i = 0; i < size && !envP->fault_occurred; ++i) {
            const char * const elemName = xml_element_name(members[i]);

            if (!xmlrpc_streq(elemName, "member"))
                setParseFault(envP, "<%s> element found where only <member> "
                              "makes sense", elemName);
            else {
                xmlrpc_value * keyP;
                xmlrpc_value * valueP;

                parseMember(envP, members[i], maxRecursion, &keyP, &valueP);

                if (!envP->fault_occurred) {
                    xmlrpc_struct_set_value_v(envP, structP, keyP, valueP);

                    xmlrpc_DECREF(keyP);
                    xmlrpc_DECREF(valueP);
                }
            }
        }
        if (envP->fault_occurred)
            xmlrpc_DECREF(structP);
        else
            *structPP = structP;
    }
}
static void
parseName(xmlrpc_env *    const envP,
          xml_element *   const nameElemP,
          xmlrpc_value ** const valuePP) {

    unsigned int const childCount = xml_element_children_size(nameElemP);

    if (childCount > 0)
        setParseFault(envP, "<name> element has %u children.  "
                      "Should have none.", childCount);
    else {
        const char * const cdata     = xml_element_cdata(nameElemP);
        size_t       const cdataSize = xml_element_cdata_size(nameElemP);

        *valuePP = xmlrpc_string_new_lp(envP, cdataSize, cdata);
    }
}
Exemple #14
0
static xml_element *
getChildByName (xmlrpc_env *  const envP,
                xml_element * const parentP,
                const char *  const name) {

    size_t const childCount = xml_element_children_size(parentP);
    xml_element ** const childrenP = xml_element_children(parentP);

    unsigned int i;

    for (i = 0; i < childCount; ++i) {
        if (xmlrpc_streq(xml_element_name(childrenP[i]), name))
            return childrenP[i];
    }
    
    setParseFault(envP, "Expected <%s> to have child <%s>",
                  xml_element_name(parentP), name);
    return NULL;
}
static void
parseBoolean(xmlrpc_env *    const envP,
             const char *    const str,
             xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Parse the content of a <boolean> XML-RPC XML element, e.g. "1".

   'str' is that content.
-----------------------------------------------------------------------------*/
    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT_PTR_OK(str);

    if (xmlrpc_streq(str, "0") || xmlrpc_streq(str, "1"))
        *valuePP = xmlrpc_bool_new(envP, xmlrpc_streq(str, "1") ? 1 : 0);
    else
        setParseFault(envP, "<boolean> XML element content must be either "
                      "'0' or '1' according to XML-RPC.  This one has '%s'",
                      str);
}
Exemple #16
0
static void
parseParamsElement(xmlrpc_env *        const envP,
                   const xml_element * const paramsElementP,
                   xmlrpc_value **     const resultPP) {

    xmlrpc_value * paramsVP;
    xmlrpc_env env;

    xmlrpc_env_init(&env);

    XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(paramsElementP), "params"));

    paramsVP = convertParams(envP, paramsElementP);

    if (!envP->fault_occurred) {
        int arraySize;
        xmlrpc_env sizeEnv;

        XMLRPC_ASSERT_ARRAY_OK(paramsVP);
        
        xmlrpc_env_init(&sizeEnv);

        arraySize = xmlrpc_array_size(&sizeEnv, paramsVP);
        /* Since it's a valid array, as asserted above, can't fail */
        XMLRPC_ASSERT(!sizeEnv.fault_occurred);

        if (arraySize != 1)
            setParseFault(envP, "Contains %d items.  It should have 1.",
                          arraySize);
        else {
            xmlrpc_array_read_item(envP, paramsVP, 0, resultPP);
        }
        xmlrpc_DECREF(paramsVP);
        xmlrpc_env_clean(&sizeEnv);
    }
    if (env.fault_occurred)
        xmlrpc_env_set_fault_formatted(
            envP, env.fault_code,
            "Invalid <params> element.  %s", env.fault_string);

    xmlrpc_env_clean(&env);
}
static void
parseDouble(xmlrpc_env *    const envP,
            const char *    const str,
            xmlrpc_value ** const valuePP) {
/*----------------------------------------------------------------------------
   Parse the content of a <double> XML-RPC XML element, e.g. "34.5".

   'str' is that content.
-----------------------------------------------------------------------------*/
    xmlrpc_env parseEnv;
    double valueDouble;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT_PTR_OK(str);

    xmlrpc_env_init(&parseEnv);

    parseDoubleString(&parseEnv, str, &valueDouble);

    if (parseEnv.fault_occurred) {
        /* As an alternative, try a strtod() parsing.  strtod()
           accepts other forms, e.g. "3.4E6"; "3,4"; " 3.4".  These
           are not permitted by XML-RPC, but an almost-XML-RPC partner
           might use one.  In fact, for many years, Xmlrpc-c generated
           such alternatives (by mistake).
        */
        bool failed;
        parseDoubleStringStrtod(str, &failed, &valueDouble);
        if (failed)
            setParseFault(envP, "<double> element value '%s' is not a valid "
                          "floating point number.  %s",
                          str, parseEnv.fault_string);
    }
    
    if (!envP->fault_occurred)
        *valuePP = xmlrpc_double_new(envP, valueDouble);

    xmlrpc_env_clean(&parseEnv);
}
static void
parseArrayDataChild(xmlrpc_env *   const envP,
                    xml_element *  const childP,
                    unsigned int   const maxRecursion,
                    xmlrpc_value * const arrayP) {

    const char * const elemName = xml_element_name(childP);

    if (!xmlrpc_streq(elemName, "value"))
        setParseFault(envP, "<data> element has <%s> child.  "
                      "Only <value> makes sense.", elemName);
    else {
        xmlrpc_value * itemP;

        xmlrpc_parseValue(envP, maxRecursion-1, childP, &itemP);

        if (!envP->fault_occurred) {
            xmlrpc_array_append_item(envP, arrayP, itemP);

            xmlrpc_DECREF(itemP);
        }
    }
}
static void
parseMember(xmlrpc_env *    const envP,
            xml_element *   const memberP,
            unsigned int    const maxRecursion,
            xmlrpc_value ** const keyPP,
            xmlrpc_value ** const valuePP) {

    unsigned int const childCount = xml_element_children_size(memberP);

    if (childCount != 2)
        setParseFault(envP,
                      "<member> element has %u children.  Only one <name> and "
                      "one <value> make sense.", childCount);
    else {
        xml_element * nameElemP;

        getNameChild(envP, memberP, &nameElemP);

        if (!envP->fault_occurred) {
            parseName(envP, nameElemP, keyPP);

            if (!envP->fault_occurred) {
                xml_element * valueElemP;

                getValueChild(envP, memberP, &valueElemP);
                
                if (!envP->fault_occurred)
                    xmlrpc_parseValue(envP, maxRecursion-1, valueElemP,
                                      valuePP);

                if (envP->fault_occurred)
                    xmlrpc_DECREF(*keyPP);
            }
        }
    }
}
Exemple #20
0
static void
parseMethodNameElement(xmlrpc_env *  const envP,
                       xml_element * const nameElemP,
                       const char ** const methodNameP) {
    
    XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(nameElemP), "methodName"));

    if (xml_element_children_size(nameElemP) > 0)
        setParseFault(envP, "A <methodName> element should not have "
                      "children.  This one has %u of them.",
                      xml_element_children_size(nameElemP));
    else {
        const char * const cdata = xml_element_cdata(nameElemP);

        xmlrpc_validate_utf8(envP, cdata, strlen(cdata));

        if (!envP->fault_occurred) {
            *methodNameP = strdup(cdata);
            if (*methodNameP == NULL)
                xmlrpc_faultf(envP,
                              "Could not allocate memory for method name");
        }
    }
}