From 776a65d8f2a9f7631a81cd2d7d36e28d3e4bb45e Mon Sep 17 00:00:00 2001 From: Yaroslav Vorobiov Date: Mon, 27 Apr 2020 18:11:46 +0300 Subject: [PATCH] windows: UTF16PtrToString remove max parameter --- windows/env_windows.go | 2 +- windows/security_windows.go | 2 +- windows/svc/mgr/config.go | 25 +++++++++---------------- windows/svc/mgr/mgr.go | 4 ++-- windows/svc/mgr/recovery.go | 4 ++-- windows/svc/service.go | 2 +- windows/syscall_windows.go | 27 +++++++++++++-------------- 7 files changed, 29 insertions(+), 37 deletions(-) diff --git a/windows/env_windows.go b/windows/env_windows.go index 07511e14..92ac05ff 100644 --- a/windows/env_windows.go +++ b/windows/env_windows.go @@ -39,7 +39,7 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { defer DestroyEnvironmentBlock(block) blockp := uintptr(unsafe.Pointer(block)) for { - entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)), (1<<30)-1) + entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp))) if len(entry) == 0 { break } diff --git a/windows/security_windows.go b/windows/security_windows.go index b0fecd50..808d3899 100644 --- a/windows/security_windows.go +++ b/windows/security_windows.go @@ -1230,7 +1230,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string { return "" } defer LocalFree(Handle(unsafe.Pointer(sddl))) - return UTF16PtrToString(sddl, int(strLen)) + return UTF16PtrToString(sddl) } // ToAbsolute converts a self-relative security descriptor into an absolute one. diff --git a/windows/svc/mgr/config.go b/windows/svc/mgr/config.go index c042ecd8..30d39294 100644 --- a/windows/svc/mgr/config.go +++ b/windows/svc/mgr/config.go @@ -45,26 +45,19 @@ type Config struct { DelayedAutoStart bool // the service is started after other auto-start services are started plus a short delay } -func toString(p *uint16) string { - return windows.UTF16PtrToString(p, 4096) -} - func toStringSlice(ps *uint16) []string { r := make([]string, 0) p := unsafe.Pointer(ps) - offset := func(count int) uintptr { - return unsafe.Sizeof(uint16(0)) * (uintptr)(count) - } - for { - s := windows.UTF16PtrToString((*uint16)(p), 4096) - if s == "" { + s := windows.UTF16PtrToString((*uint16)(p)) + if len(s) == 0 { break } r = append(r, s) - p = unsafe.Pointer(uintptr(p) + offset(len(s)+1)) + offset := unsafe.Sizeof(uint16(0)) * (uintptr)(len(s)+1) + p = unsafe.Pointer(uintptr(p) + offset) } return r @@ -109,13 +102,13 @@ func (s *Service) Config() (Config, error) { ServiceType: p.ServiceType, StartType: p.StartType, ErrorControl: p.ErrorControl, - BinaryPathName: toString(p.BinaryPathName), - LoadOrderGroup: toString(p.LoadOrderGroup), + BinaryPathName: windows.UTF16PtrToString(p.BinaryPathName), + LoadOrderGroup: windows.UTF16PtrToString(p.LoadOrderGroup), TagId: p.TagId, Dependencies: toStringSlice(p.Dependencies), - ServiceStartName: toString(p.ServiceStartName), - DisplayName: toString(p.DisplayName), - Description: toString(p2.Description), + ServiceStartName: windows.UTF16PtrToString(p.ServiceStartName), + DisplayName: windows.UTF16PtrToString(p.DisplayName), + Description: windows.UTF16PtrToString(p2.Description), DelayedAutoStart: delayedStart, }, nil } diff --git a/windows/svc/mgr/mgr.go b/windows/svc/mgr/mgr.go index edc3a46f..a6cfe51f 100644 --- a/windows/svc/mgr/mgr.go +++ b/windows/svc/mgr/mgr.go @@ -73,7 +73,7 @@ func (m *Mgr) LockStatus() (*LockStatus, error) { status := &LockStatus{ IsLocked: lockStatus.IsLocked != 0, Age: time.Duration(lockStatus.LockDuration) * time.Second, - Owner: toString(lockStatus.LockOwner), + Owner: windows.UTF16PtrToString(lockStatus.LockOwner), } return status, nil } @@ -204,7 +204,7 @@ func (m *Mgr) ListServices() ([]string, error) { services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned:servicesReturned] var names []string for _, s := range services { - name := toString(s.ServiceName) + name := windows.UTF16PtrToString(s.ServiceName) names = append(names, name) } return names, nil diff --git a/windows/svc/mgr/recovery.go b/windows/svc/mgr/recovery.go index bd1b3b2a..0139d781 100644 --- a/windows/svc/mgr/recovery.go +++ b/windows/svc/mgr/recovery.go @@ -112,7 +112,7 @@ func (s *Service) RebootMessage() (string, error) { return "", err } p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0])) - return toString(p.RebootMsg), nil + return windows.UTF16PtrToString(p.RebootMsg), nil } // SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action. @@ -131,5 +131,5 @@ func (s *Service) RecoveryCommand() (string, error) { return "", err } p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0])) - return toString(p.Command), nil + return windows.UTF16PtrToString(p.Command), nil } diff --git a/windows/svc/service.go b/windows/svc/service.go index b0e16296..d896b74b 100644 --- a/windows/svc/service.go +++ b/windows/svc/service.go @@ -227,7 +227,7 @@ func (s *service) run() { argv := (*[100]*uint16)(unsafe.Pointer(sArgv))[:sArgc:sArgc] args := make([]string, len(argv)) for i, a := range argv { - args[i] = windows.UTF16PtrToString(a, 1<<20) + args[i] = windows.UTF16PtrToString(a) } cmdsToHandler := make(chan ChangeRequest) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 0cd000d8..757c12ce 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -117,23 +117,22 @@ func UTF16PtrFromString(s string) (*uint16, error) { return &a[0], nil } -// UTF16PtrToString is like UTF16ToString, but takes *uint16 -// as a parameter instead of []uint16. -// max is how many times p can be advanced looking for the null terminator. -// If max is hit, the string is truncated at that point. -func UTF16PtrToString(p *uint16, max int) string { +// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string. +// If the pointer is nil, this returns the empty string. This assumes that the UTF-16 sequence is terminated +// at a zero word; if the zero word is not present, the program may crash. +func UTF16PtrToString(p *uint16) string { if p == nil { return "" } - // Find NUL terminator. - end := unsafe.Pointer(p) - n := 0 - for *(*uint16)(end) != 0 && n < max { - end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) - n++ + + var encoded []uint16 + for *p != 0 { + encoded = append(encoded, *p) + + p = (*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(*p))) } - s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n] - return string(utf16.Decode(s)) + + return string(utf16.Decode(encoded)) } func Getpagesize() int { return 4096 } @@ -1402,7 +1401,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e return "", err } defer CoTaskMemFree(unsafe.Pointer(p)) - return UTF16PtrToString(p, (1<<30)-1), nil + return UTF16PtrToString(p), nil } // RtlGetVersion returns the version of the underlying operating system, ignoring