diff options
author | Andreas Gruenbacher <agruen@gnu.org> | 2016-07-19 22:40:40 +0200 |
---|---|---|
committer | Andreas Gruenbacher <agruen@gnu.org> | 2016-07-27 15:47:47 +0200 |
commit | 66fdcf0e7c83a1e2eb4db97b9e24f224db656b65 (patch) | |
tree | e283ff870ab72a93f3cb05f1205a0ebe0361655c /src/patch.c | |
parent | 83a3ed012c677df484a892af69dbca8963867cb3 (diff) | |
download | patch-66fdcf0e7c83a1e2eb4db97b9e24f224db656b65.tar.gz |
Fix broken git-style patch behavior
When a git-syle patch is applied, all file modifications are done to
temporary files which are put in place when the patch ends. When a
patch fails, GNU patch was trying to "roll back" to the start. A bug in
that code that lead to accidental file deletion was recently discovered
by Richard Weinberger <richard@nod.at>. Even worse though, GNU patch
should not exhibit this "rollback" behavior in the first place; that's
not what people expect. Instead, the files modified so far should be put
in place.
* src/patch.c (cleanup): Put output files processed successfully
in place instead of trying to "roll back" to the start.
(forget_output_files): Remove obsolete (and broken) function.
* tests/git-cleanup: New broken git-style patch test case that exercises
the cleanup path.
* tests/Makefile.am (TESTS): Add new test case.
Diffstat (limited to 'src/patch.c')
-rw-r--r-- | src/patch.c | 18 |
1 files changed, 1 insertions, 17 deletions
diff --git a/src/patch.c b/src/patch.c index b0ed91a..bf7e5c2 100644 --- a/src/patch.c +++ b/src/patch.c @@ -1966,22 +1966,6 @@ output_files (struct stat const *st) gl_list_clear (files_to_output); } -static void -forget_output_files (void) -{ - gl_list_iterator_t iter = gl_list_iterator (files_to_output); - const void *elt; - - while (gl_list_iterator_next (&iter, &elt, NULL)) - { - const struct file_to_output *file_to_output = elt; - - safe_unlink (file_to_output->from); - } - gl_list_iterator_free (&iter); - gl_list_clear (files_to_output); -} - /* Fatal exit with cleanup. */ void @@ -2012,5 +1996,5 @@ cleanup (void) remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal); remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal); - forget_output_files (); + output_files (NULL); } |