From 7e0ef81015efa6d5fcdaafd388ad461aa4c6ad15 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 10:20:44 +0200
Subject: [PATCH 1/7] stdenv.mkDerivation: Always sanitize derivation name

---
 pkgs/stdenv/generic/make-derivation.nix | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index 2465449867cb..8749e8b75552 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -219,9 +219,11 @@ else let
           # it again.
           staticMarker = lib.optionalString stdenv.hostPlatform.isStatic "-static";
         in
+        lib.strings.sanitizeDerivationName (
           if attrs ? name
           then attrs.name + hostSuffix
-          else "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}";
+          else "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}"
+        );
     }) // {
       builder = attrs.realBuilder or stdenv.shell;
       args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
@@ -340,8 +342,9 @@ else let
   # passed to the builder and is not a dependency.  But since we
   # include it in the result, it *is* available to nix-env for queries.
   meta = {
-      # `name` above includes cross-compilation cruft (and is under assert),
-      # lets have a clean always accessible version here.
+      # `name` above includes cross-compilation cruft,
+      # is under assert, and is sanitized.
+      # Let's have a clean always accessible version here.
       name = attrs.name or "${attrs.pname}-${attrs.version}";
 
       # If the packager hasn't specified `outputsToInstall`, choose a default,

From 225ca9088a69767ceceac8ceb4dafc7f023754d8 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 10:25:49 +0200
Subject: [PATCH 2/7] runCommand*: Rely on mkDerivation to sanitize name

---
 pkgs/build-support/trivial-builders.nix | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/pkgs/build-support/trivial-builders.nix b/pkgs/build-support/trivial-builders.nix
index 68f0f1bc4ddc..c3072357a57e 100644
--- a/pkgs/build-support/trivial-builders.nix
+++ b/pkgs/build-support/trivial-builders.nix
@@ -70,8 +70,7 @@ rec {
     # name of the resulting derivation
     }: buildCommand:
     stdenv.mkDerivation ({
-      name = lib.strings.sanitizeDerivationName name;
-      inherit buildCommand;
+      inherit buildCommand name;
       passAsFile = [ "buildCommand" ]
         ++ (derivationArgs.passAsFile or []);
     }

From c39eff52dc6426db00938a3b3ff372b96f65c802 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 10:26:41 +0200
Subject: [PATCH 3/7] testEqualDerivation: Rely on mkDerivation to sanitize
 name

---
 pkgs/build-support/test-equal-derivation.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkgs/build-support/test-equal-derivation.nix b/pkgs/build-support/test-equal-derivation.nix
index 5d2185ce1652..652f3716b2a7 100644
--- a/pkgs/build-support/test-equal-derivation.nix
+++ b/pkgs/build-support/test-equal-derivation.nix
@@ -23,7 +23,7 @@ let
   drvB = builtins.unsafeDiscardOutputDependency b.drvPath or (throw "testEqualDerivation third argument must be a package");
   name =
     if a?name
-    then lib.strings.sanitizeDerivationName "testEqualDerivation-${a.name}"
+    then "testEqualDerivation-${a.name}"
     else "testEqualDerivation";
 in
 if drvA == drvB then

From 04c9dd89bf24d9265dc7886ff428a15960dbf3f6 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 10:30:20 +0200
Subject: [PATCH 4/7] nixos/tests/nixops: Remove sanitizeDerivationName

---
 nixos/tests/nixops/default.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nixos/tests/nixops/default.nix b/nixos/tests/nixops/default.nix
index f0834c51f0b4..227b38815073 100644
--- a/nixos/tests/nixops/default.nix
+++ b/nixos/tests/nixops/default.nix
@@ -97,7 +97,7 @@ let
     derivations and all build dependency outputs, all the way down.
   */
   allDrvOutputs = pkg:
-    let name = lib.strings.sanitizeDerivationName "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}";
+    let name = "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}";
     in
     pkgs.runCommand name { refs = pkgs.writeReferencesToFile pkg.drvPath; } ''
       touch $out

From 342a3c32c9834d6e7e7ad44228c8fe59961e6410 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 11:19:37 +0200
Subject: [PATCH 5/7] lib.sanitizeDerivationName: Optimize the common case

---
 lib/strings.nix | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/strings.nix b/lib/strings.nix
index b2fd495e4c84..3a61f5be68b6 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -756,7 +756,14 @@ rec {
        sanitizeDerivationName pkgs.hello
        => "-nix-store-2g75chlbpxlrqn15zlby2dfh8hr9qwbk-hello-2.10"
   */
-  sanitizeDerivationName = string: lib.pipe string [
+  sanitizeDerivationName =
+  let okRegex = match "^[[:alnum:]+_?=-][[:alnum:]+._?=-]*$";
+  in
+  string:
+  # First detect the common case of already valid strings, to speed those up
+  if stringLength string <= 207 && okRegex string != null
+  then unsafeDiscardStringContext string
+  else lib.pipe string [
     # Get rid of string context. This is safe under the assumption that the
     # resulting string is only used as a derivation name
     unsafeDiscardStringContext

From 2999ab114e3e122ed3be44dc72e069e66a087de6 Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Wed, 30 Mar 2022 11:20:44 +0200
Subject: [PATCH 6/7] lib.sanitizeDerivationName: Test with unicode

---
 lib/tests/misc.nix | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 271119031395..47f731512341 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -649,6 +649,11 @@ runTests {
     expected = "foo";
   };
 
+  testSanitizeDerivationNameUnicode = testSanitizeDerivationName {
+    name = "fö";
+    expected = "f-";
+  };
+
   testSanitizeDerivationNameAscii = testSanitizeDerivationName {
     name = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
     expected = "-+--.-0123456789-=-?-ABCDEFGHIJKLMNOPQRSTUVWXYZ-_-abcdefghijklmnopqrstuvwxyz-";

From fffabe7500e972eb5275199c82a35132a07fa29f Mon Sep 17 00:00:00 2001
From: Robert Hensing <robert@roberthensing.nl>
Date: Tue, 5 Apr 2022 19:14:09 +0200
Subject: [PATCH 7/7] lib.sanitizeDerivationName: Simplify regex

`^` and `$` are implicit in `match`.
---
 lib/strings.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/strings.nix b/lib/strings.nix
index 3a61f5be68b6..45d3bcbb440d 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -757,7 +757,7 @@ rec {
        => "-nix-store-2g75chlbpxlrqn15zlby2dfh8hr9qwbk-hello-2.10"
   */
   sanitizeDerivationName =
-  let okRegex = match "^[[:alnum:]+_?=-][[:alnum:]+._?=-]*$";
+  let okRegex = match "[[:alnum:]+_?=-][[:alnum:]+._?=-]*";
   in
   string:
   # First detect the common case of already valid strings, to speed those up