From 5d5312c5dd979f8ae37482f0fc938587aeb5a245 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Mon, 15 Sep 2014 12:58:28 +1000 Subject: [PATCH] runtime: fix parameter checking in syscall.NewCallback I have made mistake while converting it to Go (CL 132820043). Added test as penance for my sin. LGTM=rsc R=golang-codereviews, bradfitz, rsc CC=golang-codereviews https://golang.org/cl/136560043 --- src/runtime/syscall_windows.go | 2 +- src/runtime/syscall_windows_test.go | 39 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go index 959c675f4f..efbcab510d 100644 --- a/src/runtime/syscall_windows.go +++ b/src/runtime/syscall_windows.go @@ -53,7 +53,7 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) { } argsize := uintptr(0) for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] { - if (*t).size != uintptrSize { + if (*t).size > uintptrSize { panic("compilecallback: input parameter size is wrong") } argsize += uintptrSize diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go index fabf935d8e..a828512188 100644 --- a/src/runtime/syscall_windows_test.go +++ b/src/runtime/syscall_windows_test.go @@ -449,3 +449,42 @@ func TestStdcallAndCDeclCallbacks(t *testing.T) { } } } + +func TestRegisterClass(t *testing.T) { + kernel32 := GetDLL(t, "kernel32.dll") + user32 := GetDLL(t, "user32.dll") + mh, _, _ := kernel32.Proc("GetModuleHandleW").Call(0) + cb := syscall.NewCallback(func(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) { + t.Fatal("callback should never get called") + return 0 + }) + type Wndclassex struct { + Size uint32 + Style uint32 + WndProc uintptr + ClsExtra int32 + WndExtra int32 + Instance syscall.Handle + Icon syscall.Handle + Cursor syscall.Handle + Background syscall.Handle + MenuName *uint16 + ClassName *uint16 + IconSm syscall.Handle + } + name := syscall.StringToUTF16Ptr("test_window") + wc := Wndclassex{ + WndProc: cb, + Instance: syscall.Handle(mh), + ClassName: name, + } + wc.Size = uint32(unsafe.Sizeof(wc)) + a, _, err := user32.Proc("RegisterClassExW").Call(uintptr(unsafe.Pointer(&wc))) + if a == 0 { + t.Fatalf("RegisterClassEx failed: %v", err) + } + r, _, err := user32.Proc("UnregisterClassW").Call(uintptr(unsafe.Pointer(name)), 0) + if r == 0 { + t.Fatalf("UnregisterClass failed: %v", err) + } +}