Rollup merge of #94260 - GuillaumeGomez:infinite-redirection, r=notriddle
Fix rustdoc infinite redirection generation Someone came to me about a funny bug they had when clicking on any link on [this page](https://world.pages.gitlab.gnome.org/Rust/libadwaita-rs/stable/latest/docs/libadwaita/builders/index.html): it ended one page redirecting to itself indefinitely. I was able to make a minimum reproducible case to trigger this bug which I now use as a test. r? ``@notriddle``
This commit is contained in:
commit
a9eb5f077c
2 changed files with 64 additions and 27 deletions
|
@ -201,19 +201,19 @@ impl<'tcx> Context<'tcx> {
|
|||
} else {
|
||||
tyname.as_str()
|
||||
};
|
||||
let page = layout::Page {
|
||||
css_class: tyname_s,
|
||||
root_path: &self.root_path(),
|
||||
static_root_path: self.shared.static_root_path.as_deref(),
|
||||
title: &title,
|
||||
description: &desc,
|
||||
keywords: &keywords,
|
||||
resource_suffix: &self.shared.resource_suffix,
|
||||
extra_scripts: &[],
|
||||
static_extra_scripts: &[],
|
||||
};
|
||||
|
||||
if !self.render_redirect_pages {
|
||||
let page = layout::Page {
|
||||
css_class: tyname_s,
|
||||
root_path: &self.root_path(),
|
||||
static_root_path: self.shared.static_root_path.as_deref(),
|
||||
title: &title,
|
||||
description: &desc,
|
||||
keywords: &keywords,
|
||||
resource_suffix: &self.shared.resource_suffix,
|
||||
extra_scripts: &[],
|
||||
static_extra_scripts: &[],
|
||||
};
|
||||
layout::render(
|
||||
&self.shared.layout,
|
||||
&page,
|
||||
|
@ -223,23 +223,31 @@ impl<'tcx> Context<'tcx> {
|
|||
)
|
||||
} else {
|
||||
if let Some(&(ref names, ty)) = self.cache().paths.get(&it.def_id.expect_def_id()) {
|
||||
let mut path = String::new();
|
||||
for name in &names[..names.len() - 1] {
|
||||
path.push_str(&name.as_str());
|
||||
path.push('/');
|
||||
}
|
||||
path.push_str(&item_path(ty, &names.last().unwrap().as_str()));
|
||||
match self.shared.redirections {
|
||||
Some(ref redirections) => {
|
||||
let mut current_path = String::new();
|
||||
for name in &self.current {
|
||||
current_path.push_str(&name.as_str());
|
||||
current_path.push('/');
|
||||
}
|
||||
current_path.push_str(&item_path(ty, &names.last().unwrap().as_str()));
|
||||
redirections.borrow_mut().insert(current_path, path);
|
||||
if self.current.len() + 1 != names.len()
|
||||
|| self.current.iter().zip(names.iter()).any(|(a, b)| a != b)
|
||||
{
|
||||
// We checked that the redirection isn't pointing to the current file,
|
||||
// preventing an infinite redirection loop in the generated
|
||||
// documentation.
|
||||
|
||||
let mut path = String::new();
|
||||
for name in &names[..names.len() - 1] {
|
||||
path.push_str(&name.as_str());
|
||||
path.push('/');
|
||||
}
|
||||
path.push_str(&item_path(ty, &names.last().unwrap().as_str()));
|
||||
match self.shared.redirections {
|
||||
Some(ref redirections) => {
|
||||
let mut current_path = String::new();
|
||||
for name in &self.current {
|
||||
current_path.push_str(&name.as_str());
|
||||
current_path.push('/');
|
||||
}
|
||||
current_path.push_str(&item_path(ty, &names.last().unwrap().as_str()));
|
||||
redirections.borrow_mut().insert(current_path, path);
|
||||
}
|
||||
None => return layout::redirect(&format!("{}{}", self.root_path(), path)),
|
||||
}
|
||||
None => return layout::redirect(&format!("{}{}", self.root_path(), path)),
|
||||
}
|
||||
}
|
||||
String::new()
|
||||
|
|
29
src/test/rustdoc/infinite-redirection.rs
Normal file
29
src/test/rustdoc/infinite-redirection.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
#![crate_name = "foo"]
|
||||
|
||||
// This test ensures that there is no "infinite redirection" file generated (a
|
||||
// file which redirects to itself).
|
||||
|
||||
// We check it's not a redirection file.
|
||||
// @has 'foo/builders/struct.ActionRowBuilder.html'
|
||||
// @has - '//*[@id="synthetic-implementations"]' 'Auto Trait Implementations'
|
||||
|
||||
// And that the link in the module is targetting it.
|
||||
// @has 'foo/builders/index.html'
|
||||
// @has - '//a[@href="struct.ActionRowBuilder.html"]' 'ActionRowBuilder'
|
||||
|
||||
mod auto {
|
||||
mod action_row {
|
||||
pub struct ActionRowBuilder;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod builders {
|
||||
pub use super::action_row::ActionRowBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
pub use auto::*;
|
||||
|
||||
pub mod builders {
|
||||
pub use crate::auto::builders::*;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue