diff --git a/compiler2/record.c b/compiler2/record.c index a66dadee4d2cccd50d4ebfa8dd6913d66011af3c..6331a10b6a679cbdb7afa9a2fe2bbe99d8c54e63 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -4992,6 +4992,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) int eag_pos = 0; pos = 8; ind = 0; + boolean has_optional_in_extension = FALSE; for (i = limit; i < sdef->nElements; i++) { pos--; src = mputprintf(src, @@ -5001,6 +5002,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) eag_pos++; for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) { if (sdef->elements[sdef->oerP[j]].isOptional) { + has_optional_in_extension = TRUE; src = mputprintf(src, " field_%s = OMIT_VALUE;\n" , sdef->elements[sdef->oerP[j]].name); @@ -5009,6 +5011,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) eag_pos--; } else { if (sdef->elements[sdef->oerP[i]].isOptional) { + has_optional_in_extension = TRUE; src = mputprintf(src, " field_%s = OMIT_VALUE;\n" , sdef->elements[i].name); @@ -5071,6 +5074,18 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) ind++; } } + if (has_optional_in_extension) { + src = mputstr(src, + " }\n" + " else {\n"); + for (i = limit; i < sdef->nElements; i++) { + if (sdef->elements[sdef->oerP[i]].isOptional) { + src = mputprintf(src, + " field_%s = OMIT_VALUE;\n" + , sdef->elements[i].name); + } + } + } src = mputstr(src, " }\n"); } diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 00132ca1e66189aed42566492884f1f9423d6596..0d71670a47f1be76ecac0ca0542a508a2ee25fd4 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -6927,6 +6927,14 @@ int Record_Type::OER_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_bu } } } + else if (p_td.oer->extendable) { + // Set the optional fields after the extension to 'omit' + for (int i = limit; i < field_count; ++i) { + if (get_at(p_td.oer->p[i])->is_optional()) { + get_at(p_td.oer->p[i])->set_to_omit(); + } + } + } if (is_opentype_outermost()) { TTCN_EncDec_ErrorContext ec_1("While decoding opentypes: "); diff --git a/regression_test/OER/OER.ttcn b/regression_test/OER/OER.ttcn index 1fbe04a48d788355e4195c3e08855eca7508b658..4147ffb4382c706c4761b498443d4698d28ea47d 100644 --- a/regression_test/OER/OER.ttcn +++ b/regression_test/OER/OER.ttcn @@ -2291,7 +2291,11 @@ me := 1, me2 := 2, me3 := omit, - me4 := 4 + me4 := 4, + f2 := omit, + f4 := omit, + f5 := omit, + f7 := omit } os := enc_ExtensionRecord2(er2); if (os != '40010101020104'O) { @@ -2677,7 +2681,16 @@ if (os != '400101'O) { setverdict(fail, "tc_sequence: ", match('400101'O, os)); } - erres71 := { me := 1 } + erres71 := { + me := 1, + f2 := omit, + f4 := omit, + f5 := omit, + f6 := omit, + f7 := omit, + f9 := omit, + f_nul := omit + } erres7 := dec_ExtensionRecord5(os); if (not(match(log2str(erres7), log2str(erres71)))) { setverdict(fail, "tc_sequence: ", match(log2str(erres7), log2str(erres71))); @@ -3544,6 +3557,20 @@ } setverdict(pass); } + + external function dec_Rec533061(in octetstring stream) return Rec533061 + with { extension "prototype (convert) decode(OER)" } + + // Testing the fixes to decoding extended records made for bug 533061 + testcase tc_533061() runs on EmptyCT { + var octetstring enc := '4001010102'O; + var Rec533061 dec := dec_Rec533061(enc); + var Rec533061 dec_exp := { field1 := 1, field2 := 2, field_ext1 := omit, field_ext2 := omit }; + if (dec != dec_exp) { + setverdict(fail, "Decoding failed. Got: ", dec, ", expected: ", dec_exp); + } + setverdict(pass); + } control { execute(tc_boolean()); @@ -3565,6 +3592,7 @@ execute(tc_opentype()); execute(tc_example()); execute(tc_529017()); + execute(tc_533061()); } } diff --git a/regression_test/OER/Types.asn b/regression_test/OER/Types.asn index 53362c271cdf85aa54d2a52e9debf4e984f7dafb..bc4104d826bf79b12fde49734740aef3dd6cecb0 100644 --- a/regression_test/OER/Types.asn +++ b/regression_test/OER/Types.asn @@ -534,7 +534,14 @@ Enum529017 ::= ENUMERATED val1 } - +Rec533061 ::= SEQUENCE +{ + field1 INTEGER, + field2 INTEGER OPTIONAL, + ..., + field-ext1 INTEGER OPTIONAL, + field-ext2 REAL OPTIONAL +} END