diff --git a/tar/bsdtar.c b/tar/bsdtar.c index c80be9ca..549575ee 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -170,6 +170,8 @@ bsdtar_init(void) bsdtar->conffile = NULL; bsdtar->conf_opt = NULL; bsdtar->conf_arg = NULL; + bsdtar->conffile_actual = NULL; + bsdtar->conffile_buffer = NULL; /* We don't have bsdtar->progname yet, so we can't use bsdtar_errc. */ if (atexit(bsdtar_atexit)) { @@ -199,6 +201,12 @@ bsdtar_atexit(void) free(bsdtar->conf_opt); free(bsdtar->conf_arg); + /* Free file-parsing variables from util.c. */ + free(bsdtar->conffile_buffer); + if ((bsdtar->conffile_actual != NULL) && + (bsdtar->conffile_actual != stdin)) + fclose(bsdtar->conffile_actual); + /* Free matching and (if applicable) substitution patterns. */ cleanup_exclusions(bsdtar); #if HAVE_REGEX_H diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 1682ee62..e51b9c12 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -132,6 +132,8 @@ struct bsdtar { char *conffile; char *conf_opt; char *conf_arg; + FILE *conffile_actual; + char *conffile_buffer; /* Used for --dryrun with tarsnap.conf.sample with a missing keyfile. */ int config_file_keyfile_failed; diff --git a/tar/util.c b/tar/util.c index b857460b..2dd25adc 100644 --- a/tar/util.c +++ b/tar/util.c @@ -311,10 +311,18 @@ process_lines(struct bsdtar *bsdtar, const char *pathname, f = fopen(pathname, "r"); if (f == NULL) bsdtar_errc(bsdtar, 1, errno, "Couldn't open %s", pathname); + + /* Record pointer for freeing upon error. */ + bsdtar->conffile_actual = f; + buff_length = 8192; buff = malloc(buff_length); if (buff == NULL) bsdtar_errc(bsdtar, 1, ENOMEM, "Can't read %s", pathname); + + /* Record pointer for freeing upon error. */ + bsdtar->conffile_buffer = buff; + line_start = line_end = buff_end = buff; for (;;) { /* Get some more data into the buffer. */ @@ -381,6 +389,11 @@ process_lines(struct bsdtar *bsdtar, const char *pathname, free(buff); if (f != stdin) fclose(f); + + /* Memory has been freed. */ + bsdtar->conffile_actual = NULL; + bsdtar->conffile_buffer = NULL; + return (ret); }