diff --git a/script/cibuild b/script/cibuild index 629cab15..60a592ba 100755 --- a/script/cibuild +++ b/script/cibuild @@ -6,6 +6,7 @@ if command -v apt-get &>/dev/null; then sudo apt-get install python3 fi +failed=0 if [ x"$SPEC" = "xtrue" ]; then cargo build --verbose --release @@ -14,22 +15,41 @@ if [ x"$SPEC" = "xtrue" ]; then PROGRAM_ARG="--program=../../../target/release/comrak --syntax-highlighting none" - python3 spec_tests.py --no-normalize --spec spec.txt "$PROGRAM_ARG" - python3 pathological_tests.py "$PROGRAM_ARG" - python3 roundtrip_tests.py --spec spec.txt "$PROGRAM_ARG" - python3 entity_tests.py "$PROGRAM_ARG" - python3 spec_tests.py --no-normalize --spec smart_punct.txt "$PROGRAM_ARG --smart" - - python3 spec_tests.py --no-normalize --spec extensions.txt "$PROGRAM_ARG" --extensions "table strikethrough autolink tagfilter footnotes tasklist" - python3 roundtrip_tests.py --spec extensions.txt "$PROGRAM_ARG" --extensions "table strikethrough autolink tagfilter footnotes tasklist" - # python3 roundtrip_tests.py --spec extensions-table-prefer-style-attributes.txt "$PROGRAM_ARG --table-prefer-style-attributes" --extensions "table strikethrough autolink tagfilter footnotes tasklist" - python3 roundtrip_tests.py --spec extensions-full-info-string.txt "$PROGRAM_ARG --full-info-string" - - python3 spec_tests.py --no-normalize --spec regression.txt "$PROGRAM_ARG" + set +e + python3 spec_tests.py --no-normalize --spec spec.txt "$PROGRAM_ARG" \ + || failed=1 + python3 pathological_tests.py "$PROGRAM_ARG" \ + || failed=1 + python3 roundtrip_tests.py --spec spec.txt "$PROGRAM_ARG" \ + || failed=1 + python3 entity_tests.py "$PROGRAM_ARG" \ + || failed=1 + python3 spec_tests.py --no-normalize --spec smart_punct.txt "$PROGRAM_ARG --smart" \ + || failed=1 + + python3 spec_tests.py --no-normalize --spec extensions.txt "$PROGRAM_ARG" --extensions "table strikethrough autolink tagfilter footnotes tasklist" \ + || failed=1 + python3 roundtrip_tests.py --spec extensions.txt "$PROGRAM_ARG" --extensions "table strikethrough autolink tagfilter footnotes tasklist" \ + || failed=1 + # python3 roundtrip_tests.py --spec extensions-table-prefer-style-attributes.txt "$PROGRAM_ARG --table-prefer-style-attributes" --extensions "table strikethrough autolink tagfilter footnotes tasklist" || failed=1 + python3 roundtrip_tests.py --spec extensions-full-info-string.txt "$PROGRAM_ARG --full-info-string" \ + || failed=1 + + python3 spec_tests.py --no-normalize --spec regression.txt "$PROGRAM_ARG" \ + || failed=1 + set -e else - cargo build --verbose - cargo build --verbose --examples - - cargo test --verbose - cargo run --example sample + set +e + cargo build --verbose \ + || failed=1 + cargo build --verbose --examples \ + || failed=1 + + cargo test --verbose \ + || failed=1 + cargo run --example sample \ + || failed=1 + set -e fi + +exit $failed diff --git a/src/parser/autolink.rs b/src/parser/autolink.rs index 8a9b3aff..b5d17b17 100644 --- a/src/parser/autolink.rs +++ b/src/parser/autolink.rs @@ -278,6 +278,8 @@ fn email_match<'a>( let size = contents.len(); + let mut auto_mailto = true; + let mut is_xmpp = false; let mut rewind = 0; while rewind < i { @@ -288,6 +290,21 @@ fn email_match<'a>( continue; } + if c == b':' { + if validate_protocol("mailto", contents, i - rewind - 1) { + auto_mailto = false; + rewind += 1; + continue; + } + + if validate_protocol("xmpp", contents, i - rewind - 1) { + is_xmpp = true; + auto_mailto = false; + rewind += 1; + continue; + } + } + break; } @@ -307,6 +324,8 @@ fn email_match<'a>( return None; } else if c == b'.' && link_end < size - i - 1 && isalnum(contents[i + link_end + 1]) { np += 1; + } else if c == b'/' && is_xmpp { + // xmpp allows a `/` in the url } else if c != b'-' && c != b'_' { break; } @@ -326,7 +345,11 @@ fn email_match<'a>( return None; } - let mut url = "mailto:".to_string(); + let mut url = if auto_mailto { + "mailto:".to_string() + } else { + "".to_string() + }; let text = str::from_utf8(&contents[i - rewind..link_end + i]).unwrap(); url.push_str(text); @@ -346,3 +369,15 @@ fn email_match<'a>( )); Some((inl, rewind, rewind + link_end)) } + +fn validate_protocol(protocol: &str, contents: &[u8], cursor: usize) -> bool { + let size = contents.len(); + let mut rewind = 0; + + while rewind < cursor && isalpha(contents[cursor - rewind - 1]) { + rewind += 1; + } + + size - cursor + rewind >= protocol.len() + && &contents[cursor - rewind..cursor] == protocol.as_bytes() +} diff --git a/vendor/cmark-gfm b/vendor/cmark-gfm index fd023f62..2f13eeed 160000 --- a/vendor/cmark-gfm +++ b/vendor/cmark-gfm @@ -1 +1 @@ -Subproject commit fd023f629d2f9fb8e25fd239f01f48a0c453172d +Subproject commit 2f13eeedfe9906c72a1843b03552550af7bee29a