diff --git a/src/parser/link_url/parse_link.rs b/src/parser/link_url/parse_link.rs index 9ff1d93..f4e288b 100644 --- a/src/parser/link_url/parse_link.rs +++ b/src/parser/link_url/parse_link.rs @@ -368,6 +368,9 @@ fn parse_iri(input: &str) -> IResult<&str, LinkDestination, CustomError<&str>> { .saturating_add(authority.len()) .saturating_add(host.len()) .saturating_add(path.len()); + if ihier_len == 3 { + return Err(nom::Err::Error(CustomError::InvalidLink)); + } // compute length of authority + host + path let mut len = scheme .len() @@ -417,8 +420,9 @@ fn parse_generic(input: &str) -> IResult<&str, LinkDestination, CustomError<&str if !is_allowed_generic_scheme(scheme) { return Err(nom::Err::Error(CustomError::InvalidLink)); } - let (input, rest) = take_while(is_not_white_space)(input)?; - let len = scheme.len().saturating_add(rest.len()); + let (input, _colon) = char(':')(input)?; + let (input, rest) = take_while1(is_not_white_space)(input)?; + let len = scheme.len().saturating_add(rest.len()).saturating_add(1); if let Some(target) = i.get(0..len) { return Ok(( input, diff --git a/tests/links.rs b/tests/links.rs index a743ae5..0f8f94a 100644 --- a/tests/links.rs +++ b/tests/links.rs @@ -47,6 +47,17 @@ fn basic_parsing() { } } +#[test] +fn bare_scheme_no_parse() { + // bare scheme shouldn't be linkified + let bare = vec!["tel", "tel:", "bitcoin:", "mailto", "https://", "http://"]; + + for input in bare { + let result = LinkDestination::parse(input); + assert!(result.is_err()); + } +} + #[test] fn invalid_domains() { let test_cases = vec![";?:/hi", "##://thing"];