Fix incorrect string -> wstring conversion, causing utf16 corruption (#41406)
Blue committed
Aug 21, 2026 at 17:54 UTC
aeacef12f9c7a29c423868ba990c82aff044509e
3 files changed
+26
-4
src/shared/inc/stringshared.h
+4
-4
@@ -1253,7 +1253,7 @@ struct std::formatter<char*, wchar_t>
1253
template <typename TCtx>
1254
auto format(const char* str, TCtx& ctx) const
1255
{
1256
- return std::format_to(ctx.out(), "{}", wsl::shared::string::MultiByteToWide(str));
1256
+ return std::format_to(ctx.out(), L"{}", wsl::shared::string::MultiByteToWide(str));
1257
}
1258
};
1259
@@ -1269,7 +1269,7 @@ struct std::formatter<const char*, wchar_t>
1269
template <typename TCtx>
1270
auto format(const char* str, TCtx& ctx) const
1271
{
1272
- return std::format_to(ctx.out(), "{}", wsl::shared::string::MultiByteToWide(str));
1272
+ return std::format_to(ctx.out(), L"{}", wsl::shared::string::MultiByteToWide(str));
1273
}
1274
};
1275
@@ -1285,7 +1285,7 @@ struct std::formatter<char[N], wchar_t>
1285
template <typename TCtx>
1286
auto format(const char str[N], TCtx& ctx) const
1287
{
1288
- return std::format_to(ctx.out(), "{}", wsl::shared::string::MultiByteToWide(str));
1288
+ return std::format_to(ctx.out(), L"{}", wsl::shared::string::MultiByteToWide(str));
1289
}
1290
};
1291
@@ -1301,7 +1301,7 @@ struct std::formatter<std::basic_string<char, Traits, Allocator>, wchar_t>
1301
template <typename TCtx>
1302
auto format(const std::basic_string<char, Traits, Allocator>& str, TCtx& ctx) const
1303
{
1304
- return std::format_to(ctx.out(), "{}", wsl::shared::string::MultiByteToWide(str));
1304
+ return std::format_to(ctx.out(), L"{}", wsl::shared::string::MultiByteToWide(str));
1305
}
1306
};
1307
test/windows/StringUnitTests.cpp
+8
@@ -77,6 +77,14 @@ class StringUnitTests
77
{
78
WSL_TEST_CLASS(StringUnitTests)
79
80
+ TEST_METHOD(FormatUtf8StringAsWideString)
81
+ {
82
+ const std::string input{"安装依赖"};
83
+ const auto expected = wsl::shared::string::MultiByteToWide(input);
84
+
85
+ VERIFY_ARE_EQUAL(expected, std::format(L"{}", input));
86
+ }
87
+
88
TEST_METHOD(ParseMemorySize_LegacyForms)
89
{
90
const std::vector<std::pair<LPCSTR, std::optional<uint64_t>>> TestCases{
test/windows/wslc/e2e/WSLCE2EImageBuildTests.cpp
+14
@@ -119,6 +119,20 @@ class WSLCE2EImageBuildTests
119
VERIFY_ARE_EQUAL(BuiltImage.NameAndTag(), wsl::shared::string::MultiByteToWide(inspectData.RepoTags.value()[0]));
120
}
121
122
+ WSLC_TEST_METHOD(WSLCE2E_Image_Build_UnicodeOutput_Success)
123
+ {
124
+ auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-unicode-output";
125
+ auto cleanup = SetupTestDirectory(testRoot);
126
+
127
+ auto dockerfilePath = testRoot / L"Dockerfile";
128
+ WriteTestFileContent(dockerfilePath, "FROM debian:latest\nRUN echo 安装依赖\n");
129
+
130
+ auto buildResult = RunWslc(std::format(
131
+ L"build \"{}\" -f \"{}\" --output type=cacheonly", SharedOutputBuildContext().wstring(), dockerfilePath.wstring()));
132
+ buildResult.Verify({.ExitCode = 0});
133
+ VERIFY_IS_TRUE(buildResult.StderrContainsSubstring(wsl::shared::string::MultiByteToWide("安装依赖")));
134
+ }
135
+
136
WSLC_TEST_METHOD(WSLCE2E_Image_Build_BuildArgsFileAndMultipleTags_Success)
137
{
138
auto imageCleanup1 = DeleteImageOnExit(BuiltImageTag1);