From 570c5df73994fa2f3ed9be0178ff7d01a111a071 Mon Sep 17 00:00:00 2001
From: Ed Page <eopage@gmail.com>
Date: Mon, 12 Jun 2023 14:38:56 -0500
Subject: [PATCH] fix(embedded): Extend sanitization rules to cover cargo-add
 validation

---
 src/cargo/ops/cargo_new.rs      |  1 +
 src/cargo/util/toml/embedded.rs | 33 ++++++++++++++++++++++++++++-----
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs
index ca1339afa17f..b113671b078e 100644
--- a/src/cargo/ops/cargo_new.rs
+++ b/src/cargo/ops/cargo_new.rs
@@ -163,6 +163,7 @@ fn get_name<'a>(path: &'a Path, opts: &'a NewOptions) -> CargoResult<&'a str> {
     })
 }
 
+/// See also `util::toml::embedded::sanitize_name`
 fn check_name(
     name: &str,
     show_name_help: bool,
diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs
index 235489c803d8..5f86c11f2e2c 100644
--- a/src/cargo/util/toml/embedded.rs
+++ b/src/cargo/util/toml/embedded.rs
@@ -143,7 +143,7 @@ impl RawScript {
             // more common convention for CLIs
             '-'
         };
-        let name = restricted_names::sanitize_package_name(&file_name, separator);
+        let name = sanitize_name(&file_name, separator);
         let hash = self.hash();
         let bin_name = format!("{name}{separator}{hash}");
         package
@@ -200,6 +200,29 @@ impl RawScript {
     }
 }
 
+/// Ensure the package name matches the validation from `opt::cargo_new::check_name`
+fn sanitize_name(name: &str, placeholder: char) -> String {
+    let mut name = restricted_names::sanitize_package_name(name, placeholder);
+
+    loop {
+        if restricted_names::is_keyword(&name) {
+            name.push(placeholder);
+        } else if restricted_names::is_conflicting_artifact_name(&name) {
+            // Being an embedded manifest, we always assume it is a `[[bin]]`
+            name.push(placeholder);
+        } else if name == "test" {
+            name.push(placeholder);
+        } else if restricted_names::is_windows_reserved(&name) {
+            // Go ahead and be consistent across platforms
+            name.push(placeholder);
+        } else {
+            break;
+        }
+    }
+
+    name
+}
+
 fn default_target_dir() -> CargoResult<std::path::PathBuf> {
     let mut cargo_home = home::cargo_home()?;
     cargo_home.push("eval");
@@ -428,12 +451,12 @@ mod test_expand {
     fn test_default() {
         snapbox::assert_eq(
             r#"[[bin]]
-name = "test-a472c7a31645d310613df407eab80844346938a3b8fe4f392cae059cb181aa85"
+name = "test--a472c7a31645d310613df407eab80844346938a3b8fe4f392cae059cb181aa85"
 path = "/home/me/test.rs"
 
 [package]
 edition = "2021"
-name = "test"
+name = "test-"
 publish = false
 version = "0.0.0"
 
@@ -450,7 +473,7 @@ strip = true
     fn test_dependencies() {
         snapbox::assert_eq(
             r#"[[bin]]
-name = "test-3a1fa07700654ea2e893f70bb422efa7884eb1021ccacabc5466efe545da8a0b"
+name = "test--3a1fa07700654ea2e893f70bb422efa7884eb1021ccacabc5466efe545da8a0b"
 path = "/home/me/test.rs"
 
 [dependencies]
@@ -458,7 +481,7 @@ time = "0.1.25"
 
 [package]
 edition = "2021"
-name = "test"
+name = "test-"
 publish = false
 version = "0.0.0"