lycheeverse/lychee

Windows Filepaths With a Drive Specifier Incorrectly Identified as Urls

toadslop opened this issue · 1 comments

Hello, this is the first of the other issues that I mentioned in #1454.

Many tests in the test suite are failing because the Url crate will erroneously parse a windows filebath with a drive specifier as a url. An example of the test results are included below. Note in particular the Network Errors caused by 'URL Scheme is not allowed'.

        FAIL [   0.565s] lychee::example_domains cli::test_do_not_exclude_false_positive_example_domains

--- STDOUT:              lychee::example_domains cli::test_do_not_exclude_false_positive_example_domains ---

running 1 test
test cli::test_do_not_exclude_false_positive_example_domains ... FAILED

failures:

failures:
    cli::test_do_not_exclude_false_positive_example_domains

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.55s


--- STDERR:              lychee::example_domains cli::test_do_not_exclude_false_positive_example_domains ---
thread 'cli::test_do_not_exclude_false_positive_example_domains' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_EXAMPLE_DOMAINS_FALSE_POSITIVES.md)
    1: URL scheme is not allowed
command=`"C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_EXAMPLE_DOMAINS_FALSE_POSITIVES.md" "--include-mail" "--dump"`
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_EXAMPLE_DOMAINS_FALSE_POSITIVES.md)
    1: URL scheme is not allowed

note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Canceling due to test failure: 7 tests still running
FAIL [ 0.574s] lychee::data_uris cli::test_dump_data_uris_in_verbose_mode

--- STDOUT: lychee::data_uris cli::test_dump_data_uris_in_verbose_mode ---

running 1 test
test cli::test_dump_data_uris_in_verbose_mode ... FAILED

failures:

failures:
cli::test_dump_data_uris_in_verbose_mode

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.56s

--- STDERR: lychee::data_uris cli::test_dump_data_uris_in_verbose_mode ---
thread 'cli::test_dump_data_uris_in_verbose_mode' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\source\repos\lychee\fixtures\TEST_DATA_URIS.html)
1: URL scheme is not allowed

command="C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_DATA_URIS.html" "--dump" "--verbose"
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\source\repos\lychee\fixtures\TEST_DATA_URIS.html)
1: URL scheme is not allowed



note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

        FAIL [   0.560s] lychee::local_files cli::test_local_file

--- STDOUT:              lychee::local_files cli::test_local_file ---

running 1 test
test cli::test_local_file ... FAILED

failures:

failures:
    cli::test_local_file

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.54s


--- STDERR:              lychee::local_files cli::test_local_file ---
thread 'cli::test_local_file' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\AppData\\Local\\Temp\\.tmpaYJnxn\\index.html)
    1: URL scheme is not allowed
command=`"C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\AppData\\Local\\Temp\\.tmpaYJnxn\\index.html" "--no-progress" "--verbose"`
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\AppData\\Local\\Temp\\.tmpaYJnxn\\index.html)
    1: URL scheme is not allowed

note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

    FAIL [   0.569s] lychee::local_files cli::test_local_dir

--- STDOUT: lychee::local_files cli::test_local_dir ---

running 1 test
test cli::test_local_dir ... FAILED

failures:

failures:
cli::test_local_dir

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.55s

--- STDERR: lychee::local_files cli::test_local_dir ---
thread 'cli::test_local_dir' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\AppData\Local\Temp\.tmpxxgIJG)
1: URL scheme is not allowed

command="C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\AppData\\Local\\Temp\\.tmpxxgIJG" "--no-progress" "--verbose"
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\AppData\Local\Temp\.tmpxxgIJG)
1: URL scheme is not allowed



note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

        FAIL [   0.593s] lychee::data_uris cli::test_dont_dump_data_uris_by_default

--- STDOUT:              lychee::data_uris cli::test_dont_dump_data_uris_by_default ---

running 1 test
test cli::test_dont_dump_data_uris_by_default ... FAILED

failures:

failures:
    cli::test_dont_dump_data_uris_by_default

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.57s


--- STDERR:              lychee::data_uris cli::test_dont_dump_data_uris_by_default ---
thread 'cli::test_dont_dump_data_uris_by_default' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_DATA_URIS.html)
    1: URL scheme is not allowed
command=`"C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_DATA_URIS.html" "--dump"`
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
    0: builder error for url (c:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_DATA_URIS.html)
    1: URL scheme is not allowed

note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

    FAIL [   0.589s] lychee::example_domains cli::test_exclude_example_domains

--- STDOUT: lychee::example_domains cli::test_exclude_example_domains ---

running 1 test
test cli::test_exclude_example_domains ... FAILED

failures:

failures:
cli::test_exclude_example_domains

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.56s

--- STDERR: lychee::example_domains cli::test_exclude_example_domains ---
thread 'cli::test_exclude_example_domains' panicked at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250:5:
Unexpected failure.
code=1
stderr=``````
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\source\repos\lychee\fixtures\TEST_EXAMPLE_DOMAINS.md)
1: URL scheme is not allowed

command="C:\\Users\\bnhei\\source\\repos\\lychee\\target\\debug\\lychee.exe" "C:\\Users\\bnhei\\source\\repos\\lychee\\fixtures\\TEST_EXAMPLE_DOMAINS.md" "--include-mail" "--dump"
code=1
stdout=""
stderr=```
Error: Network error

Caused by:
0: builder error for url (c:\Users\bnhei\source\repos\lychee\fixtures\TEST_EXAMPLE_DOMAINS.md)
1: URL scheme is not allowed



note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

        PASS [   0.026s] lychee::bin/lychee commands::check::tests::test_show_cached_responses_in_progress_debug_output
        PASS [   0.021s] lychee::bin/lychee commands::check::tests::test_skip_cached_responses_in_progress_output
        PASS [   0.036s] lychee::bin/lychee commands::check::tests::test_invalid_url
        PASS [   0.025s] lychee::bin/lychee formatters::duration::tests::test_formatting
        PASS [   0.028s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_error_status
        PASS [   0.028s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_long_uri
        PASS [   0.023s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_ok_status
        PASS [   0.022s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_error_status
        PASS [   0.018s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_excluded_status
        PASS [   0.027s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_ok_status
        PASS [   0.023s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_redirect_status
        PASS [   0.022s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_unknown_status_code
        PASS [   0.018s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_error_status
        PASS [   0.018s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_excluded_status
        PASS [   0.017s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_unknown_status_code
        PASS [   0.026s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_ok_status
        PASS [   0.026s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_redirect_status
        PASS [   0.017s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_cached_err
        PASS [   0.014s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_cached_ok
        PASS [   0.014s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_ok
        PASS [   0.015s] lychee::bin/lychee formatters::stats::markdown::tests::test_render_stats
        PASS [   1.078s] lychee::bin/lychee archive::wayback::tests::wayback_suggestion
        PASS [   4.059s] lychee::bin/lychee archive::wayback::tests::wayback_suggestion_unknown_url
------------
     Summary [   4.088s] 29/242 tests run: 23 passed, 6 failed, 0 skipped
        FAIL [   0.593s] lychee::data_uris cli::test_dont_dump_data_uris_by_default
        FAIL [   0.574s] lychee::data_uris cli::test_dump_data_uris_in_verbose_mode
        FAIL [   0.565s] lychee::example_domains cli::test_do_not_exclude_false_positive_example_domains
        FAIL [   0.589s] lychee::example_domains cli::test_exclude_example_domains
        FAIL [   0.569s] lychee::local_files cli::test_local_dir
        FAIL [   0.560s] lychee::local_files cli::test_local_file

I tracked this error to Input::new method.

    pub fn new(
        value: &str,
        file_type_hint: Option<FileType>,
        glob_ignore_case: bool,
        excluded_paths: Option<Vec<PathBuf>>,
    ) -> Result<Self> {
        let source = if value == STDIN {
            InputSource::Stdin
        } else if let Ok(url) = Url::parse(value) { //  <-- HERE
            InputSource::RemoteUrl(Box::new(url))
        } else {
       // file handling here

When I checked this in my debugger, I indeed found that Windows filepaths were being identified as Urls:

[lychee-lib\\src\\types\\input.rs:136:9] url = Url {
    scheme: \"c\", // <-- HERE, scheme is c. The file path that I provided was C://etc/etc
    cannot_be_a_base: true,
    username: \"\",
    password: None,
    host: None,
    port: None,
    path: \"\\\\Users\\\\{my-username}\\\\AppData\\\\Local\\\\Temp\\\\.tmpS5lXlI\",
    query: None,
    fragment: None,
}

Short Term Solution

In my investigation, I found that the reqwest crate's RequestBuilder struct will error if you try to construct a request using such a url, so I made a minor, if inelegant modification to the function:

    pub fn new(
        value: &str,
        file_type_hint: Option<FileType>,
        glob_ignore_case: bool,
        excluded_paths: Option<Vec<PathBuf>>,
    ) -> Result<Self> {
        let source = if value == STDIN {
            InputSource::Stdin
        } else if Request::builder().uri(value).body(()).is_ok() {
            let url = Url::parse(value)
                .map_err(|err| crate::ErrorKind::ParseUrl(err, value.to_owned()))?;
            InputSource::RemoteUrl(Box::new(url))
        } else {

Something better could be worked out in the future, but for now this does the trick. Will submit a PR for this soon.

In any case, with the above change, our test output on Windows changes to this:

    Starting 242 tests across 6 binaries (2 skipped; run ID: efc6a829-22fc-4822-8bc4-f04effc0b282, nextest profile: default)
        PASS [   0.558s] lychee::example_domains cli::test_do_not_exclude_false_positive_example_domains
        PASS [   0.569s] lychee::data_uris cli::test_dont_dump_data_uris_by_default
        PASS [   0.559s] lychee::example_domains cli::test_exclude_example_domains
        PASS [   0.562s] lychee::local_files cli::test_local_file
        PASS [   0.573s] lychee::local_files cli::test_local_dir
        PASS [   0.022s] lychee::bin/lychee commands::check::tests::test_show_cached_responses_in_progress_debug_output
        PASS [   0.595s] lychee::data_uris cli::test_dump_data_uris_in_verbose_mode
        PASS [   0.028s] lychee::bin/lychee commands::check::tests::test_skip_cached_responses_in_progress_output
        PASS [   0.027s] lychee::bin/lychee formatters::duration::tests::test_formatting
        PASS [   0.025s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_error_status
        PASS [   0.048s] lychee::bin/lychee commands::check::tests::test_invalid_url
        PASS [   0.029s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_long_uri
        PASS [   0.023s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_error_status
        PASS [   0.018s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_excluded_status
        PASS [   0.028s] lychee::bin/lychee formatters::response::color::tests::test_format_response_with_ok_status
        PASS [   0.029s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_ok_status
        PASS [   0.025s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_unknown_status_code
        PASS [   0.029s] lychee::bin/lychee formatters::response::emoji::emoji_tests::test_format_response_with_redirect_status
        PASS [   0.025s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_error_status
        PASS [   0.029s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_excluded_status
        PASS [   0.029s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_ok_status
        PASS [   0.024s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_redirect_status
        PASS [   0.019s] lychee::bin/lychee formatters::response::plain::plain_tests::test_format_response_with_unknown_status_code
        PASS [   0.029s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_cached_err
        PASS [   0.029s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_cached_ok
        PASS [   0.020s] lychee::bin/lychee formatters::stats::markdown::tests::test_render_stats
        PASS [   0.025s] lychee::bin/lychee formatters::stats::markdown::tests::test_markdown_response_ok
        PASS [   0.029s] lychee::bin/lychee formatters::stats::markdown::tests::test_render_summary
        PASS [   0.025s] lychee::bin/lychee parse::tests::test_parse_custom_headers
        PASS [   0.030s] lychee::bin/lychee options::tests::test_accept_status_codes
        PASS [   0.024s] lychee::bin/lychee stats::tests::test_detailed_stats
        PASS [   0.028s] lychee::bin/lychee parse::tests::test_parse_remap
        PASS [   0.021s] lychee::bin/lychee stats::tests::test_stats_is_empty
        PASS [   0.026s] lychee::bin/lychee stats::tests::test_stats
        PASS [   0.020s] lychee::bin/lychee verbosity::test::verify_app
        PASS [   0.025s] lychee::bin/lychee verbosity::test::test_default_log_level
        PASS [   0.027s] lychee-lib basic_auth::tests::test_basic_auth_extractor_matches
        PASS [   0.023s] lychee-lib basic_auth::tests::test_basic_auth_extractor_matches_multiple
        PASS [   0.028s] lychee-lib basic_auth::tests::test_basic_auth_extractor_no_match
        PASS [   0.032s] lychee-lib basic_auth::tests::test_basic_auth_extractor_new
        PASS [   0.034s] lychee-lib basic_auth::tests::test_basic_auth_first_match_wins
        PASS [   0.030s] lychee-lib basic_auth::tests::test_basic_auth_regex_match
        PASS [   0.031s] lychee-lib chain::test::early_exit_chain
        PASS [   0.031s] lychee-lib chain::test::simple_chain
        PASS [   0.030s] lychee-lib client::tests::test_avoid_reqwest_panic
        PASS [   0.026s] lychee-lib client::tests::test_exclude_mail_by_default
        PASS [   0.039s] lychee-lib client::tests::test_chain
        PASS [   0.032s] lychee-lib client::tests::test_file
        PASS [   1.021s] lychee::bin/lychee archive::wayback::tests::wayback_suggestion
        PASS [   0.032s] lychee-lib client::tests::test_include_mail
        PASS [   0.020s] lychee-lib client::tests::test_include_tel
        PASS [   1.194s] lychee::bin/lychee archive::wayback::tests::wayback_suggestion_unknown_url
        PASS [   0.025s] lychee-lib client::tests::test_limit_max_redirects
        PASS [   0.434s] lychee-lib client::tests::test_github_nonexistent_repo
        PASS [   0.470s] lychee-lib client::tests::test_github_nonexistent_file
        PASS [   0.031s] lychee-lib client::tests::test_max_redirects
        PASS [   0.032s] lychee-lib client::tests::test_non_github
        PASS [   0.516s] lychee-lib client::tests::test_exponential_backoff
        PASS [   0.034s] lychee-lib client::tests::test_nonexistent
        PASS [   0.023s] lychee-lib client::tests::test_unsupported_scheme
        PASS [   0.661s] lychee-lib client::tests::test_github
        PASS [   0.019s] lychee-lib collector::tests::test_collect_html_links
        PASS [   0.016s] lychee-lib collector::tests::test_collect_html_srcset
        PASS [   0.029s] lychee-lib collector::tests::test_collect_links
        PASS [   0.019s] lychee-lib collector::tests::test_collect_markdown_links
        PASS [   0.018s] lychee-lib collector::tests::test_email_with_query_params
        PASS [   0.237s] lychee-lib client::tests::test_youtube
        PASS [   0.021s] lychee-lib collector::tests::test_extract_html5_not_valid_xml_relative_links
        PASS [   0.019s] lychee-lib collector::tests::test_file_without_extension_is_plaintext
        PASS [   0.823s] lychee-lib client::tests::test_custom_headers
        PASS [   0.020s] lychee-lib collector::tests::test_markdown_internal_url
        PASS [   0.022s] lychee-lib collector::tests::test_relative_url_with_base_extracted_from_input
        PASS [   0.017s] lychee-lib extract::html::html5ever::tests::test_email_false_positive
        PASS [   0.020s] lychee-lib extract::html::html5ever::tests::test_exclude_email_without_mailto
        PASS [   0.017s] lychee-lib extract::html::html5ever::tests::test_exclude_script_tags
        PASS [   0.017s] lychee-lib extract::html::html5ever::tests::test_include_nofollow
        PASS [   0.016s] lychee-lib extract::html::html5ever::tests::test_include_verbatim
        PASS [   0.016s] lychee-lib extract::html::html5ever::tests::test_include_verbatim_recursive
        PASS [   0.019s] lychee-lib extract::html::html5ever::tests::test_skip_verbatim
        PASS [   0.017s] lychee-lib extract::html::html5ever::tests::test_valid_email
        PASS [   0.015s] lychee-lib extract::html::html5ever::tests::test_valid_tel
        PASS [   0.017s] lychee-lib extract::html::html5gum::tests::test_email_false_positive
        PASS [   0.017s] lychee-lib extract::html::html5gum::tests::test_exclude_email_without_mailto
        PASS [   0.015s] lychee-lib extract::html::html5gum::tests::test_exclude_script_tags
        PASS [   0.015s] lychee-lib extract::html::html5gum::tests::test_extract_fragments
        PASS [   0.016s] lychee-lib extract::html::html5gum::tests::test_extract_srcset
        PASS [   0.016s] lychee-lib extract::html::html5gum::tests::test_include_nofollow
        PASS [   0.014s] lychee-lib extract::html::html5gum::tests::test_include_verbatim
        PASS [   0.014s] lychee-lib extract::html::html5gum::tests::test_include_verbatim_nested
        PASS [   0.014s] lychee-lib extract::html::html5gum::tests::test_skip_verbatim
        PASS [   0.018s] lychee-lib extract::html::html5gum::tests::test_valid_email
        PASS [   0.016s] lychee-lib extract::html::html5gum::tests::test_valid_tel
        PASS [   0.017s] lychee-lib extract::html::srcset::tests::test_collect_sequence_characters_with_all_match
        PASS [   0.015s] lychee-lib extract::html::srcset::tests::test_collect_sequence_characters_with_alphabetic_predicate
        PASS [   0.016s] lychee-lib extract::html::srcset::tests::test_collect_sequence_characters_with_digit_predicate
        PASS [   0.016s] lychee-lib extract::html::srcset::tests::test_collect_sequence_characters_with_empty_string
        PASS [   0.017s] lychee-lib extract::html::srcset::tests::test_collect_sequence_characters_with_no_match
        PASS [   0.017s] lychee-lib extract::html::srcset::tests::test_parse_no_value
        PASS [   0.016s] lychee-lib extract::html::srcset::tests::test_parse_srcset_two_values
        PASS [   0.016s] lychee-lib extract::html::srcset::tests::test_parse_srcset_url
        PASS [   0.016s] lychee-lib extract::html::srcset::tests::test_parse_srcset_with_commas
        PASS [   0.018s] lychee-lib extract::html::srcset::tests::test_parse_srcset_with_unencoded_comma
        PASS [   0.018s] lychee-lib extract::html::srcset::tests::test_parse_url_one_value
        PASS [   0.015s] lychee-lib extract::html::tests::test_is_email_link
        PASS [   0.015s] lychee-lib extract::html::tests::test_verbatim_matching
        PASS [   0.016s] lychee-lib extract::markdown::tests::test_extract_fragments
        PASS [   0.014s] lychee-lib extract::markdown::tests::test_include_verbatim
        PASS [   0.014s] lychee-lib extract::markdown::tests::test_kebab_case
        PASS [   0.016s] lychee-lib extract::markdown::tests::test_skip_verbatim
        PASS [   0.016s] lychee-lib extract::plaintext::tests::test_extract_link_at_end_of_line
        PASS [   0.015s] lychee-lib extract::plaintext::tests::test_extract_local_links
        PASS [   0.015s] lychee-lib extract::tests::relative_urls
        PASS [   0.017s] lychee-lib extract::tests::test_extract_html5_custom_elements
        PASS [   0.017s] lychee-lib extract::tests::test_extract_html5_lowercase_doctype
        PASS [   0.015s] lychee-lib extract::tests::test_extract_html5_malformed
        PASS [   0.016s] lychee-lib extract::tests::test_extract_html5_minified
        PASS [   0.018s] lychee-lib extract::tests::test_extract_html5_not_valid_xml
        PASS [   0.018s] lychee-lib extract::tests::test_extract_link_at_end_of_line
        PASS [   0.016s] lychee-lib extract::tests::test_extract_relative_url
        PASS [   0.018s] lychee-lib extract::tests::test_extract_urls_with_at_sign_properly
        PASS [   0.018s] lychee-lib extract::tests::test_file_type
        PASS [   0.016s] lychee-lib extract::tests::test_md_escape
        PASS [   0.015s] lychee-lib extract::tests::test_non_markdown_links
        PASS [   0.015s] lychee-lib extract::tests::test_skip_markdown_anchors
        PASS [   0.017s] lychee-lib extract::tests::test_skip_markdown_email
        PASS [   0.015s] lychee-lib extract::tests::test_skip_markdown_internal_urls
        PASS [   0.015s] lychee-lib extract::tests::verbatim_elem
        PASS [   0.016s] lychee-lib filter::tests::test_const_sanity
        PASS [   0.021s] lychee-lib filter::tests::test_exclude_include_regex
        PASS [   0.020s] lychee-lib filter::tests::test_exclude_ip_v4_mapped_ip_v6_not_supported
        PASS [   0.014s] lychee-lib filter::tests::test_exclude_link_local
        PASS [   0.506s] lychee-lib collector::tests::test_url_without_extension_is_html
        PASS [   0.018s] lychee-lib filter::tests::test_exclude_loopback
        PASS [   0.016s] lychee-lib filter::tests::test_exclude_loopback_ips
        PASS [   0.016s] lychee-lib filter::tests::test_exclude_private_ips
        PASS [   0.022s] lychee-lib filter::tests::test_exclude_mail_by_default
        PASS [   0.024s] lychee-lib filter::tests::test_exclude_regex
        PASS [   0.021s] lychee-lib filter::tests::test_excludes_no_private_ips_by_default
        PASS [   0.021s] lychee-lib filter::tests::test_false_positives
        PASS [   0.020s] lychee-lib filter::tests::test_include_mail
        PASS [   0.024s] lychee-lib filter::tests::test_include_regex
        PASS [   0.025s] lychee-lib filter::tests::test_includes_and_excludes_empty
        PASS [   0.023s] lychee-lib filter::tests::test_overwrite_false_positives
        PASS [   0.020s] lychee-lib quirks::tests::test_cratesio_request
        PASS [   0.023s] lychee-lib quirks::tests::test_no_quirk_applied
        PASS [   0.911s] lychee-lib client::tests::test_require_https
        PASS [   0.023s] lychee-lib quirks::tests::test_non_video_youtube_url_untouched
        PASS [   0.026s] lychee-lib quirks::tests::test_youtube_video_request
        PASS [   0.029s] lychee-lib quirks::tests::test_youtube_video_shortlink_request
        PASS [   0.029s] lychee-lib remap::tests::test_remap
        PASS [   0.026s] lychee-lib remap::tests::test_remap_capture_group
        PASS [   0.025s] lychee-lib remap::tests::test_remap_named_capture
        PASS [   0.024s] lychee-lib remap::tests::test_remap_named_capture_shorthand
        PASS [   0.024s] lychee-lib remap::tests::test_remap_path
        PASS [   0.023s] lychee-lib remap::tests::test_remap_skip
        PASS [   0.022s] lychee-lib remap::tests::test_remap_url_to_file
        PASS [   0.023s] lychee-lib types::accept::range::test::test_from_str::case_1
        PASS [   0.022s] lychee-lib types::accept::range::test::test_from_str::case_2
        PASS [   0.023s] lychee-lib types::accept::range::test::test_from_str::case_3
        PASS [   0.022s] lychee-lib types::accept::range::test::test_from_str::case_4
        PASS [   0.018s] lychee-lib types::accept::range::test::test_from_str::case_5
        PASS [   0.019s] lychee-lib types::accept::range::test::test_from_str_invalid::case_1
        PASS [   0.020s] lychee-lib types::accept::range::test::test_from_str_invalid::case_2
        PASS [   0.024s] lychee-lib types::accept::range::test::test_from_str_invalid::case_3
        PASS [   0.024s] lychee-lib types::accept::range::test::test_from_str_invalid::case_4
        PASS [   0.026s] lychee-lib types::accept::range::test::test_from_str_invalid::case_6
        PASS [   1.559s] lychee-lib client::tests::test_basic_auth
        PASS [   0.031s] lychee-lib types::accept::range::test::test_from_str_invalid::case_5
        PASS [   0.026s] lychee-lib types::accept::range::test::test_from_str_invalid::case_8
        PASS [   0.031s] lychee-lib types::accept::range::test::test_from_str_invalid::case_7
        PASS [   0.022s] lychee-lib types::accept::range::test::test_from_str_invalid::case_9
        PASS [   0.022s] lychee-lib types::accept::range::test::test_merge::case_1
        PASS [   0.023s] lychee-lib types::accept::range::test::test_merge::case_2
        PASS [   0.025s] lychee-lib types::accept::range::test::test_merge::case_3
        PASS [   0.026s] lychee-lib types::accept::range::test::test_merge::case_4
        PASS [   0.026s] lychee-lib types::accept::selector::test::test_deserialize::case_1
        PASS [   0.026s] lychee-lib types::accept::selector::test::test_deserialize::case_2
        PASS [   0.028s] lychee-lib types::accept::selector::test::test_deserialize::case_3
        PASS [   0.026s] lychee-lib types::accept::selector::test::test_deserialize::case_4
        PASS [   0.025s] lychee-lib types::accept::selector::test::test_deserialize::case_5
        PASS [   0.021s] lychee-lib types::accept::selector::test::test_deserialize::case_7
        PASS [   0.030s] lychee-lib types::accept::selector::test::test_deserialize::case_6
        PASS [   0.025s] lychee-lib types::accept::selector::test::test_display::case_1
        PASS [   0.026s] lychee-lib types::accept::selector::test::test_display::case_2
        PASS [   0.021s] lychee-lib types::accept::selector::test::test_from_str::case_2
        PASS [   0.030s] lychee-lib types::accept::selector::test::test_from_str::case_1
        PASS [   0.025s] lychee-lib types::accept::selector::test::test_from_str::case_3
        PASS [   0.024s] lychee-lib types::accept::selector::test::test_from_str::case_4
        PASS [   0.023s] lychee-lib types::base::test_base::test_get_base_from_url
        PASS [   0.023s] lychee-lib types::base::test_base::test_invalid_url
        FAIL [   0.023s] lychee-lib types::base::test_base::test_valid_local

--- STDOUT:              lychee-lib types::base::test_base::test_valid_local ---

running 1 test
test types::base::test_base::test_valid_local ... FAILED

failures:

failures:
    types::base::test_base::test_valid_local

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 205 filtered out; finished in 0.00s


--- STDERR:              lychee-lib types::base::test_base::test_valid_local ---
Error: InvalidBase("C:\\Users\\bnhei\\AppData\\Local\\Temp\\.tmp96nQiF", "The given URL cannot be a base")

   Canceling due to test failure: 7 tests still running
        PASS [   0.018s] lychee-lib types::base::test_base::test_valid_remote
        PASS [   0.017s] lychee-lib types::basic_auth::selector::test::test_missing_credentials_basic_auth_selector
        PASS [   0.022s] lychee-lib types::basic_auth::selector::test::test_empty_basic_auth_selector
        PASS [   0.023s] lychee-lib types::basic_auth::selector::test::test_missing_uri_basic_auth_selector
        PASS [   0.024s] lychee-lib types::basic_auth::selector::test::test_too_many_parts_basic_auth_selector
        PASS [   0.025s] lychee-lib types::basic_auth::selector::test::test_valid_basic_auth_selector
        PASS [   0.026s] lychee-lib types::cache::tests::test_deserialize_cache_status_blank
        PASS [   1.378s] lychee-lib client::tests::test_invalid_ssl
        PASS [   0.025s] lychee-lib types::cache::tests::test_deserialize_cache_status_error_code
        PASS [   0.021s] lychee-lib types::cache::tests::test_deserialize_cache_status_excluded
        PASS [   0.021s] lychee-lib types::cache::tests::test_deserialize_cache_status_success_code
        PASS [   0.021s] lychee-lib types::cache::tests::test_deserialize_cache_status_unsupported
        PASS [   0.021s] lychee-lib types::file::tests::test_extension
        PASS [   2.070s] lychee-lib client::tests::test_nonexistent_with_path
        PASS [   7.119s] lychee-lib client::tests::test_timeout
------------
     Summary [   8.415s] 206/242 tests run: 205 passed, 1 failed, 2 skipped
        FAIL [   0.023s] lychee-lib types::base::test_base::test_valid_local
error: test run failed

As you can see, there still remain some issues, but this still gets us a long way.

mre commented

Closing this as it should be fixed in master with #1460 by @toadslop.