Skip to content

Commit 7138967

Browse files
randall77gopherbot
authored andcommitted
windows: fix slicing of NTUnicodeString values
We were slicing using a count of bytes, not a count of uint16s. Fixes golang/go#73460 Change-Id: If0fd19e795078c01fda5b976e3c34af115b25dcc Reviewed-on: https://go-review.googlesource.com/c/sys/+/667235 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Junyang Shao <[email protected]> Reviewed-by: Quim Muntal <[email protected]> Auto-Submit: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 6a85559 commit 7138967

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

windows/syscall_windows.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -1698,8 +1698,9 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
16981698

16991699
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
17001700
func (s *NTUnicodeString) Slice() []uint16 {
1701-
slice := unsafe.Slice(s.Buffer, s.MaximumLength)
1702-
return slice[:s.Length]
1701+
// Note: this rounds the length down, if it happens
1702+
// to (incorrectly) be odd. Probably safer than rounding up.
1703+
return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2]
17031704
}
17041705

17051706
func (s *NTUnicodeString) String() string {

windows/syscall_windows_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -1473,3 +1473,23 @@ func TestToUnicodeEx(t *testing.T) {
14731473
t.Errorf("UnloadKeyboardLayout failed: %v", err)
14741474
}
14751475
}
1476+
1477+
func TestRoundtripNTUnicodeString(t *testing.T) {
1478+
for _, s := range []string{
1479+
"",
1480+
"hello",
1481+
"Ƀ",
1482+
strings.Repeat("*", 32000), // NTUnicodeString works up to 2^16 byte lengths == 32768 uint16s.
1483+
// TODO: various encoding errors?
1484+
} {
1485+
ntus, err := windows.NewNTUnicodeString(s)
1486+
if err != nil {
1487+
t.Errorf("encoding %q failed: %v", s, err)
1488+
continue
1489+
}
1490+
s2 := ntus.String()
1491+
if s != s2 {
1492+
t.Errorf("round trip of %q = %q, wanted original", s, s2)
1493+
}
1494+
}
1495+
}

windows/types_windows.go

+2
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,8 @@ type CommTimeouts struct {
27002700

27012701
// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING.
27022702
type NTUnicodeString struct {
2703+
// Note: Length and MaximumLength are in *bytes*, not uint16s.
2704+
// They should always be even.
27032705
Length uint16
27042706
MaximumLength uint16
27052707
Buffer *uint16

0 commit comments

Comments
 (0)