purego: check for nil callback (#126)
It was possible to create a C callback for a nil function but this shouldn't be possible. This commit makes it so that NewCallback will panic on a nil function.
- commit
- c3a82d74994b67409e9fd97be97c819977b894e9
- author
- TotallyGamerJet · · 2023-04-10 13:44 UTC
- committer
- GitHub · · 2023-04-10 13:44 UTC
- parent
- e145907
- signature
- GPG Unverified
4AEE18F83AFDEB23The key is unknown
1 file · +9 -4
M syscall_sysv.go +9 -4
| @@ -22,9 +22,11 @@ type syscall9Args struct { | |||
| 22 | 22 | ||
| 23 | 23 | //go:nosplit | |
| 24 | 24 | func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { | |
| 25 | - | args := syscall9Args{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, | |
| 25 | + | args := syscall9Args{ | |
| 26 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, | |
| 26 | 27 | a1, a2, a3, a4, a5, a6, a7, a8, | |
| 27 | - | r1, r2, err} | |
| 28 | + | r1, r2, err, | |
| 29 | + | } | |
| 28 | 30 | runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args)) | |
| 29 | 31 | return args.r1, args.r2, args.err | |
| 30 | 32 | } | |
| @@ -73,7 +75,10 @@ type callbackArgs struct { | |||
| 73 | 75 | func compileCallback(fn interface{}) uintptr { | |
| 74 | 76 | val := reflect.ValueOf(fn) | |
| 75 | 77 | if val.Kind() != reflect.Func { | |
| 76 | - | panic("purego: type is not a function") | |
| 78 | + | panic("purego: the type must be a function but was not") | |
| 79 | + | } | |
| 80 | + | if val.IsNil() { | |
| 81 | + | panic("purego: function must not be nil") | |
| 77 | 82 | } | |
| 78 | 83 | ty := val.Type() | |
| 79 | 84 | for i := 0; i < ty.NumIn(); i++ { | |
| @@ -134,7 +139,7 @@ func callbackWrap(a *callbackArgs) { | |||
| 134 | 139 | var intsN int // intsN represents the number of integer arguments processed | |
| 135 | 140 | // stack points to the index into frame of the current stack element. | |
| 136 | 141 | // The stack begins after the float and integer registers. | |
| 137 | - | var stack = numOfIntegerRegisters() + numOfFloats | |
| 142 | + | stack := numOfIntegerRegisters() + numOfFloats | |
| 138 | 143 | for i := range args { | |
| 139 | 144 | var pos int | |
| 140 | 145 | switch fnType.In(i).Kind() { | |
| @@ -22,9 +22,11 @@ type syscall9Args struct { | |||||
| 22 | 22 | ||||
| 23 | //go:nosplit | 23 | //go:nosplit | ||
| 24 | func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { | 24 | func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { | ||
| 25 | - | args := syscall9Args{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, | 25 | + | args := syscall9Args{ |
| 26 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, | |||
| 26 | a1, a2, a3, a4, a5, a6, a7, a8, | 27 | a1, a2, a3, a4, a5, a6, a7, a8, | ||
| 27 | - | r1, r2, err} | 28 | + | r1, r2, err, |
| 29 | + | } | |||
| 28 | runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args)) | 30 | runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args)) | ||
| 29 | return args.r1, args.r2, args.err | 31 | return args.r1, args.r2, args.err | ||
| 30 | } | 32 | } | ||
| @@ -73,7 +75,10 @@ type callbackArgs struct { | |||||
| 73 | func compileCallback(fn interface{}) uintptr { | 75 | func compileCallback(fn interface{}) uintptr { | ||
| 74 | val := reflect.ValueOf(fn) | 76 | val := reflect.ValueOf(fn) | ||
| 75 | if val.Kind() != reflect.Func { | 77 | if val.Kind() != reflect.Func { | ||
| 76 | - | panic("purego: type is not a function") | 78 | + | panic("purego: the type must be a function but was not") |
| 79 | + | } | |||
| 80 | + | if val.IsNil() { | |||
| 81 | + | panic("purego: function must not be nil") | |||
| 77 | } | 82 | } | ||
| 78 | ty := val.Type() | 83 | ty := val.Type() | ||
| 79 | for i := 0; i < ty.NumIn(); i++ { | 84 | for i := 0; i < ty.NumIn(); i++ { | ||
| @@ -134,7 +139,7 @@ func callbackWrap(a *callbackArgs) { | |||||
| 134 | var intsN int // intsN represents the number of integer arguments processed | 139 | var intsN int // intsN represents the number of integer arguments processed | ||
| 135 | // stack points to the index into frame of the current stack element. | 140 | // stack points to the index into frame of the current stack element. | ||
| 136 | // The stack begins after the float and integer registers. | 141 | // The stack begins after the float and integer registers. | ||
| 137 | - | var stack = numOfIntegerRegisters() + numOfFloats | 142 | + | stack := numOfIntegerRegisters() + numOfFloats |
| 138 | for i := range args { | 143 | for i := range args { | ||
| 139 | var pos int | 144 | var pos int | ||
| 140 | switch fnType.In(i).Kind() { | 145 | switch fnType.In(i).Kind() { | ||