Skip to content

Commit

Permalink
Merge pull request #13 from go-avro/fuzz-fix-enum-indexes
Browse files Browse the repository at this point in the history
Fuzz Fix: decoding enums that are out of range
  • Loading branch information
crast authored Dec 19, 2017
2 parents 206af5c + 89fc7d1 commit 4441637
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
12 changes: 11 additions & 1 deletion datum_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ func (reader sDatumReader) mapEnum(field Schema, dec Decoder) (reflect.Value, er
enumIndex, err := dec.ReadEnum()
if err != nil {
return reflect.ValueOf(enumIndex), err
} else if enumIndex < 0 {
return reflect.ValueOf(enumIndex), fmt.Errorf("Enum index %d < 0 in enum %s", enumIndex, field.GetName())
}

schema := field.(*EnumSchema)
Expand All @@ -337,6 +339,10 @@ func (reader sDatumReader) mapEnum(field Schema, dec Decoder) (reflect.Value, er
}
enumSymbolsToIndexCacheLock.Unlock()

if int(enumIndex) >= len(schema.Symbols) {
return reflect.Value{}, fmt.Errorf("Enum index %d too high for enum %s", enumIndex, field.GetName())
}

enum := &GenericEnum{
Symbols: schema.Symbols,
symbolsToIndex: symbolsToIndex,
Expand Down Expand Up @@ -402,7 +408,9 @@ func (this sDatumReader) fillRecord(field Schema, record reflect.Value, dec Deco
recordSchema := field.(*RecordSchema)
//ri := record.Interface()
for i := 0; i < len(recordSchema.Fields); i++ {
this.findAndSet(record, recordSchema.Fields[i], dec)
if err := this.findAndSet(record, recordSchema.Fields[i], dec); err != nil {
return err
}
}
}
return nil
Expand Down Expand Up @@ -553,6 +561,8 @@ func (reader *GenericDatumReader) mapEnum(field Schema, dec Decoder) (*GenericEn
enumIndex, err := dec.ReadEnum()
if err != nil {
return nil, err
} else if enumIndex < 0 {
return nil, fmt.Errorf("Enum index %d < 0 in schema %s", enumIndex, field.GetName())
}

schema := field.(*EnumSchema)
Expand Down
31 changes: 31 additions & 0 deletions datum_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,37 @@ func enumRaceTest(t *testing.T, schemas []Schema) {

}

func TestEnumNegativeRegression(t *testing.T) {
var playingCard struct {
Type *GenericEnum
}
var genericDest = NewGenericRecord(schemaEnumA)
reader := NewDatumReader(schemaEnumA)

///////////
// Scenario 1: negative index

var buf = []byte{0x7} // This is the encoding of the varint -4
// Before this fix, this panicked.
err := reader.Read(genericDest, NewBinaryDecoder(buf))
assert(t, err.Error(), "Enum index -4 < 0 in schema Type")

err = reader.Read(&playingCard, NewBinaryDecoder(buf))
//assert(t, err.Error(), "Enum index -4 < 0 in schema Type")

///////////
// Scenario 2: too-large positive index

buf = []byte{0x78} // This is the encoding of the varint 60
err = reader.Read(genericDest, NewBinaryDecoder(buf))
assert(t, err.Error(), "Enum index invalid!")

playingCard.Type = nil
err = reader.Read(&playingCard, NewBinaryDecoder(buf))
assert(t, err.Error(), "Enum index 60 too high for enum Type")

}

func parallelF(numRoutines, numLoops int, f func(routine, loop int)) {
var wg sync.WaitGroup
wg.Add(numRoutines)
Expand Down

0 comments on commit 4441637

Please sign in to comment.