Exemplo n.º 1
0
static __inline__ void
simpleVasprintf(char **      const retvalP,
                const char * const fmt,
                va_list            varargs) {
/*----------------------------------------------------------------------------
   This is a poor man's implementation of vasprintf(), of GNU fame.
-----------------------------------------------------------------------------*/
    size_t const initialSize = 4096;
    char * result;

    result = malloc(initialSize);
    if (result != NULL) {
        size_t bytesNeeded;
        bytesNeeded = XMLRPC_VSNPRINTF(result, initialSize, fmt, varargs);
        if (bytesNeeded > initialSize) {
            free(result);
            result = malloc(bytesNeeded);
            if (result != NULL)
                XMLRPC_VSNPRINTF(result, bytesNeeded, fmt, varargs);
        } else if (bytesNeeded == initialSize) {
            if (result[initialSize-1] != '\0') {
                /* This is one of those old systems where vsnprintf()
                   returns the number of bytes it used, instead of the
                   number that it needed, and it in fact needed more than
                   we gave it.  Rather than mess with this highly unlikely
                   case (old system and string > 4095 characters), we just
                   treat this like an out of memory failure.
                */
                free(result);
                result = NULL;
            }
        }
    }
    *retvalP = result;
}
Exemplo n.º 2
0
static void 
formatOut(xmlrpc_env *       const envP,
          xmlrpc_mem_block * const outputP,
          const char *       const formatString,
          ...) {
/*----------------------------------------------------------------------------
  A lightweight print routine for use with various serialization
  functions.

  Use this routine only for printing small objects -- it uses a
  fixed-size internal buffer and returns an error on overflow.  In
  particular, do NOT use this routine to print XML-RPC string values!
-----------------------------------------------------------------------------*/
    va_list args;
    char buffer[128];
    int rc;

    XMLRPC_ASSERT_ENV_OK(envP);

    va_start(args, formatString);

    rc = XMLRPC_VSNPRINTF(buffer, sizeof(buffer), formatString, args);

    /* Old vsnprintf() (and Windows) fails with return value -1 if the full
       string doesn't fit in the buffer.  New vsnprintf() puts whatever will
       fit in the buffer, and returns the length of the full string
       regardless.  For us, this truncation is a failure.
    */

    if (rc < 0)
        xmlrpc_faultf(envP, "formatOut() overflowed internal buffer");
    else {
        unsigned int const formattedLen = rc;

        if (formattedLen + 1 >= (sizeof(buffer)))
            xmlrpc_faultf(envP, "formatOut() overflowed internal buffer");
        else
            XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen);
    }
    va_end(args);
}
Exemplo n.º 3
0
static __inline__ void
newVsnprintf(char *       const buffer,
             size_t       const bufferSize,
             const char * const fmt,
             va_list            varargs,
             size_t *     const formattedSizeP) {
/*----------------------------------------------------------------------------
   This is vsnprintf() with the new behavior, where not fitting in the buffer
   is not a failure.

   Unfortunately, we can't practically return the size of the formatted string
   if the C library has old vsnprintf() and the formatted string doesn't fit
   in the buffer, so in that case we just return something larger than the
   buffer.
-----------------------------------------------------------------------------*/
    if (bufferSize > INT_MAX/2) {
        /* There's a danger we won't be able to coerce the return value
           of XMLRPC_VSNPRINTF to an integer (which we have to do because,
           while for POSIX its return value is ssize_t, on Windows it is int),
           or return double the buffer size.
        */
        *formattedSizeP = 0;
    } else {
        int rc;

        rc = XMLRPC_VSNPRINTF(buffer, bufferSize, fmt, varargs);

        if (rc < 0) {
            /* We have old vsnprintf() (or Windows) and the formatted value
               doesn't fit in the buffer, but we don't know how big a buffer it
               needs.
            */
            *formattedSizeP = bufferSize * 2;
        } else {
            /* Either the string fits in the buffer or we have new vsnprintf()
               which tells us how big the string is regardless.
            */
            *formattedSizeP = rc;
        }
    }
}
Exemplo n.º 4
0
static void 
formatOut(xmlrpc_env *       const envP,
          xmlrpc_mem_block * const outputP,
          const char *       const formatString,
          ...) {
/*----------------------------------------------------------------------------
  A lightweight print routine for use with various serialization
  functions.

  Use this routine only for printing small objects -- it uses a
  fixed-size internal buffer and returns an error on overflow.  In
  particular, do NOT use this routine to print XML-RPC string values!
-----------------------------------------------------------------------------*/
    va_list args;
    char buffer[SMALL_BUFFER_SZ];
    int count;

    XMLRPC_ASSERT_ENV_OK(envP);

    va_start(args, formatString);

    count = XMLRPC_VSNPRINTF(buffer, SMALL_BUFFER_SZ, formatString, args);

    /* Old C libraries return -1 if vsnprintf overflows its buffer.
    ** New C libraries return the number of characters which *would* have
    ** been printed if the error did not occur. This is impressively vile.
    ** Thank the C99 committee for this bright idea. But wait! We also
    ** need to keep track of the trailing NUL. */

    if (count < 0 || count >= (SMALL_BUFFER_SZ - 1))
        xmlrpc_faultf(envP, "formatOut() overflowed internal buffer");
    else
        XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, count);

    va_end(args);
}