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 )