Repository navigation
Fix zip extraction on Windows when Group Policy blocks temporary .bat files - #15202
Merged
Merged
Conversation
On Windows, unzip() launched PowerShell (for .zip files) and the self-extracting TinyTeX .exe through safeWindowsExec, which writes a quarto-safe-exec*.bat into %TEMP% and runs it with cmd /c. Group Policies that block running .bat files from %TEMP% make every extraction fail: quarto add, quarto use template, quarto use brand, and the TinyTeX, veraPDF and Chrome for Testing installs (#15198). This has been the case since 2022, so no released version works on such machines; the dart-sass fix for #14367 did not cover unzip. Both programs are real executables, so the .bat added nothing here. safeWindowsExec exists for batch files and cmd quoting; unzip went through it for #2998 (spaces in the profile path), which was actually fixed by quoting the paths inside the PowerShell script. PowerShell is now launched directly with -NoProfile -NonInteractive, and arguments travel as UTF-16, so accented and CJK paths need no chcp. Paths are embedded as PowerShell single-quoted literals with every single-quote character doubled, including the curly forms PowerShell also accepts. Before, a path containing an apostrophe (O'Brien, or D’Arcy) broke the script; that is the failing case the new test captures, since the Group Policy itself cannot be reproduced locally. Windows System32 tar.exe was rejected: probing showed it fails on archive paths outside the ANSI code page and on UTF-8 entry names. The script sets [Console]::OutputEncoding to UTF-8, taking over the output side of the removed chcp 65001. Measured from a code page 850 console, without it a non-ASCII path in PowerShell's error message comes back as '?'. Like chcp, it leaves the shared console at 65001. The unit test cannot detect its removal: the test process's console is already at 65001 when it runs.
Collaborator
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
cderv
added a commit
that referenced
this pull request
Oct 27, 2026
…eline #15202 adds four Deno.* calls in tests/unit/zip.test.ts (Deno.mkdirSync x2, Deno.copyFileSync, Deno.readTextFileSync) to build its unicode zip fixture. Its PR run reported them as warnings asking for the count to be accepted before merging, but the baseline was not updated, so main has failed the Runtime Boundary job since 55a313c. These calls have no deno_ral equivalent yet (fs/temp helpers arrive with PR 09 of the runtime migration), so the increase is accepted with --update-baseline --accept-increase. Only the tests scope changes: 870 -> 874.
1 of 5 tasks
cderv
added a commit
that referenced
this pull request
Oct 27, 2026
In pull request mode, only a Deno.* call that src/deno_ral replaces failed the Runtime Boundary check. Any other count increase was a warning on a green job, so a PR could merge without its baseline update and turn main red. #15202 did this, and main was fixed by 4bebcb4. #15134 hit the same failure earlier. The check now fails when a count is above the PR's own tools/runtime-boundary-baseline.json. That is the same comparison the push check makes on main after merge. The contributor has nothing to change. A maintainer updates the branch with main, runs --update-baseline --accept-increase, and pushes the baseline to the PR. A count that fits under the PR's baseline and was not raised by the PR is reported as a notice and does not fail the run. Covered Deno.* API errors are unchanged. Related to #15153, #15183, #15202, and #15134.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Windows machines where a Group Policy blocks running
.batfiles from the temporary folder, every zip extraction fails:quarto add,quarto use templateandquarto use brandfrom GitHub (always downloaded as.zipon Windows), andquarto install tinytex. The debug log showscmd /c ...\quarto-safe-exec*.batthenERROR: Failed to unzip template.with the Group Policy block message.This is the same environment as #14367, but a different call site. The fix for #14367 (#14273) moved dart-sass off the temporary
.bat;unzip()insrc/core/zip.tsstill went throughsafeWindowsExec, which writesquarto-safe-exec*.batinto%TEMP%and runs it withcmd /c. That code is unchanged since 2022, so no released version works on such machines.Fix
safeWindowsExecexists for batch files, whose arguments onlycmd.execan parse.powershell.exeand the self-extracting TinyTeX.exeare real executables, so the.batbrought nothing here. Both are now launched directly, and arguments go through as UTF-16, so accented and CJK paths still work withoutchcp 65001.The archive and destination paths are embedded in the PowerShell script as single-quoted literals, with every single-quote character doubled, including the curly forms PowerShell also accepts. Before, a path with an apostrophe (
O'Brien,D’Arcy) broke the script. The new unit test captures that case, as the Group Policy itself can't be reproduced in a test.The script sets
[Console]::OutputEncodingto UTF-8, which replaces the output side of the removedchcp 65001. Without it, PowerShell's error message shows a non-ASCII path as?on a console using a code page such as 850.Windows
tar.exe(bsdtar) was considered instead of PowerShell and rejected: it fails to open an archive whose path is outside the ANSI code page, and skips zip entries with UTF-8 non-ASCII names.Other
safeWindowsExeccallers (tlmgr,fmtutil,reg.exelookups,openUrl) still use the temporary.batand are not changed here.Test plan
tests/unit/zip.test.tsfails before the fix (PowerShellParserErroron the apostrophe) and passes after, extracting non-ASCII entry names into a path with a space,',’,&,éand日本quarto add quarto-ext/fontawesome --log-level debugon Windows showspowershelllaunched directly, with nocmd /c ...quarto-safe-exec*.batOutputEncoding, garbled without it.exeextraction is covered by thequarto install tinytexstep of the Windows smoke tests jobChecklist
I have (if applicable):
AI-assisted PR
Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.
Fixes #15198