mirror of
https://github.com/curl/curl.git
synced 2025-04-12 16:20:35 +08:00
fix handling of out of memory in the command line tool that afected
data url encoded HTTP POSTs when reading it from a file.
This commit is contained in:
parent
3ee32d7920
commit
3d55877764
4
CHANGES
4
CHANGES
@ -6,6 +6,10 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Yang Tse (16 Jan 2008)
|
||||
- Improved handling of out of memory in the command line tool that afected
|
||||
data url encoded HTTP POSTs when reading it from a file.
|
||||
|
||||
Daniel S (16 Jan 2008)
|
||||
- Dmitry Kurochkin worked a lot on improving the HTTP Pipelining support that
|
||||
previously had a number of flaws, perhaps most notably when an application
|
||||
|
@ -55,6 +55,7 @@ This release includes the following bugfixes:
|
||||
o libcurl hang with huge POST request and request-body read from callback
|
||||
o removed extra newlines from many error messages
|
||||
o improved pipelining
|
||||
o improved OOM handling for data url encoded HTTP POSTs when read from a file
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
|
169
src/main.c
169
src/main.c
@ -803,71 +803,6 @@ static void GetStr(char **string,
|
||||
*string = NULL;
|
||||
}
|
||||
|
||||
static char *file2string(FILE *file)
|
||||
{
|
||||
char buffer[256];
|
||||
char *ptr;
|
||||
char *string=NULL;
|
||||
size_t len=0;
|
||||
size_t stringlen;
|
||||
|
||||
if(file) {
|
||||
while(fgets(buffer, sizeof(buffer), file)) {
|
||||
ptr= strchr(buffer, '\r');
|
||||
if(ptr)
|
||||
*ptr=0;
|
||||
ptr= strchr(buffer, '\n');
|
||||
if(ptr)
|
||||
*ptr=0;
|
||||
stringlen=strlen(buffer);
|
||||
if(string)
|
||||
string = realloc(string, len+stringlen+1);
|
||||
else
|
||||
string = malloc(stringlen+1);
|
||||
|
||||
strcpy(string+len, buffer);
|
||||
|
||||
len+=stringlen;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
else
|
||||
return NULL; /* no string */
|
||||
}
|
||||
|
||||
static char *file2memory(FILE *file, long *size)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *string=NULL;
|
||||
char *newstring=NULL;
|
||||
size_t len=0;
|
||||
long stringlen=0;
|
||||
|
||||
if(file) {
|
||||
while((len = fread(buffer, 1, sizeof(buffer), file))) {
|
||||
if(string) {
|
||||
newstring = realloc(string, len+stringlen+1);
|
||||
if(newstring)
|
||||
string = newstring;
|
||||
else
|
||||
break; /* no more strings attached! :-) */
|
||||
}
|
||||
else
|
||||
string = malloc(len+1);
|
||||
memcpy(&string[stringlen], buffer, len);
|
||||
stringlen+=len;
|
||||
}
|
||||
if (string) {
|
||||
/* NUL terminate the buffer in case it's treated as a string later */
|
||||
string[stringlen] = 0;
|
||||
}
|
||||
*size = stringlen;
|
||||
return string;
|
||||
}
|
||||
else
|
||||
return NULL; /* no string */
|
||||
}
|
||||
|
||||
static void clean_getout(struct Configurable *config)
|
||||
{
|
||||
struct getout *node=config->url_list;
|
||||
@ -1310,6 +1245,82 @@ static const char *param2text(int res)
|
||||
}
|
||||
}
|
||||
|
||||
static ParameterError file2string(char **bufp, FILE *file)
|
||||
{
|
||||
char buffer[256];
|
||||
char *ptr;
|
||||
char *string = NULL;
|
||||
size_t stringlen = 0;
|
||||
size_t buflen;
|
||||
|
||||
if(file) {
|
||||
while(fgets(buffer, sizeof(buffer), file)) {
|
||||
if((ptr = strchr(buffer, '\r')) != NULL)
|
||||
*ptr = '\0';
|
||||
if((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
buflen = strlen(buffer);
|
||||
if((ptr = realloc(string, stringlen+buflen+1)) == NULL) {
|
||||
if(string)
|
||||
free(string);
|
||||
return PARAM_NO_MEM;
|
||||
}
|
||||
string = ptr;
|
||||
strcpy(string+stringlen, buffer);
|
||||
stringlen += buflen;
|
||||
}
|
||||
}
|
||||
*bufp = string;
|
||||
return PARAM_OK;
|
||||
}
|
||||
|
||||
static ParameterError file2memory(char **bufp, size_t *size, FILE *file)
|
||||
{
|
||||
char *newbuf;
|
||||
char *buffer = NULL;
|
||||
size_t alloc = 512;
|
||||
size_t nused = 0;
|
||||
size_t nread;
|
||||
|
||||
if(file) {
|
||||
do {
|
||||
if(!buffer || (alloc == nused)) {
|
||||
/* size_t overflow detection for huge files */
|
||||
if(alloc+1 > ((size_t)-1)/2) {
|
||||
if(buffer)
|
||||
free(buffer);
|
||||
return PARAM_NO_MEM;
|
||||
}
|
||||
alloc *= 2;
|
||||
/* allocate an extra char, reserved space, for null termination */
|
||||
if((newbuf = realloc(buffer, alloc+1)) == NULL) {
|
||||
if(buffer)
|
||||
free(buffer);
|
||||
return PARAM_NO_MEM;
|
||||
}
|
||||
buffer = newbuf;
|
||||
}
|
||||
nread = fread(buffer+nused, 1, alloc-nused, file);
|
||||
nused += nread;
|
||||
} while(nread);
|
||||
/* null terminate the buffer in case it's used as a string later */
|
||||
buffer[nused] = '\0';
|
||||
/* free trailing slack space, if possible */
|
||||
if(alloc != nused) {
|
||||
if((newbuf = realloc(buffer, nused+1)) != NULL)
|
||||
buffer = newbuf;
|
||||
}
|
||||
/* discard buffer if nothing was read */
|
||||
if(!nused) {
|
||||
free(buffer);
|
||||
buffer = NULL; /* no string */
|
||||
}
|
||||
}
|
||||
*size = nused;
|
||||
*bufp = buffer;
|
||||
return PARAM_OK;
|
||||
}
|
||||
|
||||
static void cleanarg(char *str)
|
||||
{
|
||||
#ifdef HAVE_WRITABLE_ARGV
|
||||
@ -2158,7 +2169,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
* the content.
|
||||
*/
|
||||
char *p = strchr(nextarg, '=');
|
||||
long size = 0;
|
||||
size_t size = 0;
|
||||
size_t nlen;
|
||||
char is_file;
|
||||
if(!p)
|
||||
@ -2188,14 +2199,16 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
"an empty POST.\n", nextarg);
|
||||
}
|
||||
|
||||
postdata = file2memory(file, &size);
|
||||
err = file2memory(&postdata, &size, file);
|
||||
|
||||
if(file && (file != stdin))
|
||||
fclose(file);
|
||||
if(err)
|
||||
return err;
|
||||
}
|
||||
else {
|
||||
GetStr(&postdata, p);
|
||||
size = (long)strlen(postdata);
|
||||
size = strlen(postdata);
|
||||
}
|
||||
|
||||
if(!postdata) {
|
||||
@ -2229,6 +2242,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
}
|
||||
}
|
||||
else if('@' == *nextarg) {
|
||||
size_t size = 0;
|
||||
/* the data begins with a '@' letter, it means that a file name
|
||||
or - (stdin) follows */
|
||||
nextarg++; /* pass the @ */
|
||||
@ -2245,13 +2259,18 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
"an empty POST.\n", nextarg);
|
||||
}
|
||||
|
||||
if(subletter == 'b') /* forced binary */
|
||||
postdata = file2memory(file, &config->postfieldsize);
|
||||
if(subletter == 'b') {
|
||||
/* forced binary */
|
||||
err = file2memory(&postdata, &size, file);
|
||||
config->postfieldsize = size;
|
||||
}
|
||||
else
|
||||
postdata = file2string(file);
|
||||
err = file2string(&postdata, file);
|
||||
|
||||
if(file && (file != stdin))
|
||||
fclose(file);
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
if(!postdata) {
|
||||
/* no data from the file, point to a zero byte string to make this
|
||||
@ -2714,11 +2733,13 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
file = stdin;
|
||||
else
|
||||
file = fopen(nextarg, "r");
|
||||
config->writeout = file2string(file);
|
||||
if(!config->writeout)
|
||||
warnf(config, "Failed to read %s", file);
|
||||
err = file2string(&config->writeout, file);
|
||||
if(file && (file != stdin))
|
||||
fclose(file);
|
||||
if(err)
|
||||
return err;
|
||||
if(!config->writeout)
|
||||
warnf(config, "Failed to read %s", file);
|
||||
}
|
||||
else
|
||||
GetStr(&config->writeout, nextarg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user