diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix-actor/src/signature | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-actor/src/signature')
-rw-r--r-- | vendor/gix-actor/src/signature/decode.rs | 179 | ||||
-rw-r--r-- | vendor/gix-actor/src/signature/mod.rs | 11 |
2 files changed, 94 insertions, 96 deletions
diff --git a/vendor/gix-actor/src/signature/decode.rs b/vendor/gix-actor/src/signature/decode.rs index 6bd7bfed6..e8d14d3cd 100644 --- a/vendor/gix-actor/src/signature/decode.rs +++ b/vendor/gix-actor/src/signature/decode.rs @@ -1,90 +1,74 @@ pub(crate) mod function { use bstr::ByteSlice; use btoi::btoi; - use nom::{ - branch::alt, - bytes::complete::{tag, take, take_until, take_while_m_n}, - character::is_digit, - error::{context, ContextError, ParseError}, - sequence::{terminated, tuple}, - IResult, + use gix_date::{time::Sign, OffsetInSeconds, SecondsSinceUnixEpoch, Time}; + use winnow::{ + combinator::{alt, separated_pair, terminated}, + error::{AddContext, ParserError, StrContext}, + prelude::*, + stream::AsChar, + token::{take, take_until0, take_while}, }; - use crate::{IdentityRef, Sign, SignatureRef, Time}; + use crate::{IdentityRef, SignatureRef}; const SPACE: &[u8] = b" "; /// Parse a signature from the bytes input `i` using `nom`. - pub fn decode<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( - i: &'a [u8], - ) -> IResult<&'a [u8], SignatureRef<'a>, E> { - let (i, (identity, _, time, tzsign, hours, minutes)) = context( - "<name> <<email>> <timestamp> <+|-><HHMM>", - tuple(( - identity, - tag(b" "), - context("<timestamp>", |i| { - terminated(take_until(SPACE), take(1usize))(i).and_then(|(i, v)| { - btoi::<u32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) + pub fn decode<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>( + i: &mut &'a [u8], + ) -> PResult<SignatureRef<'a>, E> { + separated_pair( + identity, + b" ", + ( + terminated(take_until0(SPACE), take(1usize)) + .verify_map(|v| btoi::<SecondsSinceUnixEpoch>(v).ok()) + .context(StrContext::Expected("<timestamp>".into())), + alt(( + take_while(1.., b'-').map(|_| Sign::Minus), + take_while(1.., b'+').map(|_| Sign::Plus), + )) + .context(StrContext::Expected("+|-".into())), + take_while(2, AsChar::is_dec_digit) + .verify_map(|v| btoi::<OffsetInSeconds>(v).ok()) + .context(StrContext::Expected("HH".into())), + take_while(1..=2, AsChar::is_dec_digit) + .verify_map(|v| btoi::<OffsetInSeconds>(v).ok()) + .context(StrContext::Expected("MM".into())), + ) + .map(|(time, sign, hours, minutes)| { + let offset = (hours * 3600 + minutes * 60) * if sign == Sign::Minus { -1 } else { 1 }; + Time { + seconds: time, + offset, + sign, + } }), - context("+|-", alt((tag(b"-"), tag(b"+")))), - context("HH", |i| { - take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { - btoi::<i32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) - }), - context("MM", |i| { - take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { - btoi::<i32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) - }), - )), - )(i)?; - - debug_assert!(tzsign[0] == b'-' || tzsign[0] == b'+', "parser assure it's +|- only"); - let sign = if tzsign[0] == b'-' { Sign::Minus } else { Sign::Plus }; // - let offset = (hours * 3600 + minutes * 60) * if sign == Sign::Minus { -1 } else { 1 }; - - Ok(( - i, - SignatureRef { - name: identity.name, - email: identity.email, - time: Time { - seconds_since_unix_epoch: time, - offset_in_seconds: offset, - sign, - }, - }, - )) + ) + .context(StrContext::Expected("<name> <<email>> <timestamp> <+|-><HHMM>".into())) + .map(|(identity, time)| SignatureRef { + name: identity.name, + email: identity.email, + time, + }) + .parse_next(i) } /// Parse an identity from the bytes input `i` (like `name <email>`) using `nom`. - pub fn identity<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( - i: &'a [u8], - ) -> IResult<&'a [u8], IdentityRef<'a>, E> { - let (i, (name, email)) = context( - "<name> <<email>>", - tuple(( - context("<name>", terminated(take_until(&b" <"[..]), take(2usize))), - context("<email>", terminated(take_until(&b">"[..]), take(1usize))), - )), - )(i)?; - - Ok(( - i, - IdentityRef { + pub fn identity<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>( + i: &mut &'a [u8], + ) -> PResult<IdentityRef<'a>, E> { + ( + terminated(take_until0(&b" <"[..]), take(2usize)).context(StrContext::Expected("<name>".into())), + terminated(take_until0(&b">"[..]), take(1usize)).context(StrContext::Expected("<email>".into())), + ) + .map(|(name, email): (&[u8], &[u8])| IdentityRef { name: name.as_bstr(), email: email.as_bstr(), - }, - )) + }) + .context(StrContext::Expected("<name> <<email>>".into())) + .parse_next(i) } } pub use function::identity; @@ -93,37 +77,37 @@ pub use function::identity; mod tests { mod parse_signature { use bstr::ByteSlice; + use gix_date::{time::Sign, OffsetInSeconds, SecondsSinceUnixEpoch}; use gix_testtools::to_bstr_err; - use nom::IResult; + use winnow::prelude::*; - use crate::{signature, Sign, SignatureRef, Time}; + use crate::{signature, SignatureRef, Time}; - fn decode(i: &[u8]) -> IResult<&[u8], SignatureRef<'_>, nom::error::VerboseError<&[u8]>> { - signature::decode(i) + fn decode<'i>( + i: &mut &'i [u8], + ) -> PResult<SignatureRef<'i>, winnow::error::TreeError<&'i [u8], winnow::error::StrContext>> { + signature::decode.parse_next(i) } fn signature( name: &'static str, email: &'static str, - time: u32, + seconds: SecondsSinceUnixEpoch, sign: Sign, - offset: i32, + offset: OffsetInSeconds, ) -> SignatureRef<'static> { SignatureRef { name: name.as_bytes().as_bstr(), email: email.as_bytes().as_bstr(), - time: Time { - seconds_since_unix_epoch: time, - offset_in_seconds: offset, - sign, - }, + time: Time { seconds, offset, sign }, } } #[test] fn tz_minus() { assert_eq!( - decode(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 -0230") + decode + .parse_peek(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 -0230") .expect("parse to work") .1, signature("Sebastian Thiel", "byronimo@gmail.com", 1528473343, Sign::Minus, -9000) @@ -133,7 +117,8 @@ mod tests { #[test] fn tz_plus() { assert_eq!( - decode(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 +0230") + decode + .parse_peek(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 +0230") .expect("parse to work") .1, signature("Sebastian Thiel", "byronimo@gmail.com", 1528473343, Sign::Plus, 9000) @@ -143,7 +128,8 @@ mod tests { #[test] fn negative_offset_0000() { assert_eq!( - decode(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 -0000") + decode + .parse_peek(b"Sebastian Thiel <byronimo@gmail.com> 1528473343 -0000") .expect("parse to work") .1, signature("Sebastian Thiel", "byronimo@gmail.com", 1528473343, Sign::Minus, 0) @@ -151,9 +137,20 @@ mod tests { } #[test] + fn negative_offset_double_dash() { + assert_eq!( + decode + .parse_peek(b"name <name@example.com> 1288373970 --700") + .expect("parse to work") + .1, + signature("name", "name@example.com", 1288373970, Sign::Minus, -252000) + ); + } + + #[test] fn empty_name_and_email() { assert_eq!( - decode(b" <> 12345 -1215").expect("parse to work").1, + decode.parse_peek(b" <> 12345 -1215").expect("parse to work").1, signature("", "", 12345, Sign::Minus, -44100) ); } @@ -161,22 +158,22 @@ mod tests { #[test] fn invalid_signature() { assert_eq!( - decode(b"hello < 12345 -1215") + decode.parse_peek(b"hello < 12345 -1215") .map_err(to_bstr_err) .expect_err("parse fails as > is missing") .to_string(), - "Parse error:\nTakeUntil at: 12345 -1215\nin section '<email>', at: 12345 -1215\nin section '<name> <<email>>', at: hello < 12345 -1215\nin section '<name> <<email>> <timestamp> <+|-><HHMM>', at: hello < 12345 -1215\n" + "in slice at ' 12345 -1215'\n 0: expected `<email>` at ' 12345 -1215'\n 1: expected `<name> <<email>>` at ' 12345 -1215'\n 2: expected `<name> <<email>> <timestamp> <+|-><HHMM>` at ' 12345 -1215'\n" ); } #[test] fn invalid_time() { assert_eq!( - decode(b"hello <> abc -1215") + decode.parse_peek(b"hello <> abc -1215") .map_err(to_bstr_err) .expect_err("parse fails as > is missing") .to_string(), - "Parse error:\nMapRes at: -1215\nin section '<timestamp>', at: abc -1215\nin section '<name> <<email>> <timestamp> <+|-><HHMM>', at: hello <> abc -1215\n" + "in predicate verification at 'abc -1215'\n 0: expected `<timestamp>` at 'abc -1215'\n 1: expected `<name> <<email>> <timestamp> <+|-><HHMM>` at 'abc -1215'\n" ); } } diff --git a/vendor/gix-actor/src/signature/mod.rs b/vendor/gix-actor/src/signature/mod.rs index 8634ba595..057d4293e 100644 --- a/vendor/gix-actor/src/signature/mod.rs +++ b/vendor/gix-actor/src/signature/mod.rs @@ -1,15 +1,16 @@ mod _ref { use bstr::ByteSlice; + use winnow::{error::StrContext, prelude::*}; use crate::{signature::decode, IdentityRef, Signature, SignatureRef}; impl<'a> SignatureRef<'a> { /// Deserialize a signature from the given `data`. - pub fn from_bytes<E>(data: &'a [u8]) -> Result<SignatureRef<'a>, nom::Err<E>> + pub fn from_bytes<E>(mut data: &'a [u8]) -> Result<SignatureRef<'a>, winnow::error::ErrMode<E>> where - E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>, + E: winnow::error::ParserError<&'a [u8]> + winnow::error::AddContext<&'a [u8], StrContext>, { - decode(data).map(|(_, t)| t) + decode.parse_next(&mut data) } /// Create an owned instance from this shared one. @@ -94,7 +95,7 @@ pub(crate) mod write { /// Output impl Signature { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { self.to_ref().write_to(out) } /// Computes the number of bytes necessary to serialize this signature @@ -105,7 +106,7 @@ pub(crate) mod write { impl<'a> SignatureRef<'a> { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { out.write_all(validated_token(self.name)?)?; out.write_all(b" ")?; out.write_all(b"<")?; |