aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-09-05 08:14:26 -0400
committerJunio C Hamano <gitster@pobox.com>2017-09-06 17:19:53 +0900
commit45c6b1ed24724f7f3041a60a4313df7d9c4b9909 (patch)
tree57ba55efa89a67abe3c54ca3c11a7c50af93662e
parentd88ef6605120fd75be38376ba147623cf427bf73 (diff)
downloadgit-45c6b1ed24724f7f3041a60a4313df7d9c4b9909.tar.gz
git-45c6b1ed24724f7f3041a60a4313df7d9c4b9909.tar.xz
always check return value of close_tempfile
If close_tempfile() encounters an error, then it deletes the tempfile and resets the "struct tempfile". But many code paths ignore the return value and continue to use the tempfile. Instead, we should generally treat this the same as a write() error. Note that in the postimage of some of these cases our error message will be bogus after a failed close because we look at tempfile->filename (either directly or via get_tempfile_path). But after the failed close resets the tempfile object, this is guaranteed to be the empty string. That will be addressed in a future patch (because there are many more cases of the same problem than just these instances). Note also in the hunk in gpg-interface.c that it's fine to call delete_tempfile() in the error path, even if close_tempfile() failed and already deleted the file. The tempfile code is smart enough to know the second deletion is a noop. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--diff.c4
-rw-r--r--gpg-interface.c4
-rw-r--r--shallow.c4
3 files changed, 6 insertions, 6 deletions
diff --git a/diff.c b/diff.c
index 3d3e553a9..fdb974014 100644
--- a/diff.c
+++ b/diff.c
@@ -3738,9 +3738,9 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
blob = buf.buf;
size = buf.len;
}
- if (write_in_full(fd, blob, size) != size)
+ if (write_in_full(fd, blob, size) != size ||
+ close_tempfile(&temp->tempfile))
die_errno("unable to write temp-file");
- close_tempfile(&temp->tempfile);
temp->name = get_tempfile_path(&temp->tempfile);
oid_to_hex_r(temp->hex, oid);
xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
diff --git a/gpg-interface.c b/gpg-interface.c
index 455b6c04b..05ca6ecbf 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -209,13 +209,13 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
fd = mks_tempfile_t(&temp, ".git_vtag_tmpXXXXXX");
if (fd < 0)
return error_errno(_("could not create temporary file"));
- if (write_in_full(fd, signature, signature_size) < 0) {
+ if (write_in_full(fd, signature, signature_size) < 0 ||
+ close_tempfile(&temp) < 0) {
error_errno(_("failed writing detached signature to '%s'"),
temp.filename.buf);
delete_tempfile(&temp);
return -1;
}
- close_tempfile(&temp);
argv_array_pushl(&gpg.args,
gpg_program,
diff --git a/shallow.c b/shallow.c
index c7fd68ace..f49e6ae12 100644
--- a/shallow.c
+++ b/shallow.c
@@ -295,10 +295,10 @@ const char *setup_temporary_shallow(const struct oid_array *extra)
if (write_shallow_commits(&sb, 0, extra)) {
fd = xmks_tempfile(&temp, git_path("shallow_XXXXXX"));
- if (write_in_full(fd, sb.buf, sb.len) != sb.len)
+ if (write_in_full(fd, sb.buf, sb.len) != sb.len ||
+ close_tempfile(&temp) < 0)
die_errno("failed to write to %s",
get_tempfile_path(&temp));
- close_tempfile(&temp);
strbuf_release(&sb);
return get_tempfile_path(&temp);
}