mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 01:26:58 +00:00
FS-2746 --resolve large xmlrpc update thanks garmt
This commit is contained in:
@@ -33,6 +33,11 @@ OMIT_UTILS_RULE = Y
|
||||
|
||||
include $(SRCDIR)/common.mk
|
||||
|
||||
# This 'common.mk' dependency makes sure the symlinks get built before
|
||||
# this make file is used for anything.
|
||||
|
||||
$(SRCDIR)/common.mk: srcdir blddir
|
||||
|
||||
LIBOBJS = \
|
||||
casprintf.o \
|
||||
cmdline_parser.o \
|
||||
@@ -44,17 +49,15 @@ LIBOBJS = \
|
||||
.PHONY: all
|
||||
all: $(LIBOBJS)
|
||||
|
||||
INCLUDES = -I$(SRCDIR)/$(SUBDIR)/include -I$(BLDDIR)
|
||||
|
||||
CFLAGS = $(CFLAGS_COMMON) $(INCLUDES) $(CFLAGS_PERSONAL) $(CADD)
|
||||
INCLUDES = -Isrcdir/$(SUBDIR)/include -I$(BLDDIR)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
$(CC) -c $(CFLAGS_ALL) $<
|
||||
|
||||
%.o:%.cpp
|
||||
$(CXX) -c $(CFLAGS) $<
|
||||
$(CXX) -c $(CXXFLAGS_ALL) $<
|
||||
|
||||
include Makefile.depend
|
||||
include depend.mk
|
||||
|
||||
.PHONY: clean distclean
|
||||
clean: clean-common
|
||||
|
@@ -1,13 +1,62 @@
|
||||
//#define _GNU_SOURCE
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */
|
||||
#include "bool.h"
|
||||
#include "casprintf.h"
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ void
|
||||
simpleVasprintf(char ** const retvalP,
|
||||
const char * const fmt,
|
||||
@@ -15,29 +64,24 @@ simpleVasprintf(char ** const retvalP,
|
||||
/*----------------------------------------------------------------------------
|
||||
This is a poor man's implementation of vasprintf(), of GNU fame.
|
||||
-----------------------------------------------------------------------------*/
|
||||
size_t const initialSize = 4096;
|
||||
char * result;
|
||||
size_t bufferSize;
|
||||
bool outOfMemory;
|
||||
|
||||
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.
|
||||
*/
|
||||
for (result = NULL, bufferSize = 4096, outOfMemory = false;
|
||||
!result && !outOfMemory;
|
||||
) {
|
||||
|
||||
result = malloc(bufferSize);
|
||||
if (!result)
|
||||
outOfMemory = true;
|
||||
else {
|
||||
size_t bytesNeeded;
|
||||
newVsnprintf(result, bufferSize, fmt, varargs, &bytesNeeded);
|
||||
if (bytesNeeded > bufferSize) {
|
||||
free(result);
|
||||
result = NULL;
|
||||
bufferSize = bytesNeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#define _XOPEN_SOURCE 600 /* Make sure <string.h> has strdup() */
|
||||
|
||||
#include "xmlrpc_config.h" /* prereq for mallocvar.h -- defines __inline__ */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@@ -11,6 +11,14 @@
|
||||
long long mask= ULL(1) << 33;
|
||||
*/
|
||||
|
||||
/* 'uint' is quite convenient, but there's no simple way have it everywhere.
|
||||
Some systems have it in the base system (e.g. GNU C library has it in
|
||||
<sys/types.h>, and others (e.g. Solaris - 08.12.02) don't. Since we
|
||||
can't define it unless we know it's not defined already, and we don't
|
||||
want to burden the reader with a special Xmlrpc-c name such as xuint,
|
||||
we just use standard "unsigned int" instead.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define PRId64 "I64d"
|
||||
# define PRIu64 "I64u"
|
||||
@@ -33,9 +41,6 @@ typedef __int64 int64_t;
|
||||
#ifndef uint64_t
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#endif
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
#ifndef uint8_t
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
@@ -44,6 +49,11 @@ typedef unsigned char uint8_t;
|
||||
#define LL(x) x ## i64
|
||||
#define ULL(x) x ## u64
|
||||
|
||||
#elif defined(__INTERIX)
|
||||
# include <stdint.h>
|
||||
# define PRId64 "I64d"
|
||||
# define PRIu64 "I64u"
|
||||
|
||||
#else
|
||||
/* Not Microsoft compiler */
|
||||
#include <inttypes.h>
|
||||
|
@@ -18,7 +18,7 @@
|
||||
static __inline__ void
|
||||
mallocProduct(void ** const resultP,
|
||||
unsigned int const factor1,
|
||||
unsigned int const factor2) {
|
||||
size_t const factor2) {
|
||||
/*----------------------------------------------------------------------------
|
||||
malloc a space whose size in bytes is the product of 'factor1' and
|
||||
'factor2'. But if that size cannot be represented as an unsigned int,
|
||||
@@ -102,7 +102,7 @@ do { \
|
||||
|
||||
|
||||
#define MALLOCVAR(varName) \
|
||||
if (varName = malloc(sizeof(*varName))) memset(varName, 0, sizeof(*varName))
|
||||
varName = malloc(sizeof(*varName))
|
||||
|
||||
#define MALLOCVAR_NOFAIL(varName) \
|
||||
do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0)
|
||||
|
@@ -26,10 +26,12 @@
|
||||
#ifndef PTHREADX_H_INCLUDED
|
||||
#define PTHREADX_H_INCLUDED
|
||||
|
||||
#ifndef WIN32
|
||||
#include "xmlrpc_config.h"
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
# define _REENTRANT
|
||||
# include <pthread.h>
|
||||
#elif defined (WIN32)
|
||||
#elif HAVE_WINDOWS_THREAD
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -52,11 +54,7 @@ struct {
|
||||
int attrs; /* currently unused. placeholder. */
|
||||
} pthread_mutexattr_t;
|
||||
|
||||
/* We make pthread_func identical to a Windows thread start function
|
||||
so we can use Windows thread functions to implement these pthread
|
||||
functions directly.
|
||||
*/
|
||||
typedef unsigned (WINAPI pthread_func)(void *);
|
||||
typedef void * pthread_func(void *);
|
||||
|
||||
extern int pthread_create(pthread_t * const new_thread_ID,
|
||||
const pthread_attr_t * const attr,
|
||||
@@ -75,6 +73,10 @@ extern int pthread_mutex_destroy(pthread_mutex_t * const mp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* WIN32 */
|
||||
#else /* HAVE_WINDOWS_THREAD */
|
||||
#error "You don't have any thread facility. (According to "
|
||||
#error "HAVE_PTHREAD and HAVE_WINDOWS_THREAD macros defined in "
|
||||
#error "xmlrpc_config.h)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -1,15 +0,0 @@
|
||||
#ifndef SSTRING_H_INCLUDED
|
||||
#define SSTRING_H_INCLUDED
|
||||
|
||||
/* This file contains string functions that are cognizant of the
|
||||
declared size of the destination data structure.
|
||||
*/
|
||||
|
||||
|
||||
/* Copy string pointed by B to array A with size checking. */
|
||||
#define SSTRCPY(A,B) \
|
||||
(strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0')
|
||||
#define SSTRCMP(A,B) \
|
||||
(strncmp((A), (B), sizeof(A)))
|
||||
|
||||
#endif
|
@@ -56,7 +56,7 @@ init_va_listx(va_listx * const argsxP,
|
||||
#if VA_LIST_IS_ARRAY
|
||||
/* 'args' is NOT a va_list. It is a pointer to the first element of a
|
||||
'va_list', which is the same address as a pointer to the va_list
|
||||
itself.
|
||||
itself. (That's what happens when you pass an array in C).
|
||||
*/
|
||||
memcpy(&argsxP->v, args, sizeof(argsxP->v));
|
||||
#else
|
||||
|
@@ -25,31 +25,65 @@
|
||||
|
||||
#include "xmlrpc_config.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
|
||||
#include "mallocvar.h"
|
||||
|
||||
#include "pthreadx.h"
|
||||
|
||||
#include <process.h>
|
||||
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
|
||||
struct winStartArg {
|
||||
pthread_func * func;
|
||||
void * arg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static unsigned int __stdcall
|
||||
winThreadStart(void * const arg) {
|
||||
/*----------------------------------------------------------------------------
|
||||
This is a thread start/root function for the Windows threading facility
|
||||
(i.e. this can be an argument to _beginthreadex()).
|
||||
|
||||
All we do is call the real start/root function, which expects to be
|
||||
called in the pthread format.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct winStartArg * const winStartArgP = arg;
|
||||
|
||||
winStartArgP->func(winStartArgP->arg);
|
||||
|
||||
free(winStartArgP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
pthread_create(pthread_t * const new_thread_ID,
|
||||
pthread_create(pthread_t * const newThreadIdP,
|
||||
const pthread_attr_t * const attr,
|
||||
pthread_func * func,
|
||||
void * const arg) {
|
||||
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadID;
|
||||
struct winStartArg * winStartArgP;
|
||||
|
||||
hThread = (HANDLE) _beginthreadex (
|
||||
NULL, 0, func, (LPVOID)arg, CREATE_SUSPENDED, &dwThreadID);
|
||||
MALLOCVAR_NOFAIL(winStartArgP);
|
||||
|
||||
SetThreadPriority (hThread, THREAD_PRIORITY_NORMAL);
|
||||
ResumeThread (hThread);
|
||||
winStartArgP->func = func;
|
||||
winStartArgP->arg = arg;
|
||||
|
||||
*new_thread_ID = hThread;
|
||||
hThread = (HANDLE) _beginthreadex(
|
||||
NULL, 0, &winThreadStart, (LPVOID)winStartArgP, CREATE_SUSPENDED,
|
||||
&dwThreadID);
|
||||
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL);
|
||||
ResumeThread(hThread);
|
||||
|
||||
*newThreadIdP = hThread;
|
||||
|
||||
return hThread ? 0 : -1;
|
||||
}
|
||||
@@ -119,5 +153,3 @@ pthread_mutex_destroy(pthread_mutex_t * const mp) {
|
||||
DeleteCriticalSection(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -50,7 +50,7 @@ interpretUll(const char * const string,
|
||||
|
||||
errno = 0; /* So we can tell if strtoull() overflowed */
|
||||
|
||||
*ullP = strtoull(strippedString, &tail, 10);
|
||||
*ullP = XMLRPC_STRTOULL(strippedString, &tail, 10);
|
||||
|
||||
if (tail[0] != '\0')
|
||||
casprintf(errorP, "Non-digit stuff in string: %s", tail);
|
||||
@@ -80,7 +80,7 @@ interpretLl(const char * const string,
|
||||
|
||||
errno = 0; /* So we can tell if strtoll() overflowed */
|
||||
|
||||
*llP = strtoll(string, &tail, 10);
|
||||
*llP = XMLRPC_STRTOLL(string, &tail, 10);
|
||||
|
||||
if (tail[0] != '\0')
|
||||
casprintf(errorP, "Non-digit stuff in string: %s", tail);
|
||||
@@ -94,9 +94,9 @@ interpretLl(const char * const string,
|
||||
|
||||
|
||||
void
|
||||
interpretUint(const char * const string,
|
||||
uint * const uintP,
|
||||
const char ** const errorP) {
|
||||
interpretUint(const char * const string,
|
||||
unsigned int * const uintP,
|
||||
const char ** const errorP) {
|
||||
|
||||
/* strtoul() does a lousy job of dealing with invalid numbers. A null
|
||||
string is just zero; a negative number is a large positive one; a
|
||||
|
@@ -1,4 +1,3 @@
|
||||
//#define _GNU_SOURCE
|
||||
#include <ctype.h>
|
||||
|
||||
#include "bool.h"
|
||||
|
Reference in New Issue
Block a user