Skip to content

Commit a86f67b

Browse files
committed
Work around parse errors of a bogus git.git commit
The C Git source code repository itself contains a commit with bogus `gpgsig` lines: 5f549aa2f783 (pretty: %G[?GS] placeholders, 2011-10-21). Basically, this commit's headers contain a GPG signature that _should_ have been a multi-line header, but instead every line of that signature was added individually as a `gpgsig` header. Crucially, this includes a header line that starts with `gpgsig` followed by a space and that's already the end of the line. Gitoxide's commit header parser was not prepared for that. Even worse: the error message in that instance was simply empty. Let's make the parser more robust by accepting such commit headers, and add a test to verify that the commit in question _can_ be parsed by Gitoxide. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent a149d4e commit a86f67b

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

gix-object/src/commit/decode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn commit<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
5151
alt((
5252
parse::any_header_field_multi_line.map(|(k, o)| (k.as_bstr(), Cow::Owned(o))),
5353
|i: &mut _| {
54-
parse::any_header_field(i, take_till(1.., NL))
54+
parse::any_header_field(i, take_till(0.., NL))
5555
.map(|(k, o)| (k.as_bstr(), Cow::Borrowed(o.as_bstr())))
5656
},
5757
)),
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
tree db079155794727ac821adfba2eb68b330cc0c120
2+
parent 33a11a20eb7610771268e34211509cbbdee76b1e
3+
author Junio C Hamano <[email protected]> 1319256362 -0700
4+
committer Junio C Hamano <[email protected]> 1319259176 -0700
5+
gpgsig -----BEGIN PGP SIGNATURE-----
6+
gpgsig Version: GnuPG v1.4.10 (GNU/Linux)
7+
gpgsig
8+
gpgsig iQIcBAABAgAGBQJOokwoAAoJELC16IaWr+bL0WoP/2QKYkWpEyXF608m2L/cB9Qx
9+
gpgsig /N0oBjyL1guIjPX9B3Wxq80dnLLEPnpnO39aiQIXFoJS0L6KEurqK6uDPHy3/ULa
10+
gpgsig QsAug2HeCLsDnIFbzFSpSIMv/bP/72FDb/idMBT99xTcQj5UJEUgj7AAtx0vnKvQ
11+
gpgsig pQIXtPu5GBUdhl3SiGgiJFRyp4r5EgV5I40GBwx/ty9cPEIN7ukJ3CR9+KC8eIGx
12+
gpgsig Az7qngi3dhTn7g+3Z8XX5OYFDMSt9xn1gxqWXOMNlG0mxCvpFe59kwciugp26KVp
13+
gpgsig n+yJ0UOdoxyZX8pdqXQjvklmoo7e55aaxtbHe7KSD56ebL7h7vHhkGWORU1dOp+h
14+
gpgsig Iv5dQItkKSR8afB7FmRjo8+B/2g0wZDKRTGhzm7d1gooO5gpXvuvm4GRl5Io+IEj
15+
gpgsig c7Li3EYmXADWUZWJtbDKDgKGKIOmWv72Qrz52iaESrhZ909HiXfn/jhHBuDRmLtQ
16+
gpgsig /4v3T4O25uhdZ4p/PjHQn/ZroCmDyMwmnrtw/tt5fSNrl4qGcYg8Jj/1ynfF1AtS
17+
gpgsig dM2LR65sOwXzSsqAbQjyRFYMLSWhHd/h8BcpZHDXmNBkZJVPm4zvD3ZVaAo6rtZD
18+
gpgsig WJ9YXWXtPhuf09OgYBzcBlamTrk9ByH+NCIdrFkqfhNF1YI5dArSZytIXJhpPI1e
19+
gpgsig TrmQAZf0BiI5J6PYN0AI
20+
gpgsig =Qg/+
21+
gpgsig -----END PGP SIGNATURE-----
22+
23+
pretty: %G[?GS] placeholders
24+
25+
Add new placeholders related to the GPG signature on signed commits.
26+
27+
- %GG to show the raw verification message from GPG;
28+
- %G? to show either "G" for Good, "B" for Bad;
29+
- %GS to show the name of the signer.
30+
31+
Signed-off-by: Junio C Hamano <[email protected]>

gix-object/tests/object/commit/from_bytes.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,20 @@ fn newline_right_after_signature_multiline_header() -> crate::Result {
342342
assert!(commit.message.starts_with(b"Rollup"));
343343
Ok(())
344344
}
345+
346+
#[test]
347+
fn bogus_multi_gpgsig_header() -> crate::Result {
348+
let fixture = fixture_name("commit", "bogus-gpgsig-lines-in-git.git.txt");
349+
let commit = CommitRef::from_bytes(&fixture)?;
350+
let pgp_sig = crate::commit::BEGIN_PGP_SIGNATURE.as_bstr();
351+
assert_eq!(commit.extra_headers[0].1.as_ref(), pgp_sig);
352+
assert_eq!(commit.extra_headers().pgp_signature(), Some(pgp_sig));
353+
assert_eq!(
354+
commit.extra_headers().find(gix_object::commit::SIGNATURE_FIELD_NAME),
355+
Some(pgp_sig)
356+
);
357+
assert_eq!(commit.extra_headers().find_pos("gpgsig"), Some(0));
358+
assert_eq!(commit.extra_headers().find_pos("something else"), None);
359+
assert!(commit.message.starts_with(b"pretty: %G[?GS] placeholders"));
360+
Ok(())
361+
}

gix-object/tests/object/commit/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ iyBBl69jASy41Ug/BlFJbw4+ItkShpXwkJKuBBV/JExChmvbxYWaS7QnyYC9UO0=
149149
150150
";
151151

152+
const BEGIN_PGP_SIGNATURE: &[u8] = b"-----BEGIN PGP SIGNATURE-----";
153+
152154
mod method {
153155
use gix_object::CommitRef;
154156
use pretty_assertions::assert_eq;

0 commit comments

Comments
 (0)