diff --git a/CHANGES b/CHANGES index 55437f7d4d..3b836aa937 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5.2.0-dev.478 | 2023-01-12 09:41:11 +0100 + + * fix for crashes when record definitions repeat a field name (Vern Paxson, Corelight) + 5.2.0-dev.476 | 2023-01-11 17:00:32 -0800 * CI updates (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index 4333777ac7..c5ef0d88ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.2.0-dev.476 +5.2.0-dev.478 diff --git a/src/Type.cc b/src/Type.cc index f9857fe9cb..e4dc489ba7 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1062,22 +1062,25 @@ void RecordType::AddField(unsigned int field, const TypeDecl* td) ASSERT(field == field_inits.size()); ASSERT(field == managed_fields.size()); - if ( field_ids.count(td->id) != 0 ) - { - reporter->Error("Duplicate field '%s' found in record definition\n", td->id); - return; - } - else - { - field_ids.insert(std::string(td->id)); - } - managed_fields.push_back(ZVal::IsManagedType(td->type)); auto init = new FieldInit(); init->init_type = FieldInit::R_INIT_NONE; init->attrs = td->attrs; + + // We defer error-checking until here so that we can keep field_inits + // and managed_fields correctly tracking the associated fields. + + if ( field_ids.count(td->id) != 0 ) + { + reporter->Error("duplicate field '%s' found in record definition", td->id); + field_inits.push_back(init); + return; + } + + field_ids.insert(std::string(td->id)); + auto a = init->attrs; auto type = td->type; @@ -1335,7 +1338,7 @@ void RecordType::Create(std::vector>& r) const for ( int i = 0; i < n; ++i ) { - auto& init = field_inits[i]; + auto* init = field_inits[i]; ZVal r_i; diff --git a/testing/btest/Baseline/language.record-duplicate-fields/.stderr b/testing/btest/Baseline/language.record-duplicate-fields/.stderr index 6f006bb79d..01cf21966a 100644 --- a/testing/btest/Baseline/language.record-duplicate-fields/.stderr +++ b/testing/btest/Baseline/language.record-duplicate-fields/.stderr @@ -1,3 +1,7 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/record-duplicate-fields.zeek, line 7: Duplicate field 'a' found in record definition - +error in <...>/record-duplicate-fields.zeek, line 7: duplicate field 'a' found in record definition +error in <...>/record-duplicate-fields.zeek, line 17: duplicate field 'a' found in record definition +error in <...>/record-duplicate-fields.zeek, line 23: duplicate field 'a' found in record definition +error in <...>/record-duplicate-fields.zeek, line 32: duplicate field 'a' found in record definition +error in <...>/record-duplicate-fields.zeek, line 32: duplicate field 'b' found in record definition +error in <...>/record-duplicate-fields.zeek, line 32: duplicate field 'a' found in record definition diff --git a/testing/btest/language/record-duplicate-fields.zeek b/testing/btest/language/record-duplicate-fields.zeek index 4991572b8e..b2303c9f14 100644 --- a/testing/btest/language/record-duplicate-fields.zeek +++ b/testing/btest/language/record-duplicate-fields.zeek @@ -6,8 +6,39 @@ type test: record { a: string &optional; }; +type r1: record { + a: count; + b: count; +}; + +type r2: record { + a: count; + a: count; +}; + +type r3: record { + b: count; + a: count; + a: count; +}; + +type r4: record { + a: count; + b: count; + a: count; + b: count; + a: count; + c: count; +}; + +global x1: r1; +global x2: r2; +global x3: r3; +global x4: r4; + event zeek_init() { local a = test($a=5); print a; + print x1, x2, x3, x4; }