• Kirill Smelkov's avatar
    decoder: Fix panic on dict with non-comparable keys · cdd8269c
    Kirill Smelkov authored
    Even though we tried to catch whether dict keys are ok to be used via
    reflect.TypeOf(key).Comparable() (see da5f0342 "decoder: Fix crashes
    found by fuzzer (#32)"), that turned out to be not enough. For example
    if key is a struct, e.g. of the following type
    
    	type Ref struct {
    		Pid interface{}
    	}
    
    it will be comparable. But the comparision, depending on dynamic .Pid
    type, might panic. This is what was actually cauht by fuzz-testing
    recently:
    
    	https://github.com/kisielk/og-rek/issues/50 (second part of the report)
    
    So instead of recursively walking a key type and checking each subfield
    with reflect.TypeOf().Comparable(), switch for using panic/recover for
    detecting the "unhashable key" situation.
    
    This slows down decoding a bit (only cumulative figure for all-test-vectors decoding):
    
    	name          old time/op    new time/op    delta
    	DecodeLong-4     361ns ± 0%     362ns ± 0%    ~     (p=0.238 n=5+4)
    	Decode-4        93.2µs ± 0%    95.6µs ± 0%  +2.54%  (p=0.008 n=5+5)
    	Encode-4        16.5µs ± 0%    16.6µs ± 0%    ~     (p=0.841 n=5+5)
    
    but that is the price of correctness. And with manually recursively walking key
    type I doubt it would be faster.
    
    The defer overhead should be less once https://github.com/golang/go/issues/14939 is fixed.
    
    Updates: https://github.com/kisielk/og-rek/issues/30
    cdd8269c
ogorek.go 28 KB