From 979c265a5d54a3a267563153859f2921db717b1d Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 29 Mar 2023 16:00:48 +0100 Subject: [PATCH] Check for escape sequences in Fluent resources --- compiler/rustc_codegen_llvm/messages.ftl | 3 ++- compiler/rustc_const_eval/messages.ftl | 16 +++++++++--- compiler/rustc_incremental/messages.ftl | 2 +- compiler/rustc_lint/messages.ftl | 2 +- .../rustc_macros/src/diagnostics/fluent.rs | 12 +++++++++ .../fluent-messages/invalid-escape.ftl | 1 + tests/ui-fulldeps/fluent-messages/test.rs | 9 +++++++ tests/ui-fulldeps/fluent-messages/test.stderr | 26 ++++++++++++++++++- .../existing_doc_keyword.stderr | 2 +- 9 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 tests/ui-fulldeps/fluent-messages/invalid-escape.ftl diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index e5df417370bb9..b6d7484bccefd 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -27,7 +27,8 @@ codegen_llvm_error_calling_dlltool = Error calling dlltool: {$error} codegen_llvm_dlltool_fail_import_library = - Dlltool could not create import library: {$stdout}\n{$stderr} + Dlltool could not create import library: {$stdout} + {$stderr} codegen_llvm_target_feature_disable_or_enable = the target features {$features} must all be either enabled or disabled together diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 33bb116d6fa23..f6751df443f7a 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -39,17 +39,25 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unallowed_mutable_refs = mutable references are not allowed in the final value of {$kind}s .teach_note = - References in statics and constants may only refer to immutable values.\n\n + References in statics and constants may only refer to immutable values. + + Statics are shared everywhere, and if they refer to mutable data one might violate memory - safety since holding multiple mutable references to shared data is not allowed.\n\n + safety since holding multiple mutable references to shared data is not allowed. + + If you really want global mutable state, try using static mut or a global UnsafeCell. const_eval_unallowed_mutable_refs_raw = raw mutable references are not allowed in the final value of {$kind}s .teach_note = - References in statics and constants may only refer to immutable values.\n\n + References in statics and constants may only refer to immutable values. + + Statics are shared everywhere, and if they refer to mutable data one might violate memory - safety since holding multiple mutable references to shared data is not allowed.\n\n + safety since holding multiple mutable references to shared data is not allowed. + + If you really want global mutable state, try using static mut or a global UnsafeCell. const_eval_non_const_fmt_macro_call = diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl index 4852ee0d9595c..b760620e3d48b 100644 --- a/compiler/rustc_incremental/messages.ftl +++ b/compiler/rustc_incremental/messages.ftl @@ -24,7 +24,7 @@ incremental_field_associated_value_expected = associated value expected for `{$n incremental_no_field = no field `{$name}` incremental_assertion_auto = - `except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\" + `except` specified DepNodes that can not be affected for "{$name}": "{$e}" incremental_undefined_clean_dirty_assertions_item = clean/dirty auto-assertions not yet defined for Node::Item.node={$kind} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 68e62c9789aed..02af8ca54e402 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -91,7 +91,7 @@ lint_ty_qualified = usage of qualified `ty::{$ty}` lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead -lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]` +lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]` .help = only existing keywords are allowed in core/std lint_diag_out_of_impl = diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 38c0f4895db06..3b2f5cfdc7316 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -111,6 +111,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok .emit(); return failed(&crate_name); } + let mut bad = false; + for esc in ["\\n", "\\\"", "\\'"] { + for _ in resource_contents.matches(esc) { + bad = true; + Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource")) + .note("Fluent does not interpret these escape sequences ()") + .emit(); + } + } + if bad { + return failed(&crate_name); + } let resource = match FluentResource::try_new(resource_contents) { Ok(resource) => resource, diff --git a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl new file mode 100644 index 0000000000000..e28852ea0050e --- /dev/null +++ b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl @@ -0,0 +1 @@ +no_crate_bad_escape = don't use \n, \', or \" diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 66575eb8e30cf..1ee7227a8e992 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -92,3 +92,12 @@ mod missing_message_ref { fluent_messages! { "./missing-message-ref.ftl" } //~^ ERROR referenced message `message` does not exist } + +mod bad_escape { + use super::fluent_messages; + + fluent_messages! { "./invalid-escape.ftl" } + //~^ ERROR invalid escape `\n` + //~| ERROR invalid escape `\"` + //~| ERROR invalid escape `\'` +} diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index c7961ed22f2b4..8a6a4a91cc201 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -83,5 +83,29 @@ LL | fluent_messages! { "./missing-message-ref.ftl" } | = help: you may have meant to use a variable reference (`{$message}`) -error: aborting due to 10 previous errors +error: invalid escape `\n` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: invalid escape `\"` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: invalid escape `\'` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: aborting due to 13 previous errors diff --git a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr index 4e296fff6d0ba..5110b9be08a53 100644 --- a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr +++ b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr @@ -1,4 +1,4 @@ -error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]` +error: found non-existing keyword `tadam` used in `#[doc(keyword = "...")]` --> $DIR/existing_doc_keyword.rs:10:1 | LL | #[doc(keyword = "tadam")]