From 6d874487073a1d7495868a1129843073b4637bb7 Mon Sep 17 00:00:00 2001 From: mohammed arib Date: Mon, 17 Aug 2026 13:27:26 +0530 Subject: [PATCH] MINOR: [ruby] reject out-of-range enum and union index --- lang/ruby/lib/avro/io.rb | 9 +++++++++ lang/ruby/test/test_io.rb | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lang/ruby/lib/avro/io.rb b/lang/ruby/lib/avro/io.rb index 091b3544672..a98f2b327b0 100644 --- a/lang/ruby/lib/avro/io.rb +++ b/lang/ruby/lib/avro/io.rb @@ -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 @@ -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) @@ -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 diff --git a/lang/ruby/test/test_io.rb b/lang/ruby/test/test_io.rb index c2b5ffc722c..ccc4f3984e5 100644 --- a/lang/ruby/test/test_io.rb +++ b/lang/ruby/test/test_io.rb @@ -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 = <