proc: return error when calling a non-ptr receiver method on a nil ptr (#4139)

During a call injection if the user tries to call a non-ptr receiver
method on a nil ptr it should receive a nil pointer dereference error.

Fixes #4136
This commit is contained in:
Alessandro Arzilli
2025-09-10 17:26:04 +02:00
committed by GitHub
parent b1fcbdbb25
commit d390fc62a2
3 changed files with 10 additions and 1 deletions

View File

@ -265,6 +265,8 @@ func main() {
var ref strings.Builder
fmt.Fprintf(&ref, "blah")
var nilptrtostruct *astruct
runtime.Breakpoint() // breakpoint here
call1(one, two)
fn2clos(2)
@ -272,5 +274,5 @@ func main() {
d.Method()
d.Base.Method()
x.CallMe()
fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), issue3364.String(), regabistacktest3, rast3, floatsum, ref, mul2, mul2ptr, m)
fmt.Println(one, two, zero, call, call0, call2, callexit, callpanic, callbreak, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d, x, x2.CallMe(5), longstrs, regabistacktest, regabistacktest2, issue2698.String(), issue3364.String(), regabistacktest3, rast3, floatsum, ref, mul2, mul2ptr, m, nilptrtostruct)
}

View File

@ -540,6 +540,10 @@ func funcCallEvalFuncExpr(scope *EvalScope, stack *evalStack, fncall *functionCa
if len(fnvar.Children) > 0 && argnum == (len(fncall.formalArgs)-1) {
argnum++
fncall.receiver = &fnvar.Children[0]
_, isptr := fncall.receiver.DwarfType.(*godwarf.PtrType)
if fncall.receiver.Addr == 0 && !isptr {
return errors.New("nil pointer dereference")
}
fncall.receiver.Name = astutil.ExprToString(fncall.expr.Fun)
}

View File

@ -1354,6 +1354,9 @@ func TestCallFunction(t *testing.T) {
// Issue 3176
{`ref.String()[0]`, []string{`:byte:98`}, nil, 1},
{`ref.String()[20]`, nil, errors.New("index out of bounds"), 1},
// Issue 4136
{`nilptrtostruct.VRcvr(0)`, []string{}, errors.New("nil pointer dereference"), 0},
}
var testcases112 = []testCaseCallFunction{