From 7296b2aa256049bec7ea7a372dee5cb319c7feca Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 5 Oct 2011 22:01:42 +0200 Subject: curl tool: OOM handling fixes --- src/tool_operate.c | 30 ++++++++++++++++++++++-------- src/tool_urlglob.c | 35 ++++++++++++++++++++++++----------- src/tool_urlglob.h | 4 ++-- 3 files changed, 48 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/tool_operate.c b/src/tool_operate.c index b7da80a71..9a06098a0 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -441,10 +441,18 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(!up && !infiles) Curl_nop_stmt; else { - if(inglob) - uploadfile = glob_next_url(inglob); - else if(!up) + if(inglob) { + res = glob_next_url(&uploadfile, inglob); + if(res == CURLE_OUT_OF_MEMORY) + helpf(config->errors, "out of memory\n"); + } + else if(!up) { uploadfile = strdup(infiles); + if(!uploadfile) { + helpf(config->errors, "out of memory\n"); + res = CURLE_OUT_OF_MEMORY; + } + } else uploadfile = NULL; if(!uploadfile) @@ -492,10 +500,17 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) outs.stream = stdout; outs.config = config; - if(urls) - this_url = glob_next_url(urls); + if(urls) { + res = glob_next_url(&this_url, urls); + if(res) + goto show_error; + } else if(!i) { this_url = strdup(urlnode->url); + if(!this_url) { + res = CURLE_OUT_OF_MEMORY; + goto show_error; + } } else this_url = NULL; @@ -541,12 +556,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) else if(urls) { /* fill '#1' ... '#9' terms from URL pattern */ char *storefile = outfile; - outfile = glob_match_url(storefile, urls); + res = glob_match_url(&outfile, storefile, urls); Curl_safefree(storefile); - if(!outfile) { + if(res) { /* bad globbing */ warnf(config, "bad output glob!\n"); - res = CURLE_FAILED_INIT; goto quit_urls; } } diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 108fc3987..f5c09a1e8 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -419,7 +419,7 @@ void glob_cleanup(URLGlob* glob) Curl_safefree(glob); } -char *glob_next_url(URLGlob *glob) +int glob_next_url(char **globbed, URLGlob *glob) { URLPattern *pat; char *lit; @@ -429,6 +429,8 @@ char *glob_next_url(URLGlob *glob) size_t buflen = glob->urllen + 1; char *buf = glob->glob_buffer; + *globbed = NULL; + if(!glob->beenhere) glob->beenhere = 1; else { @@ -464,11 +466,13 @@ char *glob_next_url(URLGlob *glob) break; default: printf("internal error: invalid pattern type (%d)\n", (int)pat->type); - exit (CURLE_FAILED_INIT); + return CURLE_FAILED_INIT; } } - if(carry) /* first pattern ptr has run into overflow, done! */ - return NULL; + if(carry) { /* first pattern ptr has run into overflow, done! */ + /* TODO: verify if this should actally return CURLE_OK. */ + return CURLE_OK; /* CURLE_OK to match previous behavior */ + } } for(j = 0; j < glob->size; ++j) { @@ -502,15 +506,20 @@ char *glob_next_url(URLGlob *glob) break; default: printf("internal error: invalid pattern type (%d)\n", (int)pat->type); - exit (CURLE_FAILED_INIT); + return CURLE_FAILED_INIT; } } } *buf = '\0'; - return strdup(glob->glob_buffer); + + *globbed = strdup(glob->glob_buffer); + if(!*globbed) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; } -char *glob_match_url(char *filename, URLGlob *glob) +int glob_match_url(char **result, char *filename, URLGlob *glob) { char *target; size_t allocsize; @@ -519,6 +528,8 @@ char *glob_match_url(char *filename, URLGlob *glob) size_t appendlen = 0; size_t stringlen = 0; + *result = NULL; + /* We cannot use the glob_buffer for storage here since the filename may * be longer than the URL we use. We allocate a good start size, then * we need to realloc in case of need. @@ -527,7 +538,7 @@ char *glob_match_url(char *filename, URLGlob *glob) trailing zero */ target = malloc(allocsize); if(!target) - return NULL; /* major failure */ + return CURLE_OUT_OF_MEMORY; while(*filename) { if(*filename == '#' && ISDIGIT(filename[1])) { @@ -563,7 +574,7 @@ char *glob_match_url(char *filename, URLGlob *glob) printf("internal error: invalid pattern type (%d)\n", (int)pat.type); Curl_safefree(target); - return NULL; + return CURLE_FAILED_INIT; } } else { @@ -585,7 +596,7 @@ char *glob_match_url(char *filename, URLGlob *glob) newstr = realloc(target, allocsize + 1); if(!newstr) { Curl_safefree(target); - return NULL; + return CURLE_OUT_OF_MEMORY; } target = newstr; } @@ -593,5 +604,7 @@ char *glob_match_url(char *filename, URLGlob *glob) stringlen += appendlen; } target[stringlen]= '\0'; - return target; + *result = target; + return CURLE_OK; } + diff --git a/src/tool_urlglob.h b/src/tool_urlglob.h index cf54a9b16..18281bf61 100644 --- a/src/tool_urlglob.h +++ b/src/tool_urlglob.h @@ -64,8 +64,8 @@ typedef struct { } URLGlob; int glob_url(URLGlob**, char*, int *, FILE *); -char* glob_next_url(URLGlob*); -char* glob_match_url(char*, URLGlob *); +int glob_next_url(char **, URLGlob *); +int glob_match_url(char **, char*, URLGlob *); void glob_cleanup(URLGlob* glob); #endif /* HEADER_CURL_TOOL_URLGLOB_H */ -- cgit v1.2.3