From 0e0dc5316e3f72f6e4ea0468fd8a56cba5e72101 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Tue, 4 Aug 2026 16:11:28 +0000 Subject: [PATCH] install: use reg add to avoid setx truncating Windows PATH INSTALL.bat and UNINSTALL.bat persist the system-wide PATH with 'setx /M', which silently truncates the value it writes to 1024 characters. When installing from a shell with an already long inherited PATH, such as a Visual Studio Developer Prompt, this drops the tail of the persisted PATH, which can remove entries required to even start cmd.exe or powershell.exe in a later session. Use 'reg add' on the same registry key instead, which has no such limit and requires the same administrator privilege setx already needed. Mark these Windows batch scripts, which intentionally carry carriage-return line endings, with the cr-at-eol whitespace attribute so the pre-commit hook stops flagging their line endings as trailing whitespace. Extend the native-cmd CI job to replace the inherited PATH with a controlled value past the legacy 1024-character limit before installing, then check the persisted registry PATH afterward, so a regression here gets caught automatically. The replacement keeps the length controlled and safely under the 8191-character command line length limit of cmd.exe, rather than extending the runner's own already large inherited PATH and risking hitting that separate limit. Fixes #654 Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- .gitattributes | 4 ++++ .github/workflows/windows_tests.yaml | 26 +++++++++++++++++++++++++- .hunspell.en.dic | 1 + NEWS.rst | 6 ++++++ doc/source/devel/ci.rst | 5 ++++- script/INSTALL.bat | 4 +++- script/UNINSTALL.bat | 4 +++- 7 files changed, 46 insertions(+), 4 deletions(-) diff --git a/.gitattributes b/.gitattributes index 3fbc0933c..92f72e59a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -23,3 +23,7 @@ script/pre-commit export-ignore # Scorecard entirely # no export of website-specific content doc/talk export-ignore +# these Windows batch scripts intentionally use CRLF line endings, do not +# flag the CR as a trailing whitespace error +script/INSTALL.bat whitespace=cr-at-eol +script/UNINSTALL.bat whitespace=cr-at-eol diff --git a/.github/workflows/windows_tests.yaml b/.github/workflows/windows_tests.yaml index 2a47e407e..c26f15db7 100644 --- a/.github/workflows/windows_tests.yaml +++ b/.github/workflows/windows_tests.yaml @@ -48,7 +48,31 @@ jobs: run: | jar xvf %DIST_WIN%.zip cd %DIST_WIN% - INSTALL.bat + :: replace (rather than extend) the inherited PATH with a + :: controlled value that is still past the legacy 1024-character + :: limit of the 'setx' tool previously used here, to simulate a + :: large pre-existing PATH such as found in a Visual Studio + :: Developer Prompt (see GH-654), while staying safely under the + :: 8191-character command line length limit of cmd.exe + setlocal enabledelayedexpansion + set "PATH=%SYSTEMROOT%\system32;%SYSTEMROOT%" + for /L %%i in (1,1,50) do set "PATH=!PATH!;C:\dummy-path-segment-%%i" + set "PATH=!PATH!;C:\marker-end-of-long-path" + call INSTALL.bat + - name: Check persisted PATH is not truncated + shell: cmd + run: | + reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH > persisted-path.txt + %SYSTEMROOT%\system32\find /i "marker-end-of-long-path" persisted-path.txt >nul + if errorlevel 1 ( + echo "persisted system PATH truncated: marker entry not found" + exit /b 1 + ) + %SYSTEMROOT%\system32\find /i "%MODULE_DIR%" persisted-path.txt >nul + if errorlevel 1 ( + echo "installation 'bin' directory not found in persisted system PATH" + exit /b 1 + ) - name: Test Modules installation shell: cmd run: | diff --git a/.hunspell.en.dic b/.hunspell.en.dic index 8d8de51a5..617915391 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -736,6 +736,7 @@ setState setenv setgid setq +setx severities sexualized sgr diff --git a/NEWS.rst b/NEWS.rst index 8e97a6a68..7af7124cd 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -173,6 +173,12 @@ Modules 5.7.0 (not yet released) white matte color instead of black. * Doc: document Windows Terminal profile setup as an alternative way to initialize Modules on Windows without an install script. (fix issue #634) +* Install: use ``reg add`` instead of ``setx /M`` to persist the system-wide + ``PATH`` environment variable in :file:`INSTALL.bat` and + :file:`UNINSTALL.bat`, as ``setx`` silently truncates the value it writes + to 1024 characters, which could corrupt the system ``PATH`` when installing + from a shell with an already long inherited ``PATH`` (e.g. a Visual Studio + Developer Prompt). (fix issue #654) .. _5.6 release notes: diff --git a/doc/source/devel/ci.rst b/doc/source/devel/ci.rst index 3d73609ca..ca078e8c4 100644 --- a/doc/source/devel/ci.rst +++ b/doc/source/devel/ci.rst @@ -107,7 +107,10 @@ on Windows: `_), built via ``make dist-win`` and installed/tested/uninstalled through the generated :file:`INSTALL.bat`/:file:`TESTINSTALL.bat`/:file:`UNINSTALL.bat` - scripts, driven from a ``cmd`` shell. + scripts, driven from a ``cmd`` shell. Before installing, the inherited + ``PATH`` is padded past the legacy 1024-character limit of the + ``setx`` tool (mimicking a Visual Studio Developer Prompt) to guard + against the persisted system ``PATH`` getting silently truncated. ``native-pwsh`` Same native Windows install, but through the PowerShell variant (:file:`INSTALL_PWSH.bat`/:file:`TESTINSTALL_PWSH.ps1`). diff --git a/script/INSTALL.bat b/script/INSTALL.bat index e3c742205..d9a4e8285 100644 --- a/script/INSTALL.bat +++ b/script/INSTALL.bat @@ -23,7 +23,9 @@ set FIND=%SYSTEMROOT%\system32\find echo %PATH% | %FIND% /i "%binpath:"=%">nul || set "NEWPATH=%binpath%;%PATH%" if not "%NEWPATH%" == "" ( set "PATH=%NEWPATH%" - setx /M PATH "%NEWPATH%" + :: 'reg add' is used instead of 'setx /M' as the latter silently + :: truncates the value it persists to 1024 characters + reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_EXPAND_SZ /d "%NEWPATH%" /f ) if errorlevel 1 ( exit /b 3 ) diff --git a/script/UNINSTALL.bat b/script/UNINSTALL.bat index 9527e3f10..9e4ea6079 100644 --- a/script/UNINSTALL.bat +++ b/script/UNINSTALL.bat @@ -13,7 +13,9 @@ setlocal enableextensions enabledelayedexpansion set "NEWPATH=!PATH:%binpath%;=!" if not "%NEWPATH%" == "%PATH%" ( set "PATH=%NEWPATH%" - setx /M PATH "%NEWPATH%" + :: 'reg add' is used instead of 'setx /M' as the latter silently + :: truncates the value it persists to 1024 characters + reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_EXPAND_SZ /d "%NEWPATH%" /f ) if errorlevel 1 ( exit /b 1 )