diff --git a/lib/strings.nix b/lib/strings.nix index f3c7018d4403..b2808b6693f4 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -1432,9 +1432,27 @@ rec { ::: */ escapeNixIdentifier = + let + # see https://nix.dev/manual/nix/2.26/language/identifiers#keywords + nixKeywords = [ + "assert" + "else" + "if" + "in" + "inherit" + "let" + "or" + "rec" + "then" + "with" + ]; + in s: # Regex from https://github.com/NixOS/nix/blob/d048577909e383439c2549e849c5c2f2016c997e/src/libexpr/lexer.l#L91 - if match "[a-zA-Z_][a-zA-Z0-9_'-]*" s != null then s else escapeNixString s; + if (match "[a-zA-Z_][a-zA-Z0-9_'-]*" s != null) && (!lib.elem s nixKeywords) then + s + else + escapeNixString s; /** Escapes a string `s` such that it is safe to include verbatim in an XML diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 1d4f33125ff3..6c1a8c54a547 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -865,6 +865,21 @@ runTests { expected = "'รก'"; }; + testEscapeNixIdentifierNoQuote = { + expr = strings.escapeNixIdentifier "foo"; + expected = ''foo''; + }; + + testEscapeNixIdentifierNumber = { + expr = strings.escapeNixIdentifier "1foo"; + expected = ''"1foo"''; + }; + + testEscapeNixIdentifierKeyword = { + expr = strings.escapeNixIdentifier "assert"; + expected = ''"assert"''; + }; + testSplitStringsDerivation = { expr = lib.dropEnd 1 (strings.splitString "/" dummyDerivation); expected = strings.splitString "/" builtins.storeDir; @@ -2785,6 +2800,7 @@ runTests { ]; emptylist = [ ]; attrs = { + "assert" = false; foo = null; "foo b/ar" = "baz"; }; @@ -2804,7 +2820,7 @@ runTests { functionArgs = ""; list = "[ 3 4 ${function} [ false ] ]"; emptylist = "[ ]"; - attrs = "{ foo = null; \"foo b/ar\" = \"baz\"; }"; + attrs = "{ \"assert\" = false; foo = null; \"foo b/ar\" = \"baz\"; }"; emptyattrs = "{ }"; drv = ""; };