From: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> S-o-b in the middle of a sentence, at the beginning of the sentence but it is just because of text wrapping, or a full paragraph of valid S-o-b in the middle of the message. All these are not S-o-b, but detected as is. Fix them. [bc: add two additional tests to demonstrate shortcomings of the current code: 1. failure to detect non-conforming elements in the footer when last line matches committer's s-o-b. 2. failure to handle various s-o-b -like elements in the footer as conforming. e.g. "Change-id: IXXXX or Bug: 1234" Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> Signed-off-by: Brandon Casey <bcasey@xxxxxxxxxx> --- log-tree.c | 37 +++++++++++++++++-- t/t4014-format-patch.sh | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) diff --git a/log-tree.c b/log-tree.c index 4f86def..14ebf69 100644 --- a/log-tree.c +++ b/log-tree.c @@ -260,14 +260,47 @@ static void append_signoff(struct strbuf *sb, const char *signoff) int has_signoff = 0; char *cp; - cp = sb->buf; + /* + * Only search in the last paragrah, don't be fooled by a + * paragraph full of valid S-o-b in the middle. + */ + cp = sb->buf + sb->len - 1; + while (cp > sb->buf) { + if (cp[0] == '\n' && cp[1] == '\n') { + cp += 2; + break; + } + cp--; + } /* First see if we already have the sign-off by the signer */ while ((cp = strstr(cp, signed_off_by))) { + const char *s = cp; + cp += strlen(signed_off_by); + + if (!has_signoff && s > sb->buf) { + /* + * S-o-b in the middle of a sentence is not + * really S-o-b + */ + if (s[-1] != '\n') + continue; + + if (s - 1 > sb->buf && s[-2] == '\n') + ; /* the first S-o-b */ + else if (!detect_any_signoff(sb->buf, s - sb->buf)) + /* + * The previous line looks like an + * S-o-b. There's still no guarantee + * that it's an actual S-o-b. For that + * we need to look back until we find + * a blank line, which is too costly. + */ + continue; + } has_signoff = 1; - cp += strlen(signed_off_by); if (cp + signoff_len >= sb->buf + sb->len) break; if (strncmp(cp, signoff, signoff_len)) diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index dfe9209..30e37a7 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1062,6 +1062,60 @@ EOF test_cmp expected actual ' +test_expect_success 'signoff: not really a signoff' ' + append_signoff <<\EOF >actual && +subject + +I want to mention about Signed-off-by: here. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:I want to mention about Signed-off-by: here. +10: +11:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: not really a signoff (2)' ' + append_signoff <<\EOF >actual && +subject + +My unfortunate +Signed-off-by: example happens to be wrapped here. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10:Signed-off-by: example happens to be wrapped here. +11: +12:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: valid S-o-b paragraph in the middle' ' + append_signoff <<\EOF >actual && +subject + +Signed-off-by: my@house +Signed-off-by: your@house + +A lot of houses. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:Signed-off-by: my@house +10:Signed-off-by: your@house +11: +13: +14:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + test_cmp expected actual +' + test_expect_success 'signoff: the same signoff at the end' ' append_signoff <<\EOF >actual && subject @@ -1109,4 +1163,45 @@ EOF test_cmp expected actual ' +test_expect_failure 'signoff: detect garbage in non-conforming footer' ' + append_signoff <<\EOF >actual && +subject + +body + +Tested-by: my@house +Some Trash +Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +13:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +14: +15:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + test_cmp expected actual +' + +test_expect_failure 'signoff: footer begins with non-signoff without @ sign' ' + append_signoff <<\EOF >actual && +subject + +body + +Tested-by: my@house +Change-id: Ideadbeef +Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +Bug: 1234 +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +13:Signed-off-by: C O Mitter <committer@xxxxxxxxxxx> +EOF + test_cmp expected actual +' + test_done -- 1.8.0.284.g959048a -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html