fix(windows): escape '$' before .NET regex replacement in config patching - #2962
Open
bettercalln1ck wants to merge 1 commit into
Open
fix(windows): escape '$' before .NET regex replacement in config patching#2962bettercalln1ck wants to merge 1 commit into
bettercalln1ck wants to merge 1 commit into
Conversation
…hing
Update-HermesConfigFile interpolated $Model and $BaseUrl straight into
-replace replacement strings, and the bootstrap .env rewrite did the same with
GgufFile/LlmModel. .NET reads '$' in a replacement as a substitution token, so:
'$&' splices the entire matched line into the value —
default: "qwen$&-turbo" -> default: "qwen default: "old-model"-turbo"
'$$' collapses to a single '$'
Double '$' in all four values before substituting. Verified against PowerShell
7.4; '$1' and '${x}' were already safe because the patterns carry no capture
groups, so the issue's example does not reproduce — '$&' and '$$' do.
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.
Summary
Fixes #2928.
Update-HermesConfigFile(ods/installers/windows/phases/06-directories.ps1:392-393) interpolated$Modeland$BaseUrldirectly into-replacereplacement strings, and the bootstrap.envrewrite atinstall-windows.ps1:376-377did the same with$tierConfig.GgufFile/$tierConfig.LlmModel. .NET reads$in a replacement as a substitution token, so a value carrying one is rewritten on its way into the file.One correction to the issue, from actually running it.
$1and${x}are not mangled: .NET leaves a group reference literal when the pattern has no such group, and these patterns carry no capture groups at all. The tokens that do fire are$$and$&, and$&is the destructive one — it splices the entire matched line into the value:That third line is not just a wrong value, it is broken YAML.
Worth knowing for severity: on the Hermes path the function's own post-write verification (
$verified.Contains(...)) catches the mangling and returns$false, so the installer aborts loudly rather than shipping a bad config — butWriteAllTexthas already run, so the corrupted file is on disk. On the.envpath there is no verification, so it is genuinely silent, which is where the issue's "nothing errors" description belongs.Fix: double
$viaString.Replace('$', '$$')on all four values before substitution. The verification still compares against the raw value, which is what should land on disk.AI Assistance
Claude Code drafted the patch and the regression test and ran the validation recorded below. The human author reviewed the diff, chose the validation, and is accountable for the change.
Release Lane
release/2.6.xmainStable hotfix reason:
Changed Surface
Risk And Validation
git diff --checkrelease/2.6.xCommands/results:
Operational Change Check
Notes For Reviewers
tests/contracts/test-windows-hermes-config-patching.sh(already inmake test). They are static greps, matching how the rest of that file guards Windows code — the repo has no PowerShell test runner wired intomake test, and a pwsh-dependent test would skip in every CI job that currently runs. The behavioural evidence above was produced out-of-band instead; say the word if you would rather I add a pwsh-gated test file for it.-replacesites in these files substitute integers or literals, so they are unaffected.06-directories.ps1:481interpolates a fixed here-string with no$in it.$.