diff --git a/.replit b/.replit new file mode 100644 index 000000000..619bd7227 --- /dev/null +++ b/.replit @@ -0,0 +1,8 @@ +modules = ["go-1.21", "web", "nodejs-20"] +run = "go run v2/cmd/wails/main.go" + +[nix] +channel = "stable-24_05" + +[deployment] +run = ["sh", "-c", "go run v2/cmd/wails/main.go"] diff --git a/v2/internal/go-common-file-dialog/cfd/DialogConfig.go b/v2/internal/go-common-file-dialog/cfd/DialogConfig.go index 221dbef27..edefd4e13 100644 --- a/v2/internal/go-common-file-dialog/cfd/DialogConfig.go +++ b/v2/internal/go-common-file-dialog/cfd/DialogConfig.go @@ -2,6 +2,8 @@ package cfd +import "fmt" + type FileFilter struct { // The display name of the filter (That is shown to the user) DisplayName string @@ -102,6 +104,10 @@ func (config *DialogConfig) apply(dialog Dialog) (err error) { } if config.SelectedFileFilterIndex != 0 { + if config.SelectedFileFilterIndex > uint(len(fileFilters)) { + err = fmt.Errorf("selected file filter index out of range") + return + } err = dialog.SetSelectedFileFilterIndex(config.SelectedFileFilterIndex) if err != nil { return diff --git a/v2/internal/go-common-file-dialog/cfd/iShellItem.go b/v2/internal/go-common-file-dialog/cfd/iShellItem.go index 6a747f4d9..080115345 100644 --- a/v2/internal/go-common-file-dialog/cfd/iShellItem.go +++ b/v2/internal/go-common-file-dialog/cfd/iShellItem.go @@ -30,6 +30,10 @@ type iShellItemVtbl struct { func newIShellItem(path string) (*iShellItem, error) { var shellItem *iShellItem pathPtr := ole.SysAllocString(path) + defer func(v *int16) { + _ = ole.SysFreeString(v) + }(pathPtr) + ret, _, _ := procSHCreateItemFromParsingName.Call( uintptr(unsafe.Pointer(pathPtr)), 0, @@ -40,10 +44,9 @@ func newIShellItem(path string) (*iShellItem, error) { func (vtbl *iShellItemVtbl) getDisplayName(objPtr unsafe.Pointer) (string, error) { var ptr *uint16 - ret, _, _ := syscall.Syscall(vtbl.GetDisplayName, - 2, + ret, _, _ := syscall.SyscallN(vtbl.GetDisplayName, uintptr(objPtr), - 0x80058000, // SIGDN_FILESYSPATH + 0x80058000, // SIGDN_FILESYSPATH, uintptr(unsafe.Pointer(&ptr))) if err := hresultToError(ret); err != nil { return "", err diff --git a/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go b/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go index d904e72b2..c548160d1 100644 --- a/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go +++ b/v2/internal/go-common-file-dialog/cfd/iShellItemArray.go @@ -38,11 +38,9 @@ type iShellItemArrayVtbl struct { func (vtbl *iShellItemArrayVtbl) getCount(objPtr unsafe.Pointer) (uintptr, error) { var count uintptr - ret, _, _ := syscall.Syscall(vtbl.GetCount, - 1, + ret, _, _ := syscall.SyscallN(vtbl.GetCount, uintptr(objPtr), - uintptr(unsafe.Pointer(&count)), - 0) + uintptr(unsafe.Pointer(&count))) if err := hresultToError(ret); err != nil { return 0, err } @@ -51,8 +49,7 @@ func (vtbl *iShellItemArrayVtbl) getCount(objPtr unsafe.Pointer) (uintptr, error func (vtbl *iShellItemArrayVtbl) getItemAt(objPtr unsafe.Pointer, index uintptr) (string, error) { var shellItem *iShellItem - ret, _, _ := syscall.Syscall(vtbl.GetItemAt, - 2, + ret, _, _ := syscall.SyscallN(vtbl.GetItemAt, uintptr(objPtr), index, uintptr(unsafe.Pointer(&shellItem))) diff --git a/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go b/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go index 929d5a2b7..8c88c297c 100644 --- a/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go +++ b/v2/internal/go-common-file-dialog/cfd/vtblCommonFunc.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package cfd @@ -19,20 +18,16 @@ func hresultToError(hr uintptr) error { } func (vtbl *iUnknownVtbl) release(objPtr unsafe.Pointer) error { - ret, _, _ := syscall.Syscall(vtbl.Release, - 0, + ret, _, _ := syscall.SyscallN(vtbl.Release, uintptr(objPtr), - 0, 0) return hresultToError(ret) } func (vtbl *iModalWindowVtbl) show(objPtr unsafe.Pointer, hwnd uintptr) error { - ret, _, _ := syscall.Syscall(vtbl.Show, - 1, + ret, _, _ := syscall.SyscallN(vtbl.Show, uintptr(objPtr), - hwnd, - 0) + hwnd) return hresultToError(ret) } @@ -49,8 +44,16 @@ func (vtbl *iFileDialogVtbl) setFileTypes(objPtr unsafe.Pointer, filters []FileF pszSpec: ole.SysAllocString(filter.Pattern), } } - ret, _, _ := syscall.Syscall(vtbl.SetFileTypes, - 2, + + // Ensure memory is freed after use + defer func() { + for _, spec := range comDlgFilterSpecs { + ole.SysFreeString(spec.pszName) + ole.SysFreeString(spec.pszSpec) + } + }() + + ret, _, _ := syscall.SyscallN(vtbl.SetFileTypes, uintptr(objPtr), uintptr(cFileTypes), uintptr(unsafe.Pointer(&comDlgFilterSpecs[0]))) @@ -82,21 +85,17 @@ func (vtbl *iFileDialogVtbl) setFileTypes(objPtr unsafe.Pointer, filters []FileF // FOS_FORCEPREVIEWPANEON = 0x40000000, // FOS_SUPPORTSTREAMABLEITEMS = 0x80000000 func (vtbl *iFileDialogVtbl) setOptions(objPtr unsafe.Pointer, options uint32) error { - ret, _, _ := syscall.Syscall(vtbl.SetOptions, - 1, + ret, _, _ := syscall.SyscallN(vtbl.SetOptions, uintptr(objPtr), - uintptr(options), - 0) + uintptr(options)) return hresultToError(ret) } func (vtbl *iFileDialogVtbl) getOptions(objPtr unsafe.Pointer) (uint32, error) { var options uint32 - ret, _, _ := syscall.Syscall(vtbl.GetOptions, - 1, + ret, _, _ := syscall.SyscallN(vtbl.GetOptions, uintptr(objPtr), - uintptr(unsafe.Pointer(&options)), - 0) + uintptr(unsafe.Pointer(&options))) return options, hresultToError(ret) } @@ -122,11 +121,9 @@ func (vtbl *iFileDialogVtbl) setDefaultFolder(objPtr unsafe.Pointer, path string return err } defer shellItem.vtbl.release(unsafe.Pointer(shellItem)) - ret, _, _ := syscall.Syscall(vtbl.SetDefaultFolder, - 1, + ret, _, _ := syscall.SyscallN(vtbl.SetDefaultFolder, uintptr(objPtr), - uintptr(unsafe.Pointer(shellItem)), - 0) + uintptr(unsafe.Pointer(shellItem))) return hresultToError(ret) } @@ -136,40 +133,32 @@ func (vtbl *iFileDialogVtbl) setFolder(objPtr unsafe.Pointer, path string) error return err } defer shellItem.vtbl.release(unsafe.Pointer(shellItem)) - ret, _, _ := syscall.Syscall(vtbl.SetFolder, - 1, + ret, _, _ := syscall.SyscallN(vtbl.SetFolder, uintptr(objPtr), - uintptr(unsafe.Pointer(shellItem)), - 0) + uintptr(unsafe.Pointer(shellItem))) return hresultToError(ret) } func (vtbl *iFileDialogVtbl) setTitle(objPtr unsafe.Pointer, title string) error { titlePtr := ole.SysAllocString(title) - ret, _, _ := syscall.Syscall(vtbl.SetTitle, - 1, + defer ole.SysFreeString(titlePtr) // Ensure the string is freed + ret, _, _ := syscall.SyscallN(vtbl.SetTitle, uintptr(objPtr), - uintptr(unsafe.Pointer(titlePtr)), - 0) + uintptr(unsafe.Pointer(titlePtr))) return hresultToError(ret) } func (vtbl *iFileDialogVtbl) close(objPtr unsafe.Pointer) error { - ret, _, _ := syscall.Syscall(vtbl.Close, - 1, - uintptr(objPtr), - 0, - 0) + ret, _, _ := syscall.SyscallN(vtbl.Close, + uintptr(objPtr)) return hresultToError(ret) } func (vtbl *iFileDialogVtbl) getResult(objPtr unsafe.Pointer) (*iShellItem, error) { var shellItem *iShellItem - ret, _, _ := syscall.Syscall(vtbl.GetResult, - 1, + ret, _, _ := syscall.SyscallN(vtbl.GetResult, uintptr(objPtr), - uintptr(unsafe.Pointer(&shellItem)), - 0) + uintptr(unsafe.Pointer(&shellItem))) return shellItem, hresultToError(ret) } @@ -186,42 +175,51 @@ func (vtbl *iFileDialogVtbl) getResultString(objPtr unsafe.Pointer) (string, err } func (vtbl *iFileDialogVtbl) setClientGuid(objPtr unsafe.Pointer, guid *ole.GUID) error { - ret, _, _ := syscall.Syscall(vtbl.SetClientGuid, - 1, + // Ensure the GUID is not nil + if guid == nil { + return fmt.Errorf("guid cannot be nil") + } + + // Call the SetClientGuid method + ret, _, _ := syscall.SyscallN(vtbl.SetClientGuid, uintptr(objPtr), - uintptr(unsafe.Pointer(guid)), - 0) + uintptr(unsafe.Pointer(guid))) + + // Convert the HRESULT to a Go error return hresultToError(ret) } func (vtbl *iFileDialogVtbl) setDefaultExtension(objPtr unsafe.Pointer, defaultExtension string) error { - if defaultExtension[0] == '.' { + // Ensure the string is not empty before accessing the first character + if len(defaultExtension) > 0 && defaultExtension[0] == '.' { defaultExtension = strings.TrimPrefix(defaultExtension, ".") } + + // Allocate memory for the default extension string defaultExtensionPtr := ole.SysAllocString(defaultExtension) - ret, _, _ := syscall.Syscall(vtbl.SetDefaultExtension, - 1, + defer ole.SysFreeString(defaultExtensionPtr) // Ensure the string is freed + + // Call the SetDefaultExtension method + ret, _, _ := syscall.SyscallN(vtbl.SetDefaultExtension, uintptr(objPtr), - uintptr(unsafe.Pointer(defaultExtensionPtr)), - 0) + uintptr(unsafe.Pointer(defaultExtensionPtr))) + + // Convert the HRESULT to a Go error return hresultToError(ret) } func (vtbl *iFileDialogVtbl) setFileName(objPtr unsafe.Pointer, fileName string) error { fileNamePtr := ole.SysAllocString(fileName) - ret, _, _ := syscall.Syscall(vtbl.SetFileName, - 1, + defer ole.SysFreeString(fileNamePtr) // Ensure the string is freed + ret, _, _ := syscall.SyscallN(vtbl.SetFileName, uintptr(objPtr), - uintptr(unsafe.Pointer(fileNamePtr)), - 0) + uintptr(unsafe.Pointer(fileNamePtr))) return hresultToError(ret) } func (vtbl *iFileDialogVtbl) setSelectedFileFilterIndex(objPtr unsafe.Pointer, index uint) error { - ret, _, _ := syscall.Syscall(vtbl.SetFileTypeIndex, - 1, + ret, _, _ := syscall.SyscallN(vtbl.SetFileTypeIndex, uintptr(objPtr), - uintptr(index+1), // SetFileTypeIndex counts from 1 - 0) + uintptr(index+1)) // SetFileTypeIndex counts from 1 return hresultToError(ret) } diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 4991b144c..14adb19dd 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added nil check for Drag-n-Drop on Windows. Fixed by in [PR](https://github.com/wailsapp/wails/pull/3597) by @leaanthony based on the suggestion by @Alpa-1 in [#3596](https://github.com/wailsapp/wails/issues/3596). - Fixed typos in various .mdx files. [PR #3628](https://github.com/wailsapp/wails/pull/3628) by [@deining](https://github.com/deining) - Fixed `notifyListeners()` race condition when terminated mid-emission [PR](https://github.com/wailsapp/wails/pull/3695) by [@mrf345](https://github.com/mrf345) +- Fixed dialogs in Windows when using Go 1.23 in [PR](https://github.com/wailsapp/wails/pull/3707) by [@leaanthony](https://github.com/leaanthony) - Fixed drag and drop missing cursor icon [PR](https://github.com/wailsapp/wails/pull/3703) by [@mrf345](https://github.com/mrf345) ### Changed