Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lang/ruby/lib/avro/io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ def read_fixed(writers_schema, _readers_schema, decoder)

def read_enum(writers_schema, readers_schema, decoder)
index_of_symbol = decoder.read_int
if index_of_symbol < 0 || index_of_symbol >= writers_schema.symbols.size
raise AvroError, "Enum symbol index out of range: #{index_of_symbol}"
end
read_symbol = writers_schema.symbols[index_of_symbol]

if !readers_schema.symbols.include?(read_symbol) && readers_schema.default
Expand Down Expand Up @@ -351,6 +354,9 @@ def read_map(writers_schema, readers_schema, decoder)

def read_union(writers_schema, readers_schema, decoder)
index_of_schema = decoder.read_long
if index_of_schema < 0 || index_of_schema >= writers_schema.schemas.size
raise AvroError, "Union branch index out of range: #{index_of_schema}"
end
selected_writers_schema = writers_schema.schemas[index_of_schema]

read_data(selected_writers_schema, readers_schema, decoder)
Expand Down Expand Up @@ -477,6 +483,9 @@ def skip_enum(_writers_schema, decoder)

def skip_union(writers_schema, decoder)
index = decoder.read_long
if index < 0 || index >= writers_schema.schemas.size
raise AvroError, "Union branch index out of range: #{index}"
end
skip_data(writers_schema.schemas[index], decoder)
end

Expand Down
22 changes: 22 additions & 0 deletions lang/ruby/test/test_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ def test_enum_with_default
check_default(enum_schema, '"B"', "B")
end

def test_enum_index_out_of_range
enum_schema = Avro::Schema.parse('{"type": "enum", "name": "Test", "symbols": ["A", "B"]}')
# 0x01 zigzag-decodes to -1, which would wrap to the last symbol.
assert_raise(Avro::AvroError) { read_raw([0x01], enum_schema) }
# 0x06 zigzag-decodes to 3, past the two symbols.
assert_raise(Avro::AvroError) { read_raw([0x06], enum_schema) }
end

def test_union_index_out_of_range
union_schema = Avro::Schema.parse('["null", "string"]')
# 0x01 (-1) would wrap to the "string" branch; 0x0a (5) selects a nil branch.
assert_raise(Avro::AvroError) { read_raw([0x01, 0x04, 0x41, 0x42], union_schema) }
assert_raise(Avro::AvroError) { read_raw([0x0a], union_schema) }
end

def test_recursive
recursive_schema = <<EOS
{"type": "record",
Expand Down Expand Up @@ -646,4 +661,11 @@ def read_datum(buffer, writers_schema, readers_schema=nil)
datum_reader = Avro::IO::DatumReader.new(writers_schema, readers_schema)
datum_reader.read(decoder)
end

def read_raw(bytes, writers_schema, readers_schema=nil)
reader = StringIO.new(bytes.pack('C*'))
decoder = Avro::IO::BinaryDecoder.new(reader)
datum_reader = Avro::IO::DatumReader.new(writers_schema, readers_schema)
datum_reader.read(decoder)
end
end