From e7cf12b4a0b3958040ca6458aebc86f9ca3cf7c7 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 21 Nov 2022 14:46:53 -0800 Subject: [PATCH] Get rid of unnecessary dependency --- Cargo.toml | 1 - src/parse/address.rs | 5 +-- src/parse/command.rs | 97 ++++++++++++++++++++++++------------------- src/parse/imf.rs | 36 ++++++++-------- src/parse/mod.rs | 14 +++---- src/parse/response.rs | 49 ++++++++++++---------- src/parse/trace.rs | 5 +-- 7 files changed, 110 insertions(+), 97 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b34a3d8..768f461 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,4 @@ edition = "2021" [dependencies] nom = "7" -abnf-core = "0.5" serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/src/parse/address.rs b/src/parse/address.rs index a548612..9c2a8c9 100644 --- a/src/parse/address.rs +++ b/src/parse/address.rs @@ -1,10 +1,9 @@ //! 4.1.3. Address Literals (RFC 5321) -use abnf_core::streaming::is_DIGIT; use nom::{ branch::alt, bytes::streaming::{tag, tag_no_case, take_while1, take_while_m_n}, - character::is_hex_digit, + character::{is_digit, is_hex_digit}, combinator::{map_res, opt, recognize}, multi::{count, many_m_n}, sequence::{delimited, tuple}, @@ -47,7 +46,7 @@ pub fn IPv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { /// /// Snum = 1*3DIGIT pub fn Snum(input: &[u8]) -> IResult<&[u8], &[u8]> { - take_while_m_n(1, 3, is_DIGIT)(input) + take_while_m_n(1, 3, is_digit)(input) } /// IPv6-address-literal = "IPv6:" IPv6-addr diff --git a/src/parse/command.rs b/src/parse/command.rs index a66ea92..be8d953 100644 --- a/src/parse/command.rs +++ b/src/parse/command.rs @@ -1,7 +1,7 @@ -use abnf_core::streaming::{is_ALPHA, is_DIGIT, CRLF, SP}; use nom::{ branch::alt, bytes::streaming::{tag, tag_no_case, take_while, take_while1, take_while_m_n}, + character::{is_alphabetic, is_digit}, combinator::{map, map_res, opt, recognize, value}, multi::separated_list1, sequence::{delimited, preceded, tuple}, @@ -22,18 +22,18 @@ pub fn command(input: &[u8]) -> IResult<&[u8], Command> { ))(input) } -/// helo = "HELO" SP Domain CRLF +/// helo = "HELO" tag(" ") Domain CRLF pub fn helo(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"HELO"), - SP, + tag(" "), alt(( map(Domain, |domain| DomainOrAddress::Domain(domain.into())), map(address_literal, |address| { DomainOrAddress::Address(address.into()) }), )), - CRLF, + tag("\r\n"), )); let (remaining, (_, _, domain_or_address, _)) = parser(input)?; @@ -41,18 +41,18 @@ pub fn helo(input: &[u8]) -> IResult<&[u8], Command> { Ok((remaining, Command::Helo { domain_or_address })) } -/// ehlo = "EHLO" SP ( Domain / address-literal ) CRLF +/// ehlo = "EHLO" tag(" ") ( Domain / address-literal ) CRLF pub fn ehlo(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"EHLO"), - SP, + tag(" "), alt(( map(Domain, |domain| DomainOrAddress::Domain(domain.into())), map(address_literal, |address| { DomainOrAddress::Address(address.into()) }), )), - CRLF, + tag("\r\n"), )); let (remaining, (_, _, domain_or_address, _)) = parser(input)?; @@ -60,14 +60,14 @@ pub fn ehlo(input: &[u8]) -> IResult<&[u8], Command> { Ok((remaining, Command::Ehlo { domain_or_address })) } -/// mail = "MAIL FROM:" Reverse-path [SP Mail-parameters] CRLF +/// mail = "MAIL FROM:" Reverse-path [tag(" ") Mail-parameters] CRLF pub fn mail(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"MAIL FROM:"), - opt(SP), // Out-of-Spec, but Outlook does it ... + opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ... Reverse_path, - opt(preceded(SP, Mail_parameters)), - CRLF, + opt(preceded(tag(" "), Mail_parameters)), + tag("\r\n"), )); let (remaining, (_, _, data, maybe_params, _)) = parser(input)?; @@ -81,9 +81,9 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> { )) } -/// Mail-parameters = esmtp-param *(SP esmtp-param) +/// Mail-parameters = esmtp-param *(tag(" ") esmtp-param) pub fn Mail_parameters(input: &[u8]) -> IResult<&[u8], Vec> { - separated_list1(SP, esmtp_param)(input) + separated_list1(tag(" "), esmtp_param)(input) } /// esmtp-param = esmtp-keyword ["=" esmtp-value] @@ -105,8 +105,8 @@ pub fn esmtp_param(input: &[u8]) -> IResult<&[u8], Parameter> { /// esmtp-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-") pub fn esmtp_keyword(input: &[u8]) -> IResult<&[u8], &str> { let parser = tuple(( - take_while_m_n(1, 1, |byte| is_ALPHA(byte) || is_DIGIT(byte)), - take_while(|byte| is_ALPHA(byte) || is_DIGIT(byte) || byte == b'-'), + take_while_m_n(1, 1, |byte| is_alphabetic(byte) || is_digit(byte)), + take_while(|byte| is_alphabetic(byte) || is_digit(byte) || byte == b'-'), )); let (remaining, parsed) = map_res(recognize(parser), std::str::from_utf8)(input)?; @@ -114,7 +114,7 @@ pub fn esmtp_keyword(input: &[u8]) -> IResult<&[u8], &str> { Ok((remaining, parsed)) } -/// Any CHAR excluding "=", SP, and control characters. +/// Any CHAR excluding "=", tag(" "), and control characters. /// If this string is an email address, i.e., a Mailbox, /// then the "xtext" syntax [32] SHOULD be used. /// @@ -127,7 +127,7 @@ pub fn esmtp_value(input: &[u8]) -> IResult<&[u8], &str> { map_res(take_while1(is_value_character), std::str::from_utf8)(input) } -/// rcpt = "RCPT TO:" ( "" / "" / Forward-path ) [SP Rcpt-parameters] CRLF +/// rcpt = "RCPT TO:" ( "" / "" / Forward-path ) [tag(" ") Rcpt-parameters] CRLF /// /// Note that, in a departure from the usual rules for /// local-parts, the "Postmaster" string shown above is @@ -135,7 +135,7 @@ pub fn esmtp_value(input: &[u8]) -> IResult<&[u8], &str> { pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"RCPT TO:"), - opt(SP), // Out-of-Spec, but Outlook does it ... + opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ... alt(( map_res( recognize(tuple((tag_no_case("")))), @@ -144,8 +144,8 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> { map_res(tag_no_case(""), std::str::from_utf8), Forward_path, )), - opt(preceded(SP, Rcpt_parameters)), - CRLF, + opt(preceded(tag(" "), Rcpt_parameters)), + tag("\r\n"), )); let (remaining, (_, _, data, maybe_params, _)) = parser(input)?; @@ -159,24 +159,24 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> { )) } -/// Rcpt-parameters = esmtp-param *(SP esmtp-param) +/// Rcpt-parameters = esmtp-param *(tag(" ") esmtp-param) pub fn Rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec> { - separated_list1(SP, esmtp_param)(input) + separated_list1(tag(" "), esmtp_param)(input) } /// data = "DATA" CRLF pub fn data(input: &[u8]) -> IResult<&[u8], Command> { - value(Command::Data, tuple((tag_no_case(b"DATA"), CRLF)))(input) + value(Command::Data, tuple((tag_no_case(b"DATA"), tag("\r\n"))))(input) } /// rset = "RSET" CRLF pub fn rset(input: &[u8]) -> IResult<&[u8], Command> { - value(Command::Rset, tuple((tag_no_case(b"RSET"), CRLF)))(input) + value(Command::Rset, tuple((tag_no_case(b"RSET"), tag("\r\n"))))(input) } -/// vrfy = "VRFY" SP String CRLF +/// vrfy = "VRFY" tag(" ") String CRLF pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"VRFY"), SP, String, CRLF)); + let mut parser = tuple((tag_no_case(b"VRFY"), tag(" "), String, tag("\r\n"))); let (remaining, (_, _, data, _)) = parser(input)?; @@ -188,18 +188,22 @@ pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> { )) } -/// expn = "EXPN" SP String CRLF +/// expn = "EXPN" tag(" ") String CRLF pub fn expn(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"EXPN"), SP, String, CRLF)); + let mut parser = tuple((tag_no_case(b"EXPN"), tag(" "), String, tag("\r\n"))); let (remaining, (_, _, data, _)) = parser(input)?; Ok((remaining, Command::Expn { mailing_list: data })) } -/// help = "HELP" [ SP String ] CRLF +/// help = "HELP" [ tag(" ") String ] CRLF pub fn help(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"HELP"), opt(preceded(SP, String)), CRLF)); + let mut parser = tuple(( + tag_no_case(b"HELP"), + opt(preceded(tag(" "), String)), + tag("\r\n"), + )); let (remaining, (_, maybe_data, _)) = parser(input)?; @@ -211,9 +215,13 @@ pub fn help(input: &[u8]) -> IResult<&[u8], Command> { )) } -/// noop = "NOOP" [ SP String ] CRLF +/// noop = "NOOP" [ tag(" ") String ] CRLF pub fn noop(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"NOOP"), opt(preceded(SP, String)), CRLF)); + let mut parser = tuple(( + tag_no_case(b"NOOP"), + opt(preceded(tag(" "), String)), + tag("\r\n"), + )); let (remaining, (_, maybe_data, _)) = parser(input)?; @@ -227,11 +235,14 @@ pub fn noop(input: &[u8]) -> IResult<&[u8], Command> { /// quit = "QUIT" CRLF pub fn quit(input: &[u8]) -> IResult<&[u8], Command> { - value(Command::Quit, tuple((tag_no_case(b"QUIT"), CRLF)))(input) + value(Command::Quit, tuple((tag_no_case(b"QUIT"), tag("\r\n"))))(input) } pub fn starttls(input: &[u8]) -> IResult<&[u8], Command> { - value(Command::StartTLS, tuple((tag_no_case(b"STARTTLS"), CRLF)))(input) + value( + Command::StartTLS, + tuple((tag_no_case(b"STARTTLS"), tag("\r\n"))), + )(input) } /// https://interoperability.blob.core.windows.net/files/MS-XLOGIN/[MS-XLOGIN].pdf @@ -239,19 +250,19 @@ pub fn starttls(input: &[u8]) -> IResult<&[u8], Command> { /// username = 1*CHAR ; Base64-encoded username /// password = 1*CHAR ; Base64-encoded password /// -/// auth_login_command = "AUTH LOGIN" [SP username] CRLF +/// auth_login_command = "AUTH LOGIN" [tag(" ") username] CRLF /// /// auth_login_username_challenge = "334 VXNlcm5hbWU6" CRLF -/// auth_login_username_response = username CRLF +/// auth_login_username_retag(" ")onse = username CRLF /// auth_login_password_challenge = "334 UGFzc3dvcmQ6" CRLF -/// auth_login_password_response = password CRLF +/// auth_login_password_retag(" ")onse = password CRLF pub fn auth_login(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"AUTH"), - SP, + tag(" "), tag_no_case("LOGIN"), - opt(preceded(SP, base64)), - CRLF, + opt(preceded(tag(" "), base64)), + tag("\r\n"), )); let (remaining, (_, _, _, maybe_username_b64, _)) = parser(input)?; @@ -265,10 +276,10 @@ pub fn auth_login(input: &[u8]) -> IResult<&[u8], Command> { pub fn auth_plain(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"AUTH"), - SP, + tag(" "), tag_no_case("PLAIN"), - opt(preceded(SP, base64)), - CRLF, + opt(preceded(tag(" "), base64)), + tag("\r\n"), )); let (remaining, (_, _, _, maybe_credentials_b64, _)) = parser(input)?; diff --git a/src/parse/imf.rs b/src/parse/imf.rs index 9025677..8b878ed 100644 --- a/src/parse/imf.rs +++ b/src/parse/imf.rs @@ -4,7 +4,6 @@ /// 3.2.1. Quoted characters pub mod quoted_characters { - use abnf_core::streaming::{is_VCHAR, WSP}; use nom::{ branch::alt, bytes::streaming::{tag, take_while_m_n}, @@ -20,7 +19,10 @@ pub mod quoted_characters { let parser = alt(( recognize(tuple(( tag(b"\\"), - alt((take_while_m_n(1, 1, is_VCHAR), WSP)), + alt(( + take_while_m_n(1, 1, |byte| matches!(byte, 0x21..=0x7E)), + alt((tag(" "), tag("\t"))), + )), ))), obs_qp, )); @@ -58,9 +60,9 @@ pub mod folding_ws_and_comment { /// 3.2.3. Atom pub mod atom { - use abnf_core::streaming::{is_ALPHA, is_DIGIT}; use nom::{ bytes::streaming::{tag, take_while1}, + character::{is_alphabetic, is_digit}, combinator::{opt, recognize}, multi::many0, sequence::tuple, @@ -86,7 +88,7 @@ pub mod atom { pub fn is_atext(byte: u8) -> bool { let allowed = b"!#$%&'*+-/=?^_`{|}~"; - is_ALPHA(byte) || is_DIGIT(byte) || allowed.contains(&byte) + is_alphabetic(byte) || is_digit(byte) || allowed.contains(&byte) } /// atom = [CFWS] 1*atext [CFWS] @@ -133,10 +135,9 @@ pub mod atom { /// 3.2.4. Quoted Strings pub mod quoted_strings { - use abnf_core::streaming::DQUOTE; use nom::{ branch::alt, - bytes::streaming::take_while_m_n, + bytes::streaming::{tag, take_while_m_n}, combinator::{opt, recognize}, multi::many0, sequence::tuple, @@ -173,10 +174,10 @@ pub mod quoted_strings { pub fn quoted_string(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = tuple(( opt(CFWS), - DQUOTE, + tag("\""), many0(tuple((opt(FWS), qcontent))), opt(FWS), - DQUOTE, + tag("\""), opt(CFWS), )); @@ -206,10 +207,10 @@ pub mod miscellaneous { /// 3.3. Date and Time Specification pub mod datetime { - use abnf_core::streaming::is_DIGIT; use nom::{ branch::alt, bytes::streaming::{tag, tag_no_case, take_while_m_n}, + character::is_digit, combinator::{opt, recognize}, sequence::tuple, IResult, @@ -263,7 +264,7 @@ pub mod datetime { // day = ([FWS] 1*2DIGIT FWS) / obs-day pub fn day(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((opt(FWS), take_while_m_n(1, 2, is_DIGIT), FWS)); + let parser = tuple((opt(FWS), take_while_m_n(1, 2, is_digit), FWS)); let (remaining, parsed) = recognize(parser)(input)?; @@ -294,7 +295,7 @@ pub mod datetime { // year = (FWS 4*DIGIT FWS) / obs-year pub fn year(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((FWS, take_while_m_n(4, 8, is_DIGIT), FWS)); // FIXME: 4*?! + let parser = tuple((FWS, take_while_m_n(4, 8, is_digit), FWS)); // FIXME: 4*?! let (remaining, parsed) = recognize(parser)(input)?; @@ -323,7 +324,7 @@ pub mod datetime { pub fn hour(input: &[u8]) -> IResult<&[u8], &[u8]> { // FIXME: obs- forms must not be used in SMTP. Never? - let parser = take_while_m_n(2, 2, is_DIGIT); + let parser = take_while_m_n(2, 2, is_digit); let (remaining, parsed) = recognize(parser)(input)?; @@ -334,7 +335,7 @@ pub mod datetime { pub fn minute(input: &[u8]) -> IResult<&[u8], &[u8]> { // FIXME: obs- forms must not be used in SMTP. Never? - let parser = take_while_m_n(2, 2, is_DIGIT); + let parser = take_while_m_n(2, 2, is_digit); let (remaining, parsed) = recognize(parser)(input)?; @@ -345,7 +346,7 @@ pub mod datetime { pub fn second(input: &[u8]) -> IResult<&[u8], &[u8]> { // FIXME: obs- forms must not be used in SMTP. Never? - let parser = take_while_m_n(2, 2, is_DIGIT); + let parser = take_while_m_n(2, 2, is_digit); let (remaining, parsed) = recognize(parser)(input)?; @@ -359,7 +360,7 @@ pub mod datetime { let parser = tuple(( FWS, alt((tag(b"+"), tag(b"-"))), - take_while_m_n(4, 4, is_DIGIT), + take_while_m_n(4, 4, is_digit), )); let (remaining, parsed) = recognize(parser)(input)?; @@ -520,7 +521,6 @@ pub mod identification { /// 4.1. Miscellaneous Obsolete Tokens pub mod obsolete { - use abnf_core::streaming::{CR, LF}; use nom::{ branch::alt, bytes::streaming::{tag, take_while_m_n}, @@ -557,8 +557,8 @@ pub mod obsolete { alt(( take_while_m_n(1, 1, |x| x == 0x00), take_while_m_n(1, 1, is_obs_NO_WS_CTL), - LF, - CR, + tag("\n"), + tag("\r"), )), )); diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 39f962c..7a940b8 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -2,11 +2,11 @@ use std::{borrow::Cow, str::from_utf8}; -use abnf_core::streaming::{is_ALPHA, is_DIGIT, DQUOTE}; use nom::{ branch::alt, bytes::streaming::{tag, take_while, take_while1, take_while_m_n}, character::streaming::digit1, + character::{is_alphabetic, is_digit}, combinator::{map, map_res, opt, recognize}, multi::{many0, separated_list1}, sequence::{delimited, tuple}, @@ -37,7 +37,7 @@ pub fn base64(input: &[u8]) -> IResult<&[u8], &str> { } fn is_base64_char(i: u8) -> bool { - is_ALPHA(i) || is_DIGIT(i) || i == b'+' || i == b'/' + is_alphabetic(i) || is_digit(i) || i == b'+' || i == b'/' } pub fn number(input: &[u8]) -> IResult<&[u8], u32> { @@ -63,9 +63,9 @@ pub fn Atom(input: &[u8]) -> IResult<&[u8], &str> { pub fn Quoted_string(input: &[u8]) -> IResult<&[u8], Cow<'_, str>> { map( delimited( - DQUOTE, + tag("\""), map_res(recognize(many0(QcontentSMTP)), std::str::from_utf8), - DQUOTE, + tag("\""), ), unescape_quoted, )(input) @@ -132,14 +132,14 @@ pub fn sub_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { /// Let-dig = ALPHA / DIGIT pub fn is_Let_dig(byte: u8) -> bool { - is_ALPHA(byte) || is_DIGIT(byte) + is_alphabetic(byte) || is_digit(byte) } /// Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig pub fn Ldh_str(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = many0(alt(( - take_while_m_n(1, 1, is_ALPHA), - take_while_m_n(1, 1, is_DIGIT), + take_while_m_n(1, 1, is_alphabetic), + take_while_m_n(1, 1, is_digit), recognize(tuple((tag(b"-"), take_while_m_n(1, 1, is_Let_dig)))), ))); diff --git a/src/parse/response.rs b/src/parse/response.rs index 00a5a26..62cd8a5 100644 --- a/src/parse/response.rs +++ b/src/parse/response.rs @@ -1,9 +1,9 @@ use std::str::FromStr; -use abnf_core::streaming::{is_ALPHA, is_DIGIT, CRLF, SP}; use nom::{ branch::alt, bytes::streaming::{tag, tag_no_case, take_while, take_while1, take_while_m_n}, + character::{is_alphabetic, is_digit}, combinator::{map, map_res, opt, recognize, value}, multi::{many0, separated_list0}, sequence::{delimited, preceded, tuple}, @@ -25,8 +25,8 @@ pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> { tuple(( tag(b"220 "), alt((Domain, address_literal)), - opt(preceded(SP, textstring)), - CRLF, + opt(preceded(tag(" "), textstring)), + tag("\r\n"), )), |(_, domain, maybe_text, _)| Response::Greeting { domain: domain.to_owned(), @@ -39,12 +39,12 @@ pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> { tuple(( tag(b"220-"), alt((Domain, address_literal)), - opt(preceded(SP, textstring)), - CRLF, - many0(delimited(tag(b"220-"), opt(textstring), CRLF)), + opt(preceded(tag(" "), textstring)), + tag("\r\n"), + many0(delimited(tag(b"220-"), opt(textstring), tag("\r\n"))), tag(b"220"), - opt(preceded(SP, textstring)), - CRLF, + opt(preceded(tag(" "), textstring)), + tag("\r\n"), )), |(_, domain, maybe_text, _, more_text, _, moar_text, _)| Response::Greeting { domain: domain.to_owned(), @@ -76,7 +76,7 @@ pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> { Ok((remaining, parsed)) } -/// HT, SP, Printable US-ASCII +/// HT, tag(" "), Printable US-ASCII /// /// textstring = 1*(%d09 / %d32-126) pub fn textstring(input: &[u8]) -> IResult<&[u8], TextString<'_>> { @@ -97,10 +97,10 @@ pub(crate) fn is_text_string_byte(byte: u8) -> bool { pub fn Reply_lines(input: &[u8]) -> IResult<&[u8], Response> { let mut parser = map( tuple(( - many0(tuple((Reply_code, tag(b"-"), opt(textstring), CRLF))), + many0(tuple((Reply_code, tag(b"-"), opt(textstring), tag("\r\n")))), Reply_code, - opt(tuple((SP, textstring))), - CRLF, + opt(tuple((tag(" "), textstring))), + tag("\r\n"), )), |(intermediate, code, text, _)| { let mut lines = @@ -151,7 +151,12 @@ pub fn Reply_code(input: &[u8]) -> IResult<&[u8], ReplyCode> { pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> { let mut parser = alt(( map( - tuple((tag(b"250 "), Domain, opt(preceded(SP, ehlo_greet)), CRLF)), + tuple(( + tag(b"250 "), + Domain, + opt(preceded(tag(" "), ehlo_greet)), + tag("\r\n"), + )), |(_, domain, maybe_ehlo, _)| Response::Ehlo { domain: domain.to_owned(), greet: maybe_ehlo.map(|ehlo| ehlo.to_owned()), @@ -162,12 +167,12 @@ pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> { tuple(( tag(b"250-"), Domain, - opt(preceded(SP, ehlo_greet)), - CRLF, - many0(delimited(tag(b"250-"), ehlo_line, CRLF)), + opt(preceded(tag(" "), ehlo_greet)), + tag("\r\n"), + many0(delimited(tag(b"250-"), ehlo_line, tag("\r\n"))), tag(b"250 "), ehlo_line, - CRLF, + tag("\r\n"), )), |(_, domain, maybe_ehlo, _, mut lines, _, line, _)| Response::Ehlo { domain: domain.to_owned(), @@ -203,14 +208,14 @@ pub fn ehlo_line(input: &[u8]) -> IResult<&[u8], Capability> { let auth = tuple(( tag_no_case("AUTH"), alt((tag_no_case(" "), tag_no_case("="))), - separated_list0(SP, auth_mechanism), + separated_list0(tag(" "), auth_mechanism), )); let other = tuple(( map_res(ehlo_keyword, std::str::from_utf8), opt(preceded( - alt((SP, tag("="))), // TODO: For Outlook? - separated_list0(SP, ehlo_param), + alt((tag(" "), tag("="))), // TODO: For Outlook? + separated_list0(tag(" "), ehlo_param), )), )); @@ -257,8 +262,8 @@ pub fn ehlo_line(input: &[u8]) -> IResult<&[u8], Capability> { /// ehlo-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-") pub fn ehlo_keyword(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = tuple(( - take_while_m_n(1, 1, |byte| is_ALPHA(byte) || is_DIGIT(byte)), - take_while(|byte| is_ALPHA(byte) || is_DIGIT(byte) || byte == b'-'), + take_while_m_n(1, 1, |byte| is_alphabetic(byte) || is_digit(byte)), + take_while(|byte| is_alphabetic(byte) || is_digit(byte) || byte == b'-'), )); let (remaining, parsed) = recognize(parser)(input)?; diff --git a/src/parse/trace.rs b/src/parse/trace.rs index 76e18fa..4ea8635 100644 --- a/src/parse/trace.rs +++ b/src/parse/trace.rs @@ -1,5 +1,4 @@ /// 4.4. Trace Information (RFC 5321) -use abnf_core::streaming::CRLF; use nom::{ branch::alt, bytes::streaming::{tag, tag_no_case}, @@ -22,7 +21,7 @@ use crate::parse::{ /// Return-path-line = "Return-Path:" FWS Reverse-path pub fn Return_path_line(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((tag_no_case(b"Return-Path:"), FWS, Reverse_path, CRLF)); + let parser = tuple((tag_no_case(b"Return-Path:"), FWS, Reverse_path, tag("\r\n"))); let (remaining, parsed) = recognize(parser)(input)?; @@ -31,7 +30,7 @@ pub fn Return_path_line(input: &[u8]) -> IResult<&[u8], &[u8]> { /// Time-stamp-line = "Received:" FWS Stamp pub fn Time_stamp_line(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((tag_no_case(b"Received:"), FWS, Stamp, CRLF)); + let parser = tuple((tag_no_case(b"Received:"), FWS, Stamp, tag("\r\n"))); let (remaining, parsed) = recognize(parser)(input)?;