got patch: fail when reading empty hunks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
diff --git a/lib/patch.c b/lib/patch.c
index 9a66825..d7d7afe 100644
--- a/lib/patch.c
+++ b/lib/patch.c
@@ -215,9 +215,12 @@ recv_patch(struct imsgbuf *ibuf, int *done, struct got_patch *p, int strip)
switch (imsg.hdr.type) {
case GOT_IMSG_PATCH_DONE:
+ if (h != NULL && h->len == 0)
+ err = got_error(GOT_ERR_PATCH_MALFORMED);
goto done;
case GOT_IMSG_PATCH_HUNK:
- if (h != NULL && (h->old_nonl || h->new_nonl)) {
+ if (h != NULL &&
+ (h->len == 0 || h->old_nonl || h->new_nonl)) {
err = got_error(GOT_ERR_PATCH_MALFORMED);
goto done;
}
@@ -470,9 +473,6 @@ patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop,
copypos = 0;
STAILQ_FOREACH(h, &p->head, entries) {
- if (h->lines == NULL)
- break;
-
tryagain:
err = locate_hunk(orig, h, &pos, &lineno);
if (err != NULL && err->code == GOT_ERR_HUNK_FAILED)
diff --git a/libexec/got-read-patch/got-read-patch.c b/libexec/got-read-patch/got-read-patch.c
index 074b5cb..96d9789 100644
--- a/libexec/got-read-patch/got-read-patch.c
+++ b/libexec/got-read-patch/got-read-patch.c
@@ -267,7 +267,8 @@ parse_hdr(char *s, int *done, struct got_imsg_patch_hunk *hdr)
if (hdr->oldfrom >= LONG_MAX - hdr->oldlines ||
hdr->newfrom >= LONG_MAX - hdr->newlines ||
/* not so sure about this one */
- hdr->oldlines >= LONG_MAX - hdr->newlines - 1)
+ hdr->oldlines >= LONG_MAX - hdr->newlines - 1 ||
+ (hdr->oldlines == 0 && hdr->newlines == 0))
return got_error(GOT_ERR_PATCH_MALFORMED);
if (hdr->oldlines == 0) {
diff --git a/regress/cmdline/patch.sh b/regress/cmdline/patch.sh
index b30e9e0..155c33f 100755
--- a/regress/cmdline/patch.sh
+++ b/regress/cmdline/patch.sh
@@ -537,6 +537,40 @@ EOF
return 1
fi
+ # empty hunk
+ cat <<EOF > $testroot/wt/patch
+diff --git a/alpha b/iota
+--- a/alpha
++++ b/iota
+@@ -0,0 +0,0 @@
+EOF
+
+ (cd $testroot/wt && got patch patch) \
+ > $testroot/stdout \
+ 2> $testroot/stderr
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "got managed to apply an invalid patch"
+ test_done $testroot 1
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done $testroot $ret
+ return 1
+ fi
+
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done $testroot $ret
+ return 1
+ fi
+
test_done $testroot $ret
}