Open server-may-cry opened 2 years ago
Query hook receives non nil Result with nil value. This leads to a panic:
runtime error: invalid memory address or nil pointer dereference
Code like this don't trigger a nil pointer panic as it have a e.Result != nil check.
e.Result != nil
func (h hook) AfterQuery(ctx context.Context, e *pg.QueryEvent) error { if e.Err != nil { h.log("error", e.Err) } if e.Result != nil { h.log("returned", e.Result.RowsReturned()) h.log("affected", e.Result.RowsAffected()) } return nil }
Part of panic stack trace
/usr/local/go/src/runtime/panic.go:1038 +0x215 github.com/go-pg/pg/v10.(*result).RowsReturned(0xdc4c80) /go/pkg/mod/github.com/go-pg/pg/v10@v10.10.6/result.go:52 <REDACTED>.AfterQuery({{0xdae1c0, 0xc00011e110}}, {0xdc4c80, 0xc000b5b7d0}, 0xc0004a1900) <REDACTED>.go:110 +0xf2 github.com/go-pg/pg/v10.(*baseDB).afterQueryFromIndex(0xc0000af0e0, {0xdc4c80, 0xc000b5b7d0}, 0x0, 0xdd8890) /go/pkg/mod/github.com/go-pg/pg/v10@v10.10.6/hook.go:130 +0x75 github.com/go-pg/pg/v10.(*baseDB).afterQuery(0xc000146d00, {0xdc4c80, 0xc000b5b7d0}, 0xc0009c8005, {0xdbce20, 0x0}, {0xdae1c0, 0xc00011e110}) /go/pkg/mod/github.com/go-pg/pg/v10@v10.10.6/hook.go:125 +0xaa
Explicitly set nil for Result when *result is nil. Related article https://codefibershq.com/blog/golang-why-nil-is-not-always-nil
Result
*result
Here is an example of how nil becomes not nil https://goplay.tools/snippet/DVV1XNz5icn
On first line res is a nil. At the last line it assigned a value from db.simpleQuery https://github.com/go-pg/pg/blob/51b8018c9110133183f54aa5d786c316bbfd11fc/base.go#L236-L246
res
db.simpleQuery
In db.simpleQuery result might get returned with nil value of type *result, but in db.simpleQuery it will be wrapped into Result and will pass != nil check https://github.com/go-pg/pg/blob/51b8018c9110133183f54aa5d786c316bbfd11fc/base.go#L544-L553
!= nil
Note: Same issue exists in other parts of a code.
func (h hook) AfterQuery(ctx context.Context, e *pg.QueryEvent) error { if e.Err != nil { h.log("error", e.Err) } else if e.Result != nil { h.log("returned", e.Result.RowsReturned()) h.log("affected", e.Result.RowsAffected()) } return nil }
Query hook receives non nil Result with nil value. This leads to a panic:
Expected Behavior
Code like this don't trigger a nil pointer panic as it have a
e.Result != nil
check.Current Behavior
Part of panic stack trace
Possible Solution
Explicitly set nil for
Result
when*result
is nil. Related article https://codefibershq.com/blog/golang-why-nil-is-not-always-nilSteps to Reproduce
Here is an example of how nil becomes not nil https://goplay.tools/snippet/DVV1XNz5icn
Context (Environment)
Detailed Description
On first line
res
is a nil. At the last line it assigned a value fromdb.simpleQuery
https://github.com/go-pg/pg/blob/51b8018c9110133183f54aa5d786c316bbfd11fc/base.go#L236-L246In
db.simpleQuery
result might get returned with nil value of type*result
, but indb.simpleQuery
it will be wrapped intoResult
and will pass!= nil
check https://github.com/go-pg/pg/blob/51b8018c9110133183f54aa5d786c316bbfd11fc/base.go#L544-L553Note: Same issue exists in other parts of a code.
Possible Implementation
Workaround of this issue is to change a hook to look like this: