commit 7dd42450fb28f64d7fab8fb244760da303664e7e from: Omar Polo via: Thomas Adam date: Sun Mar 13 21:25:37 2022 UTC got patch: require exact match when removing files commit - 2cfc25ace6abf08ff748259dc6687da834614ad5 commit + 7dd42450fb28f64d7fab8fb244760da303664e7e blob - 7f4134d7707578a9a67af1005e364da8d3fc3df8 blob + ea402a90828dbdf9b3363ec2b4057245e7dfa61a --- lib/patch.c +++ lib/patch.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -458,7 +459,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: @@ -586,16 +595,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); @@ -609,6 +608,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 }