"panic: runtime error: index out of range" when fuzz testing
Code that generates bug:
type eventType string
func (e eventType) Error() error { return errors.New("invalid event type " + string(e)) }
const TransactionIdRsp eventType = "transactionIdRsp"
type response struct {
ShortAddr string `json:"short_addr"`
ExtAddr string `json:"ext_addr"`
Rssi int `json:"rssi"`
EventType eventType `json:"eventType"`
Payload json.RawMessage `json:"payload"`
TransactionId int `json:"transactionId"`
}
type TransactionIdResponse struct {
DeviceTransactionId int `json:"deviceTransactionId"`
}
func (t *TransactionIdResponse) UnmarshalJSON(bytes []byte) error {
type transactionIdResponse TransactionIdResponse
var r response
var err error
if err = json.Unmarshal(bytes, &r); err != nil {
return err
}
if r.EventType != TransactionIdRsp {
return r.EventType.Error()
}
if err = json.Unmarshal(r.Payload, (*transactionIdResponse)(t)); err != nil {
return err
}
return nil
}
Test case:
func FuzzTransactionIdResponseUnmarshal(f *testing.F) {
f.Add(string(TransactionIdRsp), 0)
f.Fuzz(func(t *testing.T, eT string, deviceTransactionId int) {
value := []byte(fmt.Sprintf(`{"short_addr":"0x2","ext_addr":"0x124b001cbd4efa","rssi":-45,"eventType":"%s","payload":{"deviceTransactionId":%d},"transactionId":0}`, eT, deviceTransactionId))
var j TransactionIdResponse
err := json.Unmarshal(value, &j)
if eT != string(TransactionIdRsp) {
target := TransactionIdRsp.Error()
require.ErrorAs(t, err, &target)
return
}
require.NoError(t, err)
assert.Equal(t, deviceTransactionId, j.DeviceTransactionId)
})
}
All the time buggy string is smth. like string("\",\"\\0\"\\}"), but running this corpus separately doesn't produce any error. The problem appears only on fuzz testing.
Stack trace:
=== RUN FuzzTransactionIdResponseUnmarshal
fuzz: elapsed: 0s, gathering baseline coverage: 0/257 completed
fuzz: elapsed: 1s, gathering baseline coverage: 257/257 completed, now fuzzing with 16 workers
fuzz: elapsed: 3s, execs: 183977 (61015/sec), new interesting: 1 (total: 258)
fuzz: elapsed: 6s, execs: 449113 (88654/sec), new interesting: 1 (total: 258)
fuzz: minimizing 60-byte failing input file
fuzz: elapsed: 8s, minimizing
--- FAIL: FuzzTransactionIdResponseUnmarshal (8.17s)
--- FAIL: FuzzTransactionIdResponseUnmarshal (0.00s)
testing.go:1485: panic: runtime error: index out of range [85] with length 83
goroutine 39572 [running]:
runtime/debug.Stack()
C:/Users/Alexander/sdk/go1.20.2/src/runtime/debug/stack.go:24 +0x9e
testing.tRunner.func1()
C:/Users/Alexander/sdk/go1.20.2/src/testing/testing.go:1485 +0x1f6
panic({0x13e26c0, 0xc0046bc2b8})
C:/Users/Alexander/sdk/go1.20.2/src/runtime/panic.go:884 +0x213
github.com/goccy/go-json/internal/decoder.skipWhiteSpace(...)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/internal/decoder/context.go:49
github.com/goccy/go-json/internal/decoder.(*structDecoder).Decode(0xc000246000, 0xc003ef0120, 0x0, 0xc004944360?, 0xc00493c600)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/internal/decoder/struct.go:786 +0x10d0
github.com/goccy/go-json.unmarshal({0xc004944360?, 0x100c004389438?, 0x29fd514bd18?}, {0x139d660, 0xc00493c600}, {0x0, 0x0, 0x0?})
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/decode.go:47 +0x23c
github.com/goccy/go-json.Unmarshal(...)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/json.go:276
bitbucket/4suites/4suites-fc-messages.(*response).UnmarshalJSON(0x52?, {0xc004944360?, 0x0?, 0x60?})
C:/Users/Alexander/GolandProjects/4suites-fc-messages/base.go:61 +0x5b
github.com/goccy/go-json/internal/decoder.(*unmarshalJSONDecoder).Decode(0xc0002000c0, 0xc0000969e0, 0x9200000098?, 0xc0049442a0?, 0xc00493c600)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/internal/decoder/unmarshal_json.go:94 +0x3d3
github.com/goccy/go-json.unmarshal({0xc0049442a0?, 0xc00493fea0?, 0xfaab2d?}, {0x13b60c0, 0xc00493c600}, {0x0, 0x0, 0x0?})
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/decode.go:47 +0x23c
github.com/goccy/go-json.Unmarshal(...)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/json.go:276
bitbucket/4suites/4suites-fc-messages.(*TransactionIdResponse).UnmarshalJSON(0x52?, {0xc0049442a0, 0x52, 0x52})
C:/Users/Alexander/GolandProjects/4suites-fc-messages/transaction_id.go:81 +0x9a
github.com/goccy/go-json/internal/decoder.(*unmarshalJSONDecoder).Decode(0xc0000b7f20, 0xc000222120, 0x100c00493fe00?, 0xc00493fe00?, 0xc0048cb088)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/internal/decoder/unmarshal_json.go:94 +0x3d3
github.com/goccy/go-json.unmarshal({0xc00493fe00?, 0xc00493fd60?, 0x94?}, {0x13b5f40, 0xc0048cb088}, {0x0, 0x0, 0x0?})
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/decode.go:47 +0x23c
github.com/goccy/go-json.Unmarshal(...)
C:/Users/Alexander/go/pkg/mod/github.com/goccy/[email protected]/json.go:276
bitbucket/4suites/4suites-fc-messages.FuzzTransactionIdResponseUnmarshal.func1(0x0?, {0xc0048cb070, 0x10}, 0x1008419?)
C:/Users/Alexander/GolandProjects/4suites-fc-messages/transaction_id_test.go:72 +0x13f
reflect.Value.call({0x13ae240?, 0x142df50?, 0xfef156?}, {0x13fb11e, 0x4}, {0xc00493c5a0, 0x3, 0x4?})
C:/Users/Alexander/sdk/go1.20.2/src/reflect/value.go:586 +0xb07
reflect.Value.Call({0x13ae240?, 0x142df50?, 0x15d8df0?}, {0xc00493c5a0?, 0x13fa600?, 0xc0048cb068?})
C:/Users/Alexander/sdk/go1.20.2/src/reflect/value.go:370 +0xbc
testing.(*F).Fuzz.func1.1(0x0?)
C:/Users/Alexander/sdk/go1.20.2/src/testing/fuzz.go:335 +0x3f3
testing.tRunner(0xc00493b380, 0xc004940480)
C:/Users/Alexander/sdk/go1.20.2/src/testing/testing.go:1576 +0x10b
created by testing.(*F).Fuzz.func1
C:/Users/Alexander/sdk/go1.20.2/src/testing/fuzz.go:322 +0x5b9
Failing input written to testdata\fuzz\FuzzTransactionIdResponseUnmarshal\02d35f38fb554e01
To re-run:
go test -run=FuzzTransactionIdResponseUnmarshal/02d35f38fb554e01
FAIL
exit status 1
FAIL bitbucket/4suites/4suites-fc-messages 8.208s
sorry, i cannot reproduce it.
sorry, i cannot reproduce it.
I tried to on my PC running windows 11. It fails maximum in 40 seconds. Also I tried on my Macbook Pro 2015 running macOS 12.6.3. Iе fell in 330 seconds. Maybe it's platform specific?
I confirmed this issue. Maybe it is a concurrency problem.
I confirmed this issue. Maybe it is a concurrency problem.
yeah, it could be, because issues relates to RuntimeContextBuffer which is stored in sync.Pool and fuzz testing launches in my case 16 workers