From edb6d7267d29d974ea42d054d92f4d3b2f0d7dd0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 11 Jan 2020 22:53:34 +0100 Subject: curl: remove 'config' field from OutStruct As it was just unnecessary duplicated information already stored in the 'per_transfer' struct and that's around mostly anyway. The duplicated pointer caused problems when the code flow was aborted before the dupe was filled in and could cause a NULL pointer access. Reported-by: Brian Carpenter Fixes #4807 --- src/tool_cb_hdr.c | 28 +++++++++++++--------------- src/tool_cb_prg.c | 5 ++--- src/tool_cb_rea.c | 5 ++--- src/tool_cb_wrt.c | 15 +++++++++------ src/tool_cb_wrt.h | 5 +++-- src/tool_metalink.c | 4 ++-- src/tool_operate.c | 30 ++++++++++++++---------------- src/tool_progress.c | 5 ++--- src/tool_sdecls.h | 3 +-- 9 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index 77224adba..30d7c99ae 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -73,12 +73,12 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) */ size_t failure = (size && nmemb) ? 0 : 1; - if(!heads->config) + if(!per->config) return failure; #ifdef DEBUGBUILD if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) { - warnf(heads->config->global, "Header data exceeds single call write " + warnf(per->config->global, "Header data exceeds single call write " "limit!\n"); return failure; } @@ -88,7 +88,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) * Write header data when curl option --dump-header (-D) is given. */ - if(heads->config->headerfile && heads->stream) { + if(per->config->headerfile && heads->stream) { size_t rc = fwrite(ptr, size, nmemb, heads->stream); if(rc != cb) return rc; @@ -100,7 +100,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) * Write etag to file when --etag-save option is given. * etag string that we want is enveloped in double quotes */ - if(etag_save->config->etag_save_file && etag_save->stream) { + if(per->config->etag_save_file && etag_save->stream) { /* match only header that start with etag (case insensitive) */ if(curl_strnequal(str, "etag:", 5)) { char *etag_h = NULL; @@ -118,9 +118,8 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) */ if(!first) { - warnf( - etag_save->config->global, - "\nReceived header etag is missing double quote/s\n"); + warnf(per->config->global, + "\nReceived header etag is missing double quote/s\n"); return 1; } else { @@ -132,9 +131,8 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) last = memchr(first, '\"', cb); if(!last) { - warnf( - etag_save->config->global, - "\nReceived header etag is missing double quote/s\n"); + warnf(per->config->global, + "\nReceived header etag is missing double quote/s\n"); return 1; } @@ -197,7 +195,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) /* rename the initial file name to the new file name */ rc = rename(outs->filename, filename); if(rc != 0) { - warnf(outs->config->global, "Failed to rename %s -> %s: %s\n", + warnf(per->config->global, "Failed to rename %s -> %s: %s\n", outs->filename, filename, strerror(errno)); } if(outs->alloc_filename) @@ -213,12 +211,12 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) outs->filename = filename; outs->alloc_filename = TRUE; hdrcbdata->honor_cd_filename = FALSE; /* done now! */ - if(!tool_create_output_file(outs)) + if(!tool_create_output_file(outs, per->config)) return failure; } break; } - if(!outs->stream && !tool_create_output_file(outs)) + if(!outs->stream && !tool_create_output_file(outs, per->config)) return failure; } @@ -228,7 +226,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) /* bold headers only for selected protocols */ char *value = NULL; - if(!outs->stream && !tool_create_output_file(outs)) + if(!outs->stream && !tool_create_output_file(outs, per->config)) return failure; if(hdrcbdata->global->isatty && hdrcbdata->global->styled_output) diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 505ae751f..9d16ec766 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -123,8 +123,7 @@ int tool_progress_cb(void *clientp, struct timeval now = tvnow(); struct per_transfer *per = clientp; - struct OutStruct *outs = &per->outs; - struct OperationConfig *config = outs->config; + struct OperationConfig *config = per->config; struct ProgressData *bar = &per->progressbar; curl_off_t total; curl_off_t point; diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c index 03ed4a467..78a169fb0 100644 --- a/src/tool_cb_rea.c +++ b/src/tool_cb_rea.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -63,8 +63,7 @@ int tool_readbusy_cb(void *clientp, curl_off_t ultotal, curl_off_t ulnow) { struct per_transfer *per = clientp; - struct OutStruct *outs = &per->outs; - struct OperationConfig *config = outs->config; + struct OperationConfig *config = per->config; (void)dltotal; /* unused */ (void)dlnow; /* unused */ diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index 0f47b4d0f..ed108911e 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,11 +33,14 @@ #include "memdebug.h" /* keep this as LAST include */ /* create a local file for writing, return TRUE on success */ -bool tool_create_output_file(struct OutStruct *outs) +bool tool_create_output_file(struct OutStruct *outs, + struct OperationConfig *config) { - struct GlobalConfig *global = outs->config->global; + struct GlobalConfig *global; FILE *file; - + DEBUGASSERT(outs); + DEBUGASSERT(config); + global = config->global; if(!outs->filename || !*outs->filename) { warnf(global, "Remote filename has no length!\n"); return FALSE; @@ -78,7 +81,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) size_t rc; struct per_transfer *per = userdata; struct OutStruct *outs = &per->outs; - struct OperationConfig *config = outs->config; + struct OperationConfig *config = per->config; size_t bytes = sz * nmemb; bool is_tty = config->global->isatty; #ifdef WIN32 @@ -147,7 +150,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) } #endif - if(!outs->stream && !tool_create_output_file(outs)) + if(!outs->stream && !tool_create_output_file(outs, per->config)) return failure; if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) { diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h index 188d3ea7d..e49d8f35d 100644 --- a/src/tool_cb_wrt.h +++ b/src/tool_cb_wrt.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,6 +30,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata); /* create a local file for writing, return TRUE on success */ -bool tool_create_output_file(struct OutStruct *outs); +bool tool_create_output_file(struct OutStruct *outs, + struct OperationConfig *config); #endif /* HEADER_CURL_TOOL_CB_WRT_H */ diff --git a/src/tool_metalink.c b/src/tool_metalink.c index 6d62f2d93..53de61258 100644 --- a/src/tool_metalink.c +++ b/src/tool_metalink.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -895,7 +895,7 @@ size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb, { struct per_transfer *per = userdata; struct OutStruct *outs = &per->outs; - struct OperationConfig *config = outs->config; + struct OperationConfig *config = per->config; int rv; /* diff --git a/src/tool_operate.c b/src/tool_operate.c index 2bee9349a..66f2139c8 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -380,7 +380,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, /* do not create (or even overwrite) the file in case we get no data because of unmet condition */ curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet); - if(!cond_unmet && !tool_create_output_file(outs)) + if(!cond_unmet && !tool_create_output_file(outs, config)) result = CURLE_WRITE_ERROR; } @@ -866,7 +866,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, /* default headers output stream is stdout */ heads = &per->heads; heads->stream = stdout; - heads->config = config; /* Single header file for all URLs */ if(config->headerfile) { @@ -891,10 +890,22 @@ static CURLcode single_transfer(struct GlobalConfig *global, } } + hdrcbdata = &per->hdrcbdata; + + outs = &per->outs; + input = &per->input; + + per->outfile = NULL; + per->infdopen = FALSE; + per->infd = STDIN_FILENO; + + /* default output stream is stdout */ + outs->stream = stdout; + /* --etag-save */ etag_save = &per->etag_save; etag_save->stream = stdout; - etag_save->config = config; + if(config->etag_save_file) { /* open file for output: */ if(strcmp(config->etag_save_file, "-")) { @@ -961,19 +972,6 @@ static CURLcode single_transfer(struct GlobalConfig *global, } } - hdrcbdata = &per->hdrcbdata; - - outs = &per->outs; - input = &per->input; - - per->outfile = NULL; - per->infdopen = FALSE; - per->infd = STDIN_FILENO; - - /* default output stream is stdout */ - outs->stream = stdout; - outs->config = config; - if(metalink) { /* For Metalink download, use name in Metalink file as filename. */ diff --git a/src/tool_progress.c b/src/tool_progress.c index ac4f58f41..31cd56ae4 100644 --- a/src/tool_progress.c +++ b/src/tool_progress.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -95,8 +95,7 @@ int xferinfo_cb(void *clientp, curl_off_t ulnow) { struct per_transfer *per = clientp; - struct OutStruct *outs = &per->outs; - struct OperationConfig *config = outs->config; + struct OperationConfig *config = per->config; per->dltotal = dltotal; per->dlnow = dlnow; per->ultotal = ultotal; diff --git a/src/tool_sdecls.h b/src/tool_sdecls.h index 562fef852..ccc9f5aba 100644 --- a/src/tool_sdecls.h +++ b/src/tool_sdecls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -69,7 +69,6 @@ struct OutStruct { bool s_isreg; bool fopened; FILE *stream; - struct OperationConfig *config; curl_off_t bytes; curl_off_t init; #ifdef USE_METALINK -- cgit v1.2.1