コード例 #1
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
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);
        }
    }
}
コード例 #2
0
void 
xmlrpc_registry_free(xmlrpc_registry * registry) {

    XMLRPC_ASSERT_PTR_OK(registry);
    XMLRPC_ASSERT(registry->_methods != XMLRPC_BAD_POINTER);

    xmlrpc_DECREF(registry->_methods);
    registry->_methods = XMLRPC_BAD_POINTER;
    if (registry->_default_method != NULL)
        xmlrpc_DECREF(registry->_default_method);
    if (registry->_preinvoke_method != NULL)
        xmlrpc_DECREF(registry->_preinvoke_method);
    free(registry);
}
コード例 #3
0
void
xmlrpc_server_abyss_global_term(void) {

    /* Note that this is specified as not thread safe; user calls it at
       the end of his program, when it is only one thread.
    */

    XMLRPC_ASSERT(globallyInitialized > 0);

    --globallyInitialized;

    if (globallyInitialized == 0)
        termAbyss();
}
コード例 #4
0
void 
xmlrpc_client_cleanup() {
/*----------------------------------------------------------------------------
   This function is not thread-safe
-----------------------------------------------------------------------------*/
    XMLRPC_ASSERT(globalClientExists);

    xmlrpc_client_destroy(globalClientP);

    globalClientExists = false;

    /* The following call is not thread-safe */
    xmlrpc_client_teardown_global_const();
}
コード例 #5
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
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);
}
コード例 #6
0
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;
    }
}
コード例 #7
0
void 
xmlrpc_mem_block_append(xmlrpc_env *       const envP,
                        xmlrpc_mem_block * const blockP,
                        const void *       const data, 
                        size_t             const len) {

    size_t const originalSize = blockP->_size;

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

    xmlrpc_mem_block_resize(envP, blockP, originalSize + len);
    if (!envP->fault_occurred) {
        memcpy(((unsigned char*) blockP->_block) + originalSize, data, len);
    }
}
コード例 #8
0
static uint32_t
hashStructKey(const char * const key, 
              size_t       const keyLen) {

    uint32_t hash;
    size_t i;

    XMLRPC_ASSERT(key != NULL);
    
    /* This is the Bernstein hash, optimized for lower case ASCII
       keys.  Note that the bytes of such a key differ only in their
       lower 5 bits.
    */
    for (hash = 0, i = 0; i < keyLen; ++i)
        hash = hash + key[i] + (hash << 5);

    return hash;
}
コード例 #9
0
/* Resize an xmlrpc_mem_block, preserving as much of the contents as
   possible.
*/
void 
xmlrpc_mem_block_resize (xmlrpc_env *       const envP,
                         xmlrpc_mem_block * const blockP,
                         size_t             const size) {

    size_t proposed_alloc;
    void* new_block;

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

    /* Check to see if we already have enough space. Maybe we'll get lucky. */
    if (size <= blockP->_allocated) {
        blockP->_size = size;
        return;
    }

    /* Calculate a new allocation size. */
#ifdef EFENCE
    proposed_alloc = size;
#else
    proposed_alloc = blockP->_allocated;
    while (proposed_alloc < size && proposed_alloc <= BLOCK_ALLOC_MAX)
        proposed_alloc *= 2;
#endif /* DEBUG_MEM_ERRORS */

    if (proposed_alloc > BLOCK_ALLOC_MAX)
        XMLRPC_FAIL(envP, XMLRPC_INTERNAL_ERROR, "Memory block too large");

    /* Allocate our new memory block. */
    new_block = (void*) malloc(proposed_alloc);
    XMLRPC_FAIL_IF_NULL(new_block, envP, XMLRPC_INTERNAL_ERROR,
                        "Can't resize memory block");

    /* Copy over our data and update the xmlrpc_mem_block struct. */
    memcpy(new_block, blockP->_block, blockP->_size);
    free(blockP->_block);
    blockP->_block     = new_block;
    blockP->_size      = size;
    blockP->_allocated = proposed_alloc;

 cleanup:
    return;
}
コード例 #10
0
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;
    }
}
コード例 #11
0
/* Initialize the contents of the provided xmlrpc_mem_block. */
void
xmlrpc_mem_block_init(xmlrpc_env *       const envP,
                      xmlrpc_mem_block * const blockP,
                      size_t             const size) {

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

    blockP->_size = size;
    if (size < BLOCK_ALLOC_MIN)
        blockP->_allocated = BLOCK_ALLOC_MIN;
    else
        blockP->_allocated = size;

    blockP->_block = (void*) malloc(blockP->_allocated);
    if (!blockP->_block)
        xmlrpc_faultf(envP, "Can't allocate %u-byte memory block",
                      (unsigned)blockP->_allocated);
}
コード例 #12
0
void
xmlrpc_server_info_free(xmlrpc_server_info * const serverInfoP) {

    XMLRPC_ASSERT_PTR_OK(serverInfoP);
    XMLRPC_ASSERT(serverInfoP->serverUrl != XMLRPC_BAD_POINTER);
    
    if (serverInfoP->userNamePw)
        xmlrpc_strfree(serverInfoP->userNamePw);
    serverInfoP->userNamePw = XMLRPC_BAD_POINTER;

    if (serverInfoP->basicAuthHdrValue)
        xmlrpc_strfree(serverInfoP->basicAuthHdrValue);
    serverInfoP->basicAuthHdrValue = XMLRPC_BAD_POINTER;

    xmlrpc_strfree(serverInfoP->serverUrl);
    serverInfoP->serverUrl = XMLRPC_BAD_POINTER;

    free(serverInfoP);
}
コード例 #13
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
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);
            }
        }
    }
}
コード例 #14
0
ファイル: xmlrpc_decompose.c プロジェクト: arssivka/naomech
static void
parsearray(xmlrpc_env *const envP,
           const xmlrpc_value *const arrayP,
           struct arrayDecomp const arrayDecomp,
           bool const oldstyleMemMgmt) {

    validateArraySize(envP, arrayP, arrayDecomp);

    if (!envP->fault_occurred) {
        unsigned int doneCnt;

        doneCnt = 0;
        while (doneCnt < arrayDecomp.itemCnt && !envP->fault_occurred) {
            xmlrpc_value *itemP;

            xmlrpc_array_read_item(envP, arrayP, doneCnt, &itemP);

            if (!envP->fault_occurred) {
                XMLRPC_ASSERT(doneCnt < ARRAY_SIZE(arrayDecomp.itemArray));
                decomposeValueWithTree(envP, itemP, oldstyleMemMgmt,
                                       arrayDecomp.itemArray[doneCnt]);

                if (!envP->fault_occurred)
                    ++doneCnt;

                xmlrpc_DECREF(itemP);
            }
        }
        if (envP->fault_occurred) {
            if (!oldstyleMemMgmt) {
                /* Release the items we completed before we failed. */
                unsigned int i;
                for (i = 0; i < doneCnt; ++i)
                    releaseDecomposition(arrayDecomp.itemArray[i]);
            }
        }
    }
}
コード例 #15
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
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");
        }
    }
}            
コード例 #16
0
ファイル: utf8.c プロジェクト: arssivka/naomech
static void
decodeUtf8(xmlrpc_env *const envP,
           const char *const utf8_data,
           size_t const utf8_len,
           wchar_t *const ioBuff,
           size_t *const outBuffLenP) {
/*----------------------------------------------------------------------------
  Decode to UCS-2 (or validate as UTF-8 that can be decoded to UCS-2)
  a UTF-8 string.  To validate, set ioBuff and outBuffLenP to NULL.
  To decode, allocate a sufficiently large buffer, pass it as ioBuff,
  and pass a pointer as as outBuffLenP.  The data will be written to
  the buffer, and the length to outBuffLenP.

  We assume that wchar_t holds a single UCS-2 character in native-endian
  byte ordering.
-----------------------------------------------------------------------------*/
    size_t utf8Cursor;
    size_t outPos;

    XMLRPC_ASSERT_ENV_OK(envP);
    XMLRPC_ASSERT_PTR_OK(utf8_data);
    XMLRPC_ASSERT((!ioBuff && !outBuffLenP) || (ioBuff && outBuffLenP));

    for (utf8Cursor = 0, outPos = 0;
         utf8Cursor < utf8_len && !envP->fault_occurred;
            ) {

        char const init = utf8_data[utf8Cursor];
        /* Initial byte of the UTF-8 sequence */

        wchar_t wc;

        if ((init & 0x80) == 0x00) {
            /* Convert ASCII character to wide character. */
            wc = init;
            ++utf8Cursor;
        } else {
            /* Look up the length of this UTF-8 sequence. */
            size_t const length = utf8SeqLength[(unsigned char) init];
            /* Special value 0 means no length could be determined because
               it is not a valid initial byte for a UTF-8 sequence.
            */
            if (length == 0)
                xmlrpc_env_set_fault_formatted(
                        envP, XMLRPC_INVALID_UTF8_ERROR,
                        "Unrecognized UTF-8 initial byte value 0x%02x",
                        (unsigned char) init);
            else {
                /* Make sure we have enough bytes to convert. */
                if (utf8Cursor + length > utf8_len) {
                    xmlrpc_env_set_fault_formatted(
                            envP, XMLRPC_INVALID_UTF8_ERROR,
                            "Invalid UTF-8 sequence indicates a %u-byte sequence "
                                    "when only %u bytes are left in the string",
                            (unsigned) length, (unsigned) (utf8_len - utf8Cursor));
                } else {
                    decodeMultibyte(envP, &utf8_data[utf8Cursor], length, &wc);

                    /* Advance to the end of the sequence. */
                    utf8Cursor += length;
                }
            }
        }

        if (!envP->fault_occurred) {
            /* If we have a buffer, write our character to it. */
            if (ioBuff)
                ioBuff[outPos++] = wc;
        }
    }

    if (outBuffLenP)
        *outBuffLenP = envP->fault_occurred ? 0 : outPos;
}
コード例 #17
0
static void 
decomposeValueWithTree(xmlrpc_env *                  const envP,
                       xmlrpc_value *                const valueP,
                       bool                          const oldstyleMemMgmt,
                       const struct decompTreeNode * const decompRootP) {
/*----------------------------------------------------------------------------
   Decompose XML-RPC value *valueP, given the decomposition tree
   *decompRootP.  The decomposition tree tells what structure *valueP
   is expected to have and where to put the various components of it
   (e.g. it says "it's an array of 3 integers.  Put their values at
   locations x, y, and z")
-----------------------------------------------------------------------------*/
    switch (decompRootP->formatSpecChar) {
    case '-':
        /* There's nothing to validate or return */
        break;
    case 'i':
        xmlrpc_read_int(envP, valueP, decompRootP->store.Tinteger.valueP);
        break;

    case 'b':
        xmlrpc_read_bool(envP, valueP, decompRootP->store.Tbool.valueP);
        break;

    case 'd':
        xmlrpc_read_double(envP, valueP, decompRootP->store.Tdouble.valueP);
        break;

    case 't':
        xmlrpc_read_datetime_sec(envP, valueP,
                                 decompRootP->store.TdatetimeT.valueP);
        break;

    case '8':
        readDatetime8Str(envP, valueP, decompRootP->store.Tdatetime8.valueP,
                         oldstyleMemMgmt);
        break;

    case 's':
        if (decompRootP->store.Tstring.sizeP)
            readStringLp(envP, valueP,
                         decompRootP->store.Tstring.sizeP,
                         decompRootP->store.Tstring.valueP,
                         oldstyleMemMgmt);
        else
            readString(envP, valueP, decompRootP->store.Tstring.valueP,
                       oldstyleMemMgmt);
        break;

    case 'w':
#if HAVE_UNICODE_WCHAR
        if (decompRootP->store.Tstring.sizeP)
            readStringWLp(envP, valueP,
                          decompRootP->store.TwideString.sizeP,
                          decompRootP->store.TwideString.valueP,
                          oldstyleMemMgmt);
        else
            readStringW(envP, valueP, decompRootP->store.TwideString.valueP,
                        oldstyleMemMgmt);
#else
        XMLRPC_ASSERT(false);
#endif /* HAVE_UNICODE_WCHAR */
        break;
        
    case '6':
        readBase64(envP, valueP,
                   decompRootP->store.TbitString.sizeP,
                   decompRootP->store.TbitString.valueP,
                   oldstyleMemMgmt);
        break;

    case 'n':
        xmlrpc_read_nil(envP, valueP);
        break;

    case 'I':
        xmlrpc_read_i8(envP, valueP, decompRootP->store.Ti8.valueP);
        break;

    case 'p':
        xmlrpc_read_cptr(envP, valueP, decompRootP->store.Tcptr.valueP);
        break;

    case 'V':
        *decompRootP->store.Tvalue.valueP = valueP;
        if (!oldstyleMemMgmt)
            xmlrpc_INCREF(valueP);
        break;

    case 'A':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'A' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TarrayVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case 'S':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'S' specifier requires type STRUCT.",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TstructVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case '(':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '(...)' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsearray(envP, valueP, decompRootP->store.Tarray,
                       oldstyleMemMgmt);
        break;

    case '{':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '{...}' specifier requires type STRUCT",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsestruct(envP, valueP, decompRootP->store.Tstruct,
                        oldstyleMemMgmt);
        break;

    default:
        /* Every format character that is allowed in a decomposition tree
           node is handled above.
        */
        XMLRPC_ASSERT(false);
    }
}
コード例 #18
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
static xmlrpc_value *
convertParams(xmlrpc_env *        const envP,
              const xml_element * const elemP) {
/*----------------------------------------------------------------------------
   Convert an XML element representing a list of parameters (i.e.  a <params>
   element) to an xmlrpc_value of type array.  Note that an xmlrpc_value is
   normally represented in XML by a <value> element, not a <params> element.
   We use type xmlrpc_value to represent the parameter list just for
   convenience.
-----------------------------------------------------------------------------*/
    xmlrpc_value * arrayP;
    xmlrpc_value * itemP;
    unsigned int i;
    unsigned int size;
    xml_element ** params;

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

    /* Set up our error-handling preconditions. */
    arrayP = itemP = NULL;

    /* Allocate an array to hold our parameters. */
    arrayP = xmlrpc_build_value(envP, "()");
    XMLRPC_FAIL_IF_FAULT(envP);

    /* We're responsible for checking our own element name. */
    CHECK_NAME(envP, elemP, "params");    

    /* Iterate over our children. */
    size = xml_element_children_size(elemP);
    params = xml_element_children(elemP);
    for (i = 0; i < size; ++i) {
        xml_element * const paramP = params[i];
        unsigned int const maxNest = (unsigned int)
            xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID);

        xml_element * valueEltP;

        CHECK_NAME(envP, paramP, "param");
        CHECK_CHILD_COUNT(envP, paramP, 1);

        valueEltP = xml_element_children(paramP)[0];

        CHECK_NAME(envP, valueEltP, "value");

        xmlrpc_parseValue(envP, maxNest, valueEltP, &itemP);
        XMLRPC_FAIL_IF_FAULT(envP);

        xmlrpc_array_append_item(envP, arrayP, itemP);
        xmlrpc_DECREF(itemP);
        itemP = NULL;
        XMLRPC_FAIL_IF_FAULT(envP);
    }

 cleanup:
    if (envP->fault_occurred) {
        if (arrayP)
            xmlrpc_DECREF(arrayP);
        if (itemP)
            xmlrpc_DECREF(itemP);
        return NULL;
    }
    return arrayP;
}
コード例 #19
0
/* Get the contents of the xmlrpc_mem_block. */
void * 
xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) {

    XMLRPC_ASSERT(blockP != NULL);
    return blockP->_block;
}
コード例 #20
0
ファイル: xmlrpc_parse.c プロジェクト: TekatoD/xmlrpc-c
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 * responseEltP;

    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",
            (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID),
            (unsigned)xmlDataLen);
    else {
        xmlrpc_env env;
        xmlrpc_env_init(&env);

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

        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(responseEltP),
                             "methodResponse")) {
                parseMethodResponseElt(envP, responseEltP,
                                       resultPP, faultCodeP, faultStringP);
            } else
                setParseFault(envP, "XML-RPC response must consist of a "
                              "<methodResponse> element.  "
                              "This has a <%s> instead.",
                              xml_element_name(responseEltP));
            
            xml_element_free(responseEltP);
        }
        xmlrpc_env_clean(&env);
    }
}
コード例 #21
0
/* Get the size of the xmlrpc_mem_block. */
size_t 
xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) {

    XMLRPC_ASSERT(blockP != NULL);
    return blockP->_size;
}