From 9cc8e1ba941e63621f83690a09b6e441a14f7547 Mon Sep 17 00:00:00 2001 From: mohammed arib Date: Fri, 17 Jul 2026 14:01:14 +0530 Subject: [PATCH] bounds-check reader default value lookup in schema resolution --- lang/c++/include/avro/NodeImpl.hh | 3 +++ lang/c++/test/SchemaTests.cc | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lang/c++/include/avro/NodeImpl.hh b/lang/c++/include/avro/NodeImpl.hh index 2038c9d5ce7..9297d419489 100644 --- a/lang/c++/include/avro/NodeImpl.hh +++ b/lang/c++/include/avro/NodeImpl.hh @@ -341,6 +341,9 @@ public: } const GenericDatum &defaultValueAt(size_t index) override { + if (index >= fieldsDefaultValues_.size()) { + throw Exception("No default value at: {}", index); + } return fieldsDefaultValues_[index]; } diff --git a/lang/c++/test/SchemaTests.cc b/lang/c++/test/SchemaTests.cc index 2aa39d4146e..bddf396b3b2 100644 --- a/lang/c++/test/SchemaTests.cc +++ b/lang/c++/test/SchemaTests.cc @@ -17,8 +17,10 @@ */ #include "Compiler.hh" +#include "Decoder.hh" #include "GenericDatum.hh" #include "NodeImpl.hh" +#include "Schema.hh" #include "ValidSchema.hh" #include @@ -924,6 +926,23 @@ static void testCustomAttributesSchema2Json2Schema() { } } +// A reader record built with the programmatic API (RecordSchema::addField) +// carries no default values, so fieldsDefaultValues_ is empty. When the writer +// schema omits a field the reader declares, resolution asks the reader for that +// field's default and previously indexed the empty vector out of bounds. It must +// throw instead. +void testResolveReaderFieldWithoutDefault() { + ValidSchema writer = compileJsonSchemaFromString( + R"({"type":"record","name":"R","fields":[{"name":"a","type":"int"}]})"); + + RecordSchema readerRecord("R"); + readerRecord.addField("a", IntSchema()); + readerRecord.addField("b", IntSchema()); + ValidSchema reader(readerRecord); + + BOOST_CHECK_THROW(resolvingDecoder(writer, reader, binaryDecoder()), Exception); +} + } // namespace schema } // namespace avro @@ -952,5 +971,6 @@ init_unit_test_suite(int /*argc*/, char * /*argv*/[]) { ts->add(BOOST_TEST_CASE(&avro::schema::testAddCustomAttributes)); ts->add(BOOST_TEST_CASE(&avro::schema::testCustomAttributesJson2Schema2Json)); ts->add(BOOST_TEST_CASE(&avro::schema::testCustomAttributesSchema2Json2Schema)); + ts->add(BOOST_TEST_CASE(&avro::schema::testResolveReaderFieldWithoutDefault)); return ts; }