commit 5b67f96efbfbf2e5a3f75f6ab91e45dd3013c77f from: Omar Polo date: Sun Mar 13 15:36:59 2022 UTC got patch: require exact match when removing files commit - dd6c3779b6533ba060e07dc68fdaf6b1e0e49d30 commit + 5b67f96efbfbf2e5a3f75f6ab91e45dd3013c77f blob - 478ade488151adafcb6e73d746f9a7ba2e84acdf blob + 71695e64b89d1a1b07daab61fb55d3c1883760ec --- lib/patch.c +++ lib/patch.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -456,7 +457,15 @@ patch_file(struct got_patch *p, const char *path, FILE } } - if (!feof(orig)) + + if (p->new == NULL) { + struct stat sb; + + if (fstat(fileno(orig), &sb) == -1) + err = got_error_from_errno("fstat"); + else if (sb.st_size != copypos) + err = got_error(GOT_ERR_PATCH_DONT_APPLY); + } else if (!feof(orig)) err = copy(tmp, orig, copypos, -1); done: @@ -584,16 +593,6 @@ apply_patch(struct got_worktree *worktree, struct got_ if (err) goto done; - if (p->old != NULL && p->new == NULL) { - /* - * special case: delete a file. don't try to match - * the lines but just schedule the removal. - */ - err = got_worktree_schedule_delete(worktree, &oldpaths, - 0, NULL, delete_cb, delete_arg, repo, 0, 0); - goto done; - } - if (asprintf(&template, "%s/got-patch", got_worktree_get_root_path(worktree)) == -1) { err = got_error_from_errno(template); @@ -607,6 +606,12 @@ apply_patch(struct got_worktree *worktree, struct got_ if (err) goto done; + if (p->old != NULL && p->new == NULL) { + err = got_worktree_schedule_delete(worktree, &oldpaths, + 0, NULL, delete_cb, delete_arg, repo, 0, 0); + goto done; + } + if (rename(tmppath, newpath) == -1) { err = got_error_from_errno3("rename", tmppath, newpath); goto done; blob - 36c9ef55d45f97cd15c3f787c35d5a7623def72a blob + 9a300a816a79b7eacef07263e7bd7cbce706ae25 --- regress/cmdline/patch.sh +++ regress/cmdline/patch.sh @@ -436,9 +436,47 @@ EOF if [ $ret -ne 0 ]; then diff -u $testroot/stderr.expected $testroot/stderr test_done $testroot $ret + return 1 + fi + + # try to delete a file with a patch that doesn't match + jot 100 > $testroot/wt/numbers + (cd $testroot/wt && got add numbers && got commit -m 'add numbers') \ + >/dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + cat < $testroot/wt/patch +--- numbers ++++ /dev/null +@@ -1,9 +0,0 @@ +-1 +-2 +-3 +-4 +-5 +-6 +-7 +-8 +-9 +EOF + + (cd $testroot/wt && got patch patch) > /dev/null 2> $testroot/stderr + ret=$? + if [ $ret -eq 0 ]; then # should fail + test_done $testroot 1 return 1 fi + echo "got: patch doesn't apply" > $testroot/stderr.expected + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr + fi test_done $testroot $ret }