Merge branch 'kh/trailers-no-urls' into jch

The trailers code has been taught to avoid mistaking a line that has
'<token>://' at the beginning as a trailer line.

* kh/trailers-no-urls:
  trailers: stop recognizing URLs as trailers
This commit is contained in:
Junio C Hamano
2026-08-07 14:48:15 -07:00
4 changed files with 87 additions and 4 deletions

View File

@@ -123,9 +123,16 @@ OTHER RULES
What was covered in the previous section are the rules that are relevant
for regular use. The following points are included for completeness.
This command ignores comment lines (see `core.commentString` in
linkgit:git-config[1]). This is for use with the `prepare-commit-msg`
and `commit-msg` hooks.
--
* This command ignores comment lines (see `core.commentString` in
linkgit:git-config[1]). This is for use with the `prepare-commit-msg`
and `commit-msg` hooks.
* Candidate trailer lines that have `:` as the separator, that have no
whitespace before the value part, and that start with `//` are not
recognized as trailers. This is to avoid accidentally interpreting
URLs as trailers (e.g. lines that start with `https://`).
--
OPTIONS
-------

View File

@@ -1989,4 +1989,23 @@ test_expect_success 'handling of --- lines in conjunction with cut-lines' '
test_cmp expected actual
'
test_expect_success 'URLs and lines that are not quite URLs' '
cat >expect <<-\EOF &&
https: //www.a-trailer.org
https: //www.another-trailer.org
Signed-off-by: somebody <somebody@somewhere>
EOF
git interpret-trailers --only-trailers >actual <<-\EOF &&
subject
body
https://www.not-a-trailer.org
https ://www.a-trailer.org
https: //www.another-trailer.org
Signed-off-by: somebody <somebody@somewhere>
EOF
test_cmp expect actual
'
test_done

View File

@@ -318,3 +318,55 @@ void test_trailer__one_non_trailer_no_git_trailers(void)
0,
expected_contents);
}
void test_trailer__URL(void)
{
struct contents expected_contents[] = { 0 };
t_trailer_iterator("Subject: foo bar\n"
"\n"
/*
* We do not want to match URLs as trailers.
*/
"https://www.example.org\n",
0,
expected_contents);
}
void test_trailer__not_a_URL_space_after_separator(void)
{
struct contents expected_contents[] = {
{ .raw = "https: //www.example.org\n",
.key = "https",
.val = "//www.example.org" },
{ 0 },
};
t_trailer_iterator("Subject: foo bar\n"
"\n"
/*
* This has a space after ':' so it's not a URL.
*/
"https: //www.example.org\n",
1,
expected_contents);
}
void test_trailer__not_a_URL_space_before_separator(void)
{
struct contents expected_contents[] = {
{ .raw = "https ://www.example.org\n",
.key = "https",
.val = "//www.example.org" },
{ 0 },
};
t_trailer_iterator("Subject: foo bar\n"
"\n"
/*
* This has a space before ':' so it's not a URL.
*/
"https ://www.example.org\n",
1,
expected_contents);
}

View File

@@ -635,8 +635,13 @@ static ssize_t find_separator(const char *line, const char *separators)
int whitespace_found = 0;
const char *c;
for (c = line; *c; c++) {
if (strchr(separators, *c))
if (strchr(separators, *c)) {
/* avoid accidental URL matches (://) */
if (*c == ':' && c[1] == '/' && c[2] == '/' &&
!whitespace_found)
return -1;
return c - line;
}
if (!whitespace_found && (isalnum(*c) || *c == '-'))
continue;
if (c != line && (*c == ' ' || *c == '\t')) {