Skip to content

Commit 059c9f9

Browse files
pierrecByron
authored andcommitted
Be lenient to missing timestamp in signature (#1542)
1 parent 3868767 commit 059c9f9

File tree

3 files changed

+41
-26
lines changed

3 files changed

+41
-26
lines changed

gix-actor/src/signature/decode.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub(crate) mod function {
66
use winnow::error::{ErrMode, ErrorKind};
77
use winnow::stream::Stream;
88
use winnow::{
9-
combinator::{alt, separated_pair, terminated},
9+
combinator::{alt, opt, separated_pair, terminated},
1010
error::{AddContext, ParserError, StrContext},
1111
prelude::*,
1212
stream::AsChar,
@@ -21,8 +21,8 @@ pub(crate) mod function {
2121
) -> PResult<SignatureRef<'a>, E> {
2222
separated_pair(
2323
identity,
24-
b" ",
25-
(
24+
opt(b" "),
25+
opt((
2626
terminated(take_until(0.., SPACE), take(1usize))
2727
.verify_map(|v| to_signed::<SecondsSinceUnixEpoch>(v).ok())
2828
.context(StrContext::Expected("<timestamp>".into())),
@@ -38,8 +38,9 @@ pub(crate) mod function {
3838
.verify_map(|v| to_signed::<OffsetInSeconds>(v).ok())
3939
.context(StrContext::Expected("MM".into())),
4040
take_while(0.., AsChar::is_dec_digit).map(|v: &[u8]| v),
41-
)
42-
.map(|(time, sign, hours, minutes, trailing_digits)| {
41+
))
42+
.map(|maybe_timestamp| {
43+
if let Some((time, sign, hours, minutes, trailing_digits)) = maybe_timestamp {
4344
let offset = if trailing_digits.is_empty() {
4445
(hours * 3600 + minutes * 60) * if sign == Sign::Minus { -1 } else { 1 }
4546
} else {
@@ -50,7 +51,10 @@ pub(crate) mod function {
5051
offset,
5152
sign,
5253
}
53-
}),
54+
} else {
55+
Time::new(0, 0)
56+
}
57+
}),
5458
)
5559
.context(StrContext::Expected("<name> <<email>> <timestamp> <+|-><HHMM>".into()))
5660
.map(|(identity, time)| SignatureRef {
@@ -206,12 +210,9 @@ mod tests {
206210
#[test]
207211
fn invalid_time() {
208212
assert_eq!(
209-
decode.parse_peek(b"hello <> abc -1215")
210-
.map_err(to_bstr_err)
211-
.expect_err("parse fails as > is missing")
212-
.to_string(),
213-
"in predicate verification at 'abc -1215'\n 0: expected `<timestamp>` at 'abc -1215'\n 1: expected `<name> <<email>> <timestamp> <+|-><HHMM>` at 'hello <> abc -1215'\n"
214-
);
213+
decode.parse_peek(b"hello <> abc -1215").expect("parse to work").1,
214+
signature("hello", "", 0, Sign::Plus, 0)
215+
);
215216
}
216217
}
217218
}

gix-actor/tests/signature/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,14 @@ fn parse_timestamp_with_trailing_digits() {
108108

109109
#[test]
110110
fn parse_missing_timestamp() {
111+
let signature = gix_actor::SignatureRef::from_bytes::<()>(b"first last <[email protected]>")
112+
.expect("deal with missing timestamp in signature by zeroing it");
111113
assert_eq!(
112-
format!(
113-
"{:?}",
114-
gix_actor::SignatureRef::from_bytes::<()>(b"first last <[email protected]>")
115-
),
116-
"Err(Backtrack(()))".to_string()
114+
signature,
115+
SignatureRef {
116+
name: "first last".into(),
117+
email: "[email protected]".into(),
118+
time: gix_actor::date::Time::new(0, 0),
119+
}
117120
);
118121
}

gix-object/tests/tag/mod.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,11 @@ fn invalid() {
137137
}
138138

139139
mod from_bytes {
140+
use gix_actor::SignatureRef;
141+
use gix_date::Time;
140142
use gix_object::{bstr::ByteSlice, Kind, TagRef};
141143

142-
use crate::{fixture_name, signature, tag::tag_fixture};
144+
use crate::{fixture_name, signature, tag::tag_fixture, Sign};
143145

144146
#[test]
145147
fn signed() -> crate::Result {
@@ -232,15 +234,24 @@ KLMHist5yj0sw1E4hDTyQa0=
232234

233235
#[test]
234236
fn tagger_without_timestamp() -> crate::Result {
235-
// Note: this behaviour is inconsistent with Git's
236-
// Git would successfully interpret this tag and set the timestamp to 0
237-
// See https://github.com/git/git/blob/3a7362eb9fad0c4838f5cfaa95ed3c51a4c18d93/tag.c#L116
238237
assert_eq!(
239-
format!(
240-
"{:?}",
241-
TagRef::from_bytes(&fixture_name("tag", "tagger-without-timestamp.txt"))
242-
),
243-
"Err(Error { inner: () })".to_string()
238+
TagRef::from_bytes(&fixture_name("tag", "tagger-without-timestamp.txt"))?,
239+
TagRef {
240+
target: b"4fcd840c4935e4c7a5ea3552710a0f26b9178c24".as_bstr(),
241+
name: b"ChangeLog".as_bstr(),
242+
target_kind: Kind::Commit,
243+
message: b"".as_bstr(),
244+
tagger: Some(SignatureRef {
245+
name: b"shemminger".as_bstr(),
246+
email: b"shemminger".as_bstr(),
247+
time: Time {
248+
seconds: 0,
249+
offset: 0,
250+
sign: Sign::Plus
251+
}
252+
}),
253+
pgp_signature: None
254+
}
244255
);
245256
Ok(())
246257
}

0 commit comments

Comments
 (0)