From 29a46c36f68be9d46893d8fe716a8485e5869ec2 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 31 Jan 2024 01:16:24 +0100 Subject: [PATCH] Fix a bug caused by #16592 (#16624) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #16592 passes the return value of `GetEnvironmentStringsW` directly to the `hstring` constructor even though the former returns a double-null terminated string and the latter expects a regular one. This PR fixes the issue by using a basic strlen() loop to compute the length ourselves. It's still theoretically beneficial over the previous code, but now it's rather bitter since the code isn't particularly short anymore and so the biggest benefit is gone. Closes #16623 ## Validation Steps Performed * Validated the `env` string in a debugger ✅ It's 1 character shorter than the old `til::env` string. That's fine however, since any `HSTRING` is always null-terminated anyways and so we get an extra null-terminator for free. * `wt powershell` works ✅ (cherry picked from commit c669afe2a06c6db9a103e81a48cdc5b040d6fcff) Service-Card-Id: 91719863 Service-Version: 1.20 --- src/cascadia/WindowsTerminal/WindowEmperor.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/cascadia/WindowsTerminal/WindowEmperor.cpp b/src/cascadia/WindowsTerminal/WindowEmperor.cpp index e81ccf049b8..3ff3f06f546 100644 --- a/src/cascadia/WindowsTerminal/WindowEmperor.cpp +++ b/src/cascadia/WindowsTerminal/WindowEmperor.cpp @@ -74,7 +74,23 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow) } } - const Remoting::CommandlineArgs eventArgs{ args, cwd, gsl::narrow_cast(nCmdShow), GetEnvironmentStringsW() }; + // GetEnvironmentStringsW() returns a double-null terminated string. + // The hstring(wchar_t*) constructor however only works for regular null-terminated strings. + // Due to that we need to manually search for the terminator. + winrt::hstring env; + { + const wil::unique_environstrings_ptr strings{ GetEnvironmentStringsW() }; + const auto beg = strings.get(); + auto end = beg; + + for (; *end; end += wcsnlen(end, SIZE_T_MAX) + 1) + { + } + + env = winrt::hstring{ beg, gsl::narrow(end - beg) }; + } + + const Remoting::CommandlineArgs eventArgs{ args, cwd, gsl::narrow_cast(nCmdShow), std::move(env) }; const auto isolatedMode{ _app.Logic().IsolatedMode() }; const auto result = _manager.ProposeCommandline(eventArgs, isolatedMode); int exitCode = 0;