From 8d81d5a909551631b51177f976f68ac02dcafd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 18 Aug 2023 13:23:53 +0200 Subject: [PATCH] Validate crate name in CLI option --extern --- compiler/rustc_session/src/config.rs | 13 +++++++++++++ compiler/rustc_session/src/session.rs | 9 +++++++++ compiler/rustc_session/src/utils.rs | 9 +++++++++ tests/run-make/incr-foreign-head-span/Makefile | 2 +- tests/ui/extern-flag/invalid-crate-name-dashed.rs | 10 ++++++++++ .../ui/extern-flag/invalid-crate-name-dashed.stderr | 4 ++++ .../ui/extern-flag/invalid-crate-name-non-ascii.rs | 4 ++++ .../extern-flag/invalid-crate-name-non-ascii.stderr | 2 ++ tests/ui/extern-flag/invalid-crate-name.rs | 4 ++++ tests/ui/extern-flag/invalid-crate-name.stderr | 2 ++ .../crate_name_nonascii_forbidden-2.rs | 6 ------ .../crate_name_nonascii_forbidden-2.stderr | 8 -------- ...bidden-1.rs => crate_name_nonascii_forbidden.rs} | 0 ....stderr => crate_name_nonascii_forbidden.stderr} | 2 +- tests/ui/rust-2018/trait-import-suggestions.rs | 2 +- 15 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 tests/ui/extern-flag/invalid-crate-name-dashed.rs create mode 100644 tests/ui/extern-flag/invalid-crate-name-dashed.stderr create mode 100644 tests/ui/extern-flag/invalid-crate-name-non-ascii.rs create mode 100644 tests/ui/extern-flag/invalid-crate-name-non-ascii.stderr create mode 100644 tests/ui/extern-flag/invalid-crate-name.rs create mode 100644 tests/ui/extern-flag/invalid-crate-name.stderr delete mode 100644 tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.rs delete mode 100644 tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.stderr rename tests/ui/rfcs/rfc-2457-non-ascii-idents/{crate_name_nonascii_forbidden-1.rs => crate_name_nonascii_forbidden.rs} (100%) rename tests/ui/rfcs/rfc-2457-non-ascii-idents/{crate_name_nonascii_forbidden-1.stderr => crate_name_nonascii_forbidden.stderr} (75%) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f00472f181d8e..3ccd18f8ac650 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2451,6 +2451,19 @@ pub fn parse_externs( Some((opts, name)) => (Some(opts), name.to_string()), }; + if !crate::utils::is_ascii_ident(&name) { + let mut error = handler.early_struct_error(format!( + "crate name `{name}` passed to `--extern` is not a valid ASCII identifier" + )); + let adjusted_name = name.replace("-", "_"); + if crate::utils::is_ascii_ident(&adjusted_name) { + error.help(format!( + "consider replacing the dashes with underscores: `{adjusted_name}`" + )); + } + error.emit(); + } + let path = path.map(|p| CanonicalizedPath::new(p)); let entry = externs.entry(name.to_owned()); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 086ce4e69646a..889d7e730108f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1710,6 +1710,15 @@ impl EarlyErrorHandler { self.handler.struct_fatal(msg).emit() } + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub(crate) fn early_struct_error( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, !> { + self.handler.struct_fatal(msg) + } + #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] pub fn early_warn(&self, msg: impl Into) { diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index f76c69af526e9..aea7c6c284286 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -158,3 +158,12 @@ pub fn extra_compiler_flags() -> Option<(Vec, bool)> { if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } } + +pub(crate) fn is_ascii_ident(string: &str) -> bool { + let mut chars = string.chars(); + if let Some(start) = chars.next() && (start.is_ascii_alphabetic() || start == '_') { + chars.all(|char| char.is_ascii_alphanumeric() || char == '_') + } else { + false + } +} diff --git a/tests/run-make/incr-foreign-head-span/Makefile b/tests/run-make/incr-foreign-head-span/Makefile index 9d6102cdd72dc..9be4b0f601c30 100644 --- a/tests/run-make/incr-foreign-head-span/Makefile +++ b/tests/run-make/incr-foreign-head-span/Makefile @@ -15,7 +15,7 @@ INCR=$(TMPDIR)/incr all: cp first_crate.rs second_crate.rs $(TMPDIR) $(RUSTC) $(TMPDIR)/first_crate.rs -C incremental=$(INCR) --target $(TARGET) --crate-type lib - $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first-crate=$(TMPDIR) --crate-type lib + $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib rm $(TMPDIR)/first_crate.rs $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib diff --git a/tests/ui/extern-flag/invalid-crate-name-dashed.rs b/tests/ui/extern-flag/invalid-crate-name-dashed.rs new file mode 100644 index 0000000000000..7f351e48b6fa1 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-dashed.rs @@ -0,0 +1,10 @@ +// compile-flags: --extern=my-awesome-library=libawesome.rlib +// error-pattern: crate name `my-awesome-library` passed to `--extern` is not a valid ASCII identifier +// error-pattern: consider replacing the dashes with underscores: `my_awesome_library` + +// In a sense, this is a regression test for issue #113035. We no longer suggest +// `pub use my-awesome-library::*;` (sic!) as we outright ban this crate name. + +pub use my_awesome_library::*; + +fn main() {} diff --git a/tests/ui/extern-flag/invalid-crate-name-dashed.stderr b/tests/ui/extern-flag/invalid-crate-name-dashed.stderr new file mode 100644 index 0000000000000..5da1c4bb20a37 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-dashed.stderr @@ -0,0 +1,4 @@ +error: crate name `my-awesome-library` passed to `--extern` is not a valid ASCII identifier + | + = help: consider replacing the dashes with underscores: `my_awesome_library` + diff --git a/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs b/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs new file mode 100644 index 0000000000000..ec4a85820d122 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-non-ascii.rs @@ -0,0 +1,4 @@ +// compile-flags: --extern čɍαţē=libnon_ascii.rlib +// error-pattern: crate name `čɍαţē` passed to `--extern` is not a valid ASCII identifier + +fn main() {} diff --git a/tests/ui/extern-flag/invalid-crate-name-non-ascii.stderr b/tests/ui/extern-flag/invalid-crate-name-non-ascii.stderr new file mode 100644 index 0000000000000..6b38dcd01e0c3 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name-non-ascii.stderr @@ -0,0 +1,2 @@ +error: crate name `čɍαţē` passed to `--extern` is not a valid ASCII identifier + diff --git a/tests/ui/extern-flag/invalid-crate-name.rs b/tests/ui/extern-flag/invalid-crate-name.rs new file mode 100644 index 0000000000000..a26b5dd4635ff --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name.rs @@ -0,0 +1,4 @@ +// compile-flags: --extern=?#1%$ +// error-pattern: crate name `?#1%$` passed to `--extern` is not a valid ASCII identifier + +fn main() {} diff --git a/tests/ui/extern-flag/invalid-crate-name.stderr b/tests/ui/extern-flag/invalid-crate-name.stderr new file mode 100644 index 0000000000000..e2f83160db904 --- /dev/null +++ b/tests/ui/extern-flag/invalid-crate-name.stderr @@ -0,0 +1,2 @@ +error: crate name `?#1%$` passed to `--extern` is not a valid ASCII identifier + diff --git a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.rs b/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.rs deleted file mode 100644 index f8e033937c607..0000000000000 --- a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags:--extern му_сгате -// edition:2018 - -use му_сгате::baz; //~ ERROR cannot load a crate with a non-ascii name `му_сгате` - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.stderr b/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.stderr deleted file mode 100644 index 05fc4fb22ad1e..0000000000000 --- a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot load a crate with a non-ascii name `му_сгате` - --> $DIR/crate_name_nonascii_forbidden-2.rs:4:5 - | -LL | use му_сгате::baz; - | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-1.rs b/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden.rs similarity index 100% rename from tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-1.rs rename to tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden.rs diff --git a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-1.stderr b/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden.stderr similarity index 75% rename from tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-1.stderr rename to tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden.stderr index a8f3abe599eb2..5aade17cba52d 100644 --- a/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden-1.stderr +++ b/tests/ui/rfcs/rfc-2457-non-ascii-idents/crate_name_nonascii_forbidden.stderr @@ -1,5 +1,5 @@ error: cannot load a crate with a non-ascii name `ьаг` - --> $DIR/crate_name_nonascii_forbidden-1.rs:1:1 + --> $DIR/crate_name_nonascii_forbidden.rs:1:1 | LL | extern crate ьаг; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rust-2018/trait-import-suggestions.rs b/tests/ui/rust-2018/trait-import-suggestions.rs index 9c67c3f4b4b2e..900b3d09334d0 100644 --- a/tests/ui/rust-2018/trait-import-suggestions.rs +++ b/tests/ui/rust-2018/trait-import-suggestions.rs @@ -1,6 +1,6 @@ // edition:2018 // aux-build:trait-import-suggestions.rs -// compile-flags:--extern trait-import-suggestions +// compile-flags:--extern trait_import_suggestions mod foo { mod foobar {