From 72dd34eaf37b197f975285603c5f4dcffd6d61fa Mon Sep 17 00:00:00 2001 From: David Levy Date: Thu, 5 Feb 2026 16:06:59 -0600 Subject: [PATCH 1/2] fix: resolve linting warnings - Replace deprecated io/ioutil with os.ReadFile in internal/io/file - Simplify make([]*Credential, count, count) to make([]*Credential, count) - Explicitly ignore errors in test cleanup/setup for credman tests Remaining warnings are for unsafe pointer handling in credman which requires careful review before modifying. --- internal/credman/credman_windows.go | 5 +++-- internal/credman/credman_windows_test.go | 7 ++++--- internal/io/file/file.go | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/internal/credman/credman_windows.go b/internal/credman/credman_windows.go index 0fb1c68f..d1719955 100644 --- a/internal/credman/credman_windows.go +++ b/internal/credman/credman_windows.go @@ -7,10 +7,11 @@ package credman import ( - syscall "golang.org/x/sys/windows" "reflect" "time" "unsafe" + + syscall "golang.org/x/sys/windows" ) // Load the Windows DLL "advapi32.dll", then set up Go wrapper functions for @@ -78,7 +79,7 @@ func EnumerateCredentials(filter string, all bool) ([]*Credential, error) { Len: count, Cap: count, })) - credentials := make([]*Credential, count, count) + credentials := make([]*Credential, count) for i, c := range systemCredentials { credentials[i] = convertFromSystemCredential(c) } diff --git a/internal/credman/credman_windows_test.go b/internal/credman/credman_windows_test.go index c3223d96..7e0c5547 100644 --- a/internal/credman/credman_windows_test.go +++ b/internal/credman/credman_windows_test.go @@ -4,9 +4,10 @@ package credman import ( - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestWriteCredential(t *testing.T) { @@ -31,7 +32,7 @@ func TestWriteCredential(t *testing.T) { assert.Equal(t, credentials[0].Persist, PersistSession, "WriteCredential wrote incorrect Persist, got: %d, want: %d", credentials[0].Persist, PersistSession) // Cleanup the written credential - DeleteCredential(credential, CredTypeGeneric) + _ = DeleteCredential(credential, CredTypeGeneric) } func TestDeleteCredential(t *testing.T) { @@ -44,7 +45,7 @@ func TestDeleteCredential(t *testing.T) { } // Write the credential first - WriteCredential(credential, CredTypeGeneric) + _ = WriteCredential(credential, CredTypeGeneric) err := DeleteCredential(credential, CredTypeGeneric) assert.NoErrorf(t, err, "DeleteCredential returned an error: %v", err) diff --git a/internal/io/file/file.go b/internal/io/file/file.go index 7f0b2360..f390b775 100644 --- a/internal/io/file/file.go +++ b/internal/io/file/file.go @@ -4,10 +4,10 @@ package file import ( - "github.com/microsoft/go-sqlcmd/internal/io/folder" - "io/ioutil" "os" "path/filepath" + + "github.com/microsoft/go-sqlcmd/internal/io/folder" ) func CloseFile(f *os.File) { @@ -55,7 +55,7 @@ func Exists(filename string) (exists bool) { } func GetContents(filename string) string { - b, err := ioutil.ReadFile(filename) + b, err := os.ReadFile(filename) checkErr(err) return string(b) From d953ecee716ab5cc74a587d6df342e035220e3eb Mon Sep 17 00:00:00 2001 From: David Levy Date: Thu, 16 Apr 2026 11:54:47 -0500 Subject: [PATCH 2/2] refactor: replace deprecated reflect.SliceHeader with unsafe.Slice Replace reflect.SliceHeader usage with unsafe.Slice (available since Go 1.17) in credman_windows.go. Change CREDENTIAL.CredentialBlob from uintptr to unsafe.Pointer to eliminate go vet warnings. Explicitly discard credFree.Call return values. --- internal/credman/credman_windows.go | 25 ++++++++---------------- internal/credman/credman_windows_test.go | 2 +- internal/credman/types_windows.go | 6 ++++-- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/internal/credman/credman_windows.go b/internal/credman/credman_windows.go index d1719955..73a20568 100644 --- a/internal/credman/credman_windows.go +++ b/internal/credman/credman_windows.go @@ -7,7 +7,6 @@ package credman import ( - "reflect" "time" "unsafe" @@ -59,7 +58,7 @@ func DeleteCredential(credential *Credential, credentialType CredentialType) err // Credential Manager func EnumerateCredentials(filter string, all bool) ([]*Credential, error) { var count int - var systemCredential uintptr + var systemCredential unsafe.Pointer var filterPtr *uint16 if !all { filterPtr, _ = syscall.UTF16PtrFromString(filter) @@ -73,12 +72,8 @@ func EnumerateCredentials(filter string, all bool) ([]*Credential, error) { if ret == 0 { return nil, err } - defer credFree.Call(systemCredential) - systemCredentials := *(*[]*CREDENTIAL)(unsafe.Pointer(&reflect.SliceHeader{ - Data: systemCredential, - Len: count, - Cap: count, - })) + defer func() { _, _, _ = credFree.Call(uintptr(systemCredential)) }() + systemCredentials := unsafe.Slice((**CREDENTIAL)(systemCredential), count) credentials := make([]*Credential, count) for i, c := range systemCredentials { credentials[i] = convertFromSystemCredential(c) @@ -118,9 +113,9 @@ func convertToSystemCredential(cred *Credential) (result *CREDENTIAL) { result.LastWritten = syscall.NsecToFiletime(cred.LastWritten.UnixNano()) result.CredentialBlobSize = uint32(len(cred.CredentialBlob)) if len(cred.CredentialBlob) > 0 { - result.CredentialBlob = uintptr(unsafe.Pointer(&cred.CredentialBlob[0])) + result.CredentialBlob = unsafe.Pointer(&cred.CredentialBlob[0]) } else { - result.CredentialBlob = 0 + result.CredentialBlob = nil } result.Persist = uint32(cred.Persist) result.TargetAlias, _ = syscall.UTF16PtrFromString(cred.TargetAlias) @@ -129,15 +124,11 @@ func convertToSystemCredential(cred *Credential) (result *CREDENTIAL) { return } -func copyBytesToSlice(src uintptr, len uint32) (bytes []byte) { - if src == uintptr(0) { +func copyBytesToSlice(src unsafe.Pointer, len uint32) (bytes []byte) { + if src == nil { return []byte{} } bytes = make([]byte, len) - copy(bytes, *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ - Data: src, - Len: int(len), - Cap: int(len), - }))) + copy(bytes, unsafe.Slice((*byte)(src), len)) return } diff --git a/internal/credman/credman_windows_test.go b/internal/credman/credman_windows_test.go index 7e0c5547..24b670d0 100644 --- a/internal/credman/credman_windows_test.go +++ b/internal/credman/credman_windows_test.go @@ -80,6 +80,6 @@ func TestNegConvertToSystemCredential(t *testing.T) { } func TestNegcopyBytesToSlice(t *testing.T) { - b := copyBytesToSlice(uintptr(0), 0) + b := copyBytesToSlice(nil, 0) assert.Len(t, b, 0, "bytes should be empty") } diff --git a/internal/credman/types_windows.go b/internal/credman/types_windows.go index 1b4e5ee4..90988ca5 100644 --- a/internal/credman/types_windows.go +++ b/internal/credman/types_windows.go @@ -4,8 +4,10 @@ package credman import ( - syscall "golang.org/x/sys/windows" "time" + "unsafe" + + syscall "golang.org/x/sys/windows" ) const ( @@ -56,7 +58,7 @@ type CREDENTIAL struct { Comment *uint16 LastWritten syscall.Filetime CredentialBlobSize uint32 - CredentialBlob uintptr + CredentialBlob unsafe.Pointer Persist uint32 AttributeCount uint32 Attributes uintptr