If tuple is used directly, for example:
In [11]: s = "((tNd."
In [19]: dis(s)
0: ( MARK
1: ( MARK
2: t TUPLE (MARK at 1)
3: N NONE
4: d DICT (MARK at 0)
5: . STOP
highest protocol among opcodes = 0
In [20]: loads(s)
Out[20]: {(): None}
our Decoder gives:
pickle: loadDict: invalid key type ogórek.Tuple
However the pickle is valid by Python rules because there tuple is immutable (and thus hashable).
However the check inside Decoder is not complete - for example if we hook Tuple into another type whos is comparable (e.g. Ref here):
In [11]: s = "((tQNd."
In [15]: dis(s)
0: ( MARK
1: ( MARK
2: t TUPLE (MARK at 1)
3: Q BINPERSID
4: N NONE
5: d DICT (MARK at 0)
6: . STOP
highest protocol among opcodes = 1
our Decoder crashes:
panic: runtime error: hash of unhashable type ogórek.Tuple
goroutine 1 [running]:
github.com/kisielk/og-rek.(*Decoder).loadDict(0xc00009efd0, 0xc00000a264, 0x0)
/tmp/go-fuzz-build914098789/gopath/src/github.com/kisielk/og-rek/ogorek.go:819 +0x32b
github.com/kisielk/og-rek.(*Decoder).Decode(0xc00009efd0, 0xc00009aa10, 0xc00009efd0, 0x464f39, 0x4)
/tmp/go-fuzz-build914098789/gopath/src/github.com/kisielk/og-rek/ogorek.go:242 +0x14fa
github.com/kisielk/og-rek.Fuzz(0x7f62339cc000, 0x6, 0x200000, 0x3)
/tmp/go-fuzz-build914098789/gopath/src/github.com/kisielk/og-rek/fuzz.go:15 +0xdf
go-fuzz-dep.Main(0x524df8)
/tmp/go-fuzz-build914098789/goroot/src/go-fuzz-dep/main.go:49 +0xad
main.main()
/tmp/go-fuzz-build914098789/gopath/src/github.com/kisielk/og-rek/go.fuzz.main/main.go:10 +0x2d
exit status 2
If tuple is used directly, for example:
our Decoder gives:
However the pickle is valid by Python rules because there tuple is immutable (and thus hashable).
However the check inside Decoder is not complete - for example if we hook Tuple into another type whos is comparable (e.g. Ref here):
our Decoder crashes: