Skip to content

Commit 8f8c737

Browse files
committed
use UTF16PtrToString function instead of slicing
1 parent a7604b9 commit 8f8c737

File tree

5 files changed

+25
-6
lines changed

5 files changed

+25
-6
lines changed

windows/security_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string {
12301230
return ""
12311231
}
12321232
defer LocalFree(Handle(unsafe.Pointer(sddl)))
1233-
return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(sddl))[:strLen:strLen])
1233+
return UTF16PtrToString(sddl, int(strLen))
12341234
}
12351235

12361236
// ToAbsolute converts a self-relative security descriptor into an absolute one.

windows/svc/mgr/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func toString(p *uint16) string {
5050
if p == nil {
5151
return ""
5252
}
53-
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
53+
return windows.UTF16PtrToString(p, 4096)
5454
}
5555

5656
func toStringSlice(ps *uint16) []string {

windows/svc/mgr/mgr.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (m *Mgr) LockStatus() (*LockStatus, error) {
7373
status := &LockStatus{
7474
IsLocked: lockStatus.IsLocked != 0,
7575
Age: time.Duration(lockStatus.LockDuration) * time.Second,
76-
Owner: windows.UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(lockStatus.LockOwner))[:]),
76+
Owner: toString(lockStatus.LockOwner),
7777
}
7878
return status, nil
7979
}
@@ -204,7 +204,7 @@ func (m *Mgr) ListServices() ([]string, error) {
204204
services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned:servicesReturned]
205205
var names []string
206206
for _, s := range services {
207-
name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
207+
name := toString(s.ServiceName)
208208
names = append(names, name)
209209
}
210210
return names, nil

windows/svc/service.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ const (
224224
func (s *service) run() {
225225
s.goWaits.Wait()
226226
s.h = windows.Handle(ssHandle)
227-
argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc:sArgc]
227+
argv := (*[100]*uint16)(unsafe.Pointer(sArgv))[:sArgc:sArgc]
228228
args := make([]string, len(argv))
229229
for i, a := range argv {
230-
args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:])
230+
args[i] = windows.UTF16PtrToString(a, 1<<20)
231231
}
232232

233233
cmdsToHandler := make(chan ChangeRequest)

windows/syscall_windows.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ func UTF16PtrFromString(s string) (*uint16, error) {
117117
return &a[0], nil
118118
}
119119

120+
// UTF16PtrToString is like UTF16ToString, but takes *uint16
121+
// as a parameter instead of []uint16.
122+
// max is how many times p can be advanced looking for the null terminator.
123+
// If max is hit, the string is truncated at that point.
124+
func UTF16PtrToString(p *uint16, max int) string {
125+
if p == nil {
126+
return ""
127+
}
128+
// Find NUL terminator.
129+
end := unsafe.Pointer(p)
130+
n := 0
131+
for *(*uint16)(end) != 0 && n < max {
132+
end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
133+
n++
134+
}
135+
s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n]
136+
return string(utf16.Decode(s))
137+
}
138+
120139
func Getpagesize() int { return 4096 }
121140

122141
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.

0 commit comments

Comments
 (0)