summaryrefslogtreecommitdiff
path: root/src/patch.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@gnu.org>2016-07-19 22:40:40 +0200
committerAndreas Gruenbacher <agruen@gnu.org>2016-07-27 15:47:47 +0200
commit66fdcf0e7c83a1e2eb4db97b9e24f224db656b65 (patch)
treee283ff870ab72a93f3cb05f1205a0ebe0361655c /src/patch.c
parent83a3ed012c677df484a892af69dbca8963867cb3 (diff)
downloadpatch-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.c18
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);
}