Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ Options:
Enable relaxing which character is allowed in a tasklists

--relaxed-autolinks
Enable relaxing of autolink parsing, allowing links to be recognized when in brackets
Enable relaxing of autolink parsing, allow links to be recognized when in brackets
and allow all url schemes

--default-info-string <INFO>
Default value for fenced code block's info strings if none is given
Expand Down
78 changes: 74 additions & 4 deletions fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ struct Cli {
#[arg(long)]
relaxed_tasklist_character: bool,

/// Enable relaxing of autolink parsing, allowing links to be recognized when in brackets
/// Enable relaxing of autolink parsing, allow links to be recognized when in brackets
/// and allow all url schemes
#[arg(long)]
relaxed_autolinks: bool,

Expand Down
11 changes: 7 additions & 4 deletions src/parser/autolink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(crate) fn process_autolinks<'a>(

match contents[i] {
b':' => {
post_org = url_match(arena, contents, i);
post_org = url_match(arena, contents, i, relaxed_autolinks);
if post_org.is_some() {
break;
}
Expand Down Expand Up @@ -235,6 +235,7 @@ fn url_match<'a>(
arena: &'a Arena<AstNode<'a>>,
contents: &[u8],
i: usize,
relaxed_autolinks: bool,
) -> Option<(&'a AstNode<'a>, usize, usize)> {
const SCHEMES: [&[u8]; 3] = [b"http", b"https", b"ftp"];

Expand All @@ -249,9 +250,11 @@ fn url_match<'a>(
rewind += 1;
}

let cond = |s: &&[u8]| size - i + rewind >= s.len() && &&contents[i - rewind..i] == s;
if !SCHEMES.iter().any(cond) {
return None;
if !relaxed_autolinks {
let cond = |s: &&[u8]| size - i + rewind >= s.len() && &&contents[i - rewind..i] == s;
if !SCHEMES.iter().any(cond) {
return None;
}
}

let mut link_end = match check_domain(&contents[i + 3..], true) {
Expand Down
3 changes: 2 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,8 @@ pub struct ParseOptions {
/// Whether or not a simple `x` or `X` is used for tasklist or any other symbol is allowed.
pub relaxed_tasklist_matching: bool,

/// Relax parsing of autolinks, allowing links to be detected inside brackets.
/// Relax parsing of autolinks, allow links to be detected inside brackets
/// and allow all url schemes
///
/// ```
/// # use comrak::{markdown_to_html, Options};
Expand Down
36 changes: 33 additions & 3 deletions src/tests/autolink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ fn autolink_email() {
fn autolink_scheme() {
html_opts!(
[extension.autolink],
concat!("https://google.com/search\n"),
concat!("https://google.com/search\n", "rdar://localhost.com/blah"),
concat!(
"<p><a href=\"https://google.com/search\">https://google.\
com/search</a></p>\n"
"<p><a href=\"https://google.com/search\">https://google.com/search</a>\n",
"rdar://localhost.com/blah</p>\n"
),
);
}
Expand Down Expand Up @@ -102,6 +102,36 @@ fn autolink_relaxed_links_in_brackets() {
}
}

#[test]
fn autolink_relaxed_links_schemes() {
let examples = [
[
"https://foo.com",
"<p><a href=\"https://foo.com\">https://foo.com</a></p>\n",
],
[
"smb:///Volumes/shared/foo.pdf",
"<p><a href=\"smb:///Volumes/shared/foo.pdf\">smb:///Volumes/shared/foo.pdf</a></p>\n",
],
[
"irc://irc.freenode.net/git",
"<p><a href=\"irc://irc.freenode.net/git\">irc://irc.freenode.net/git</a></p>\n",
],
[
"rdar://localhost.com/blah",
"<p><a href=\"rdar://localhost.com/blah\">rdar://localhost.com/blah</a></p>\n",
],
];

for example in examples {
html_opts!(
[extension.autolink, parse.relaxed_autolinks],
example[0],
example[1]
);
}
}

#[test]
fn sourcepos_correctly_restores_context() {
// There's unsoundness in trying to maintain and adjust sourcepos
Expand Down