Files
dsh-worktable/02_process/upstream/utf16-picker-fix.patch
T

36 lines
4.1 KiB
Diff

diff --git a/packages/host/directory-picker-native/src/win32-dialog-bindings.ts b/packages/host/directory-picker-native/src/win32-dialog-bindings.ts
index 654bbc5..5b3977a 100644
--- a/packages/host/directory-picker-native/src/win32-dialog-bindings.ts
+++ b/packages/host/directory-picker-native/src/win32-dialog-bindings.ts
@@ -37,7 +37,7 @@ interface Koffi {
function readUtf16(koffi: Koffi, address: unknown): string {
const bytes = Buffer.from(koffi.view(address, 32768))
let end = 0
- while (end + 1 < bytes.length && bytes[end] !== 0) end += 2
+ while (end + 1 < bytes.length && (bytes[end] !== 0 || bytes[end + 1] !== 0)) end += 2
return bytes.toString('utf16le', 0, end)
}
diff --git a/packages/host/directory-picker-native/tests/win32-dialog-bindings.spec.ts b/packages/host/directory-picker-native/tests/win32-dialog-bindings.spec.ts
index b8ff4c3..9bef599 100644
--- a/packages/host/directory-picker-native/tests/win32-dialog-bindings.spec.ts
+++ b/packages/host/directory-picker-native/tests/win32-dialog-bindings.spec.ts
@@ -180,6 +180,17 @@ describe('loadWin32DialogBindings over the fake COM world', () => {
expect(world.uninitialized).toBe(1)
})
+ it('keeps paths whose code units carry a zero low byte (BMP trigger + astral surrogate)', async () => {
+ // Ā (U+0100) encodes as 00 01 in UTF-16LE, and 🀀 (U+1F000) ends in the
+ // low surrogate DC00 (00 DC): both code units have a zero low byte
+ // without being the NUL terminator. readUtf16 must only stop at a full
+ // 00 00 unit, otherwise the path is truncated at the first such char.
+ const world = comWorld({ path: 'C:\\Ā区\\🀀-workspace' })
+ installFakeKoffi(world)
+ const bindings = await (await loadBindingsModule()).loadWin32DialogBindings()
+ expect(runFolderDialog(bindings, '选择工作区目录', vi.fn())).toBe('C:\\Ā区\\🀀-workspace')
+ })
+
it('maps dismissal and the S_FALSE CoInitializeEx', async () => {
const world = comWorld({ showHr: HRESULT_CANCELLED, coInitHr: 1 })
installFakeKoffi(world)