rustdoc: Fully escape link section and export name
Escape "special characters" (e.g., double quotes `"` and line breaks `\n`). Escape HTML. Lastly, add regression tests and clean up existing tests.
This commit is contained in:
@@ -2935,11 +2935,11 @@ fn render_attributes_in_code(
|
|||||||
let hir::Attribute::Parsed(kind) = attr else { continue };
|
let hir::Attribute::Parsed(kind) = attr else { continue };
|
||||||
let attr = match kind {
|
let attr = match kind {
|
||||||
AttributeKind::LinkSection { name, .. } => {
|
AttributeKind::LinkSection { name, .. } => {
|
||||||
Cow::Owned(format!("#[unsafe(link_section = \"{name}\")]"))
|
Cow::Owned(format!("#[unsafe(link_section = {})]", Escape(&format!("{name:?}"))))
|
||||||
}
|
}
|
||||||
AttributeKind::NoMangle(..) => Cow::Borrowed("#[unsafe(no_mangle)]"),
|
AttributeKind::NoMangle(..) => Cow::Borrowed("#[unsafe(no_mangle)]"),
|
||||||
AttributeKind::ExportName { name, .. } => {
|
AttributeKind::ExportName { name, .. } => {
|
||||||
Cow::Owned(format!("#[unsafe(export_name = \"{name}\")]"))
|
Cow::Owned(format!("#[unsafe(export_name = {})]", Escape(&format!("{name:?}"))))
|
||||||
}
|
}
|
||||||
AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"),
|
AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#![crate_name = "foo"]
|
|
||||||
|
|
||||||
//@ has 'foo/fn.f.html'
|
|
||||||
//@ has - //*[@'class="code-attribute"]' '#[unsafe(export_name = "f")]'
|
|
||||||
//@ has - //*[@'class="rust item-decl"]' 'pub fn f()'
|
|
||||||
#[unsafe(export_name = "\
|
|
||||||
f")]
|
|
||||||
pub fn f() {}
|
|
||||||
@@ -9,6 +9,18 @@ pub extern "C" fn f() {}
|
|||||||
#[unsafe(export_name = "bar")]
|
#[unsafe(export_name = "bar")]
|
||||||
pub extern "C" fn g() {}
|
pub extern "C" fn g() {}
|
||||||
|
|
||||||
|
//@ has foo/fn.escape_special.html '//*[@class="code-attribute"]' \
|
||||||
|
// '#[unsafe(export_name = "\n\"\n")]'
|
||||||
|
#[unsafe(export_name = "\n\"
|
||||||
|
")]
|
||||||
|
pub extern "C" fn escape_special() {}
|
||||||
|
|
||||||
|
// issue: <https://github.com/rust-lang/rust/issues/142835>
|
||||||
|
//@ has foo/fn.escape_html.html '//*[@class="code-attribute"]' \
|
||||||
|
// '#[unsafe(export_name = "<script>alert()</script>")]'
|
||||||
|
#[unsafe(export_name = "<script>alert()</script>")]
|
||||||
|
pub extern "C" fn escape_html() {}
|
||||||
|
|
||||||
//@ has foo/fn.example.html '//*[@class="code-attribute"]' '#[unsafe(link_section = ".text")]'
|
//@ has foo/fn.example.html '//*[@class="code-attribute"]' '#[unsafe(link_section = ".text")]'
|
||||||
#[unsafe(link_section = ".text")]
|
#[unsafe(link_section = ".text")]
|
||||||
pub extern "C" fn example() {}
|
pub extern "C" fn example() {}
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
|
// Ensure that we render attributes on inlined cross-crate re-exported items.
|
||||||
|
// issue: <https://github.com/rust-lang/rust/issues/144004>
|
||||||
|
|
||||||
//@ aux-crate:attributes=attributes.rs
|
//@ aux-crate:attributes=attributes.rs
|
||||||
//@ edition:2021
|
//@ edition:2021
|
||||||
#![crate_name = "user"]
|
#![crate_name = "user"]
|
||||||
|
|
||||||
//@ has 'user/struct.NonExhaustive.html'
|
//@ has 'user/fn.no_mangle.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
|
||||||
//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[non_exhaustive]'
|
pub use attributes::no_mangle;
|
||||||
|
|
||||||
|
//@ has 'user/fn.link_section.html' '//pre[@class="rust item-decl"]' \
|
||||||
|
// '#[unsafe(link_section = ".here")]'
|
||||||
|
pub use attributes::link_section;
|
||||||
|
|
||||||
|
//@ has 'user/fn.export_name.html' '//pre[@class="rust item-decl"]' \
|
||||||
|
// '#[unsafe(export_name = "exonym")]'
|
||||||
|
pub use attributes::export_name;
|
||||||
|
|
||||||
|
//@ has 'user/struct.NonExhaustive.html' '//pre[@class="rust item-decl"]' '#[non_exhaustive]'
|
||||||
pub use attributes::NonExhaustive;
|
pub use attributes::NonExhaustive;
|
||||||
|
|||||||
@@ -1,2 +1,11 @@
|
|||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub fn no_mangle() {}
|
||||||
|
|
||||||
|
#[unsafe(link_section = ".here")]
|
||||||
|
pub fn link_section() {}
|
||||||
|
|
||||||
|
#[unsafe(export_name = "exonym")]
|
||||||
|
pub fn export_name() {}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct NonExhaustive;
|
pub struct NonExhaustive;
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#[unsafe(no_mangle)]
|
|
||||||
pub fn f0() {}
|
|
||||||
|
|
||||||
#[unsafe(link_section = ".here")]
|
|
||||||
pub fn f1() {}
|
|
||||||
|
|
||||||
#[unsafe(export_name = "f2export")]
|
|
||||||
pub fn f2() {}
|
|
||||||
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum T0 { V1 }
|
|
||||||
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum T1 {}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
//@ aux-build: reexports-attrs.rs
|
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
|
||||||
|
|
||||||
extern crate reexports_attrs;
|
|
||||||
|
|
||||||
//@ has 'foo/fn.f0.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]'
|
|
||||||
pub use reexports_attrs::f0;
|
|
||||||
|
|
||||||
//@ has 'foo/fn.f1.html' '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".here")]'
|
|
||||||
pub use reexports_attrs::f1;
|
|
||||||
|
|
||||||
//@ has 'foo/fn.f2.html' '//pre[@class="rust item-decl"]' '#[unsafe(export_name = "f2export")]'
|
|
||||||
pub use reexports_attrs::f2;
|
|
||||||
|
|
||||||
//@ has 'foo/enum.T0.html' '//pre[@class="rust item-decl"]' '#[repr(u8)]'
|
|
||||||
pub use reexports_attrs::T0;
|
|
||||||
|
|
||||||
//@ has 'foo/enum.T1.html' '//pre[@class="rust item-decl"]' '#[non_exhaustive]'
|
|
||||||
pub use reexports_attrs::T1;
|
|
||||||
Reference in New Issue
Block a user