Skip to content

Commit

Permalink
We must also check the fragment before it is percent decoded as requi…
Browse files Browse the repository at this point in the history
…red by the html standard. Fixes #1467
  • Loading branch information
autoantwort committed Oct 18, 2024
1 parent f5a4f7c commit d5293d1
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
2 changes: 2 additions & 0 deletions fixtures/fragments/file.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<body>
<section id="in-the-beginning" style="height: 100vh;">
<p id="Upper-ÄÖö">
<div id="tangent%3A-kustomize"></div>
To start
<a href="file1.md#fragment-1">
let's run away.
Expand All @@ -17,6 +18,7 @@
<p id="a-word">Word</p>
<a href="#in-the-beginning">back we go</a><br>
<a href="#in-THE-begiNNing">back we go upper does not work</a><br>
<a href="#tangent%3A-kustomize">id with percent encoding</a><br>
<a href="#Upper-ÄÖö">back to Upper-ÄÖö</a><br>
<a href="#Upper-%C3%84%C3%96%C3%B6">back to öüä encoded</a><br>
<a href="#in-the-end">doesn't exist</a><br>
Expand Down
12 changes: 8 additions & 4 deletions lychee-lib/src/utils/fragment_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl FragmentChecker {
let Some(fragment) = url.fragment() else {
return Ok(true);
};
let mut fragment = percent_decode_str(fragment).decode_utf8()?;
let mut fragment_decoded = percent_decode_str(fragment).decode_utf8()?;
let url_without_frag = Self::remove_fragment(url.clone());

let file_type = FileType::from(path);
Expand All @@ -57,15 +57,19 @@ impl FragmentChecker {
FileType::Plaintext => return Ok(true),
};
if file_type == FileType::Markdown {
fragment = fragment.to_lowercase().into();
fragment_decoded = fragment_decoded.to_lowercase().into();
}
match self.cache.lock().await.entry(url_without_frag) {
Entry::Vacant(entry) => {
let content = fs::read_to_string(path).await?;
let file_frags = extractor(&content);
Ok(entry.insert(file_frags).contains(&fragment as &str))
let contains_fragment =
file_frags.contains(fragment) || file_frags.contains(&fragment_decoded as &str);
entry.insert(file_frags);
Ok(contains_fragment)
}
Entry::Occupied(entry) => Ok(entry.get().contains(&fragment as &str)),
Entry::Occupied(entry) => Ok(entry.get().contains(&fragment as &str)
|| entry.get().contains(&fragment_decoded as &str)),
}
}

Expand Down

0 comments on commit d5293d1

Please sign in to comment.