From 3e17edd5e6d75e3908338e28b7101e847182b581 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Mon, 18 May 2026 15:29:10 -0500 Subject: [PATCH] zsh: escape named directory hashes Named directory hash values are rendered into zsh code. Interpolating them inside double quotes is not enough for values containing quotes, glob syntax, or other shell metacharacters. Render both the hash name and target with shell escaping so dirHashes entries are emitted as literal zsh arguments. --- modules/programs/zsh/default.nix | 8 +++++--- .../programs/zsh/zshrc-content-priorities.nix | 12 ++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/programs/zsh/default.nix b/modules/programs/zsh/default.nix index 34d519946..d6e25b22d 100644 --- a/modules/programs/zsh/default.nix +++ b/modules/programs/zsh/default.nix @@ -395,11 +395,13 @@ in ) cfg.shellAliases ); - dirHashesStr = concatStringsSep "\n" ( - lib.mapAttrsToList (k: v: ''hash -d ${k}="${v}"'') cfg.dirHashes - ); # Keep double quotes so existing configs using shell variables like # $HOME still expand, while escaping chars special inside them. + dirHashesStr = concatStringsSep "\n" ( + lib.mapAttrsToList ( + k: v: ''hash -d ${lib.escapeShellArg k}="${lib.escape [ "\\" "\"" "`" ] v}"'' + ) cfg.dirHashes + ); cdpathStr = concatStringsSep " " (map (v: ''"${lib.escape [ "\\" "\"" "`" ] v}"'') cfg.cdpath); in mkIf cfg.enable ( diff --git a/tests/modules/programs/zsh/zshrc-content-priorities.nix b/tests/modules/programs/zsh/zshrc-content-priorities.nix index 114c7e3f5..6c87e602e 100644 --- a/tests/modules/programs/zsh/zshrc-content-priorities.nix +++ b/tests/modules/programs/zsh/zshrc-content-priorities.nix @@ -8,6 +8,12 @@ "/tmp/with space" "/tmp/with[glob]" ]; + dirHashes = { + docs = "/tmp/with space"; + glob = "/tmp/with[glob]"; + home = "$HOME/Documents"; + quoted = ''/tmp/with "quotes"''; + }; initContent = lib.mkMerge [ (lib.mkBefore '' @@ -71,6 +77,12 @@ # Default priority echo "Default priority content" + # Named Directory Hashes + hash -d docs="/tmp/with space" + hash -d glob="/tmp/with[glob]" + hash -d home="$HOME/Documents" + hash -d quoted="/tmp/with \"quotes\"" + zprof # Low priority (mkAfter) echo "Low priority content"