Skip to content

Commit 200f0dd

Browse files
XCDRv1: support extra bytes in optional types (#285) (#286)
* Refs #23838. Regression test * Refs #23838. Fix * Refs #23838. Apply suggestions --------- (cherry picked from commit 486ce90) Signed-off-by: Ricardo González Moreno <[email protected]> Co-authored-by: Ricardo González <[email protected]>
1 parent 7f56d28 commit 200f0dd

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

include/fastcdr/Cdr.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,11 +2731,16 @@ class Cdr
27312731
{
27322732
deserialize(member_value);
27332733
}
2734-
if (current_state.member_size_ != offset_ - prev_offset)
2734+
size_t member_size {current_state.member_size_};
2735+
size_t diff {offset_ - prev_offset};
2736+
if (member_size < diff)
27352737
{
27362738
throw exception::BadParamException(
2737-
"Member size provided by member header is not equal to the real decoded member size");
2739+
"Member size provided by member header is lower than real decoded member size");
27382740
}
2741+
2742+
// Skip unused bytes
2743+
offset_ += (member_size - diff);
27392744
}
27402745
else
27412746
{

test/xcdr/xcdrv1.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,57 @@ INSTANTIATE_TEST_SUITE_P(
460460
Cdr::XCdrHeaderSelection::AUTO_WITH_SHORT_HEADER_BY_DEFAULT,
461461
Cdr::XCdrHeaderSelection::AUTO_WITH_LONG_HEADER_BY_DEFAULT
462462
));
463+
464+
/*!
465+
* @test Regression test for optional string with extra alignment sent by RTI (#23838)
466+
* @code{.idl}
467+
* struct OptinalStringWithExtraAlignment
468+
* {
469+
* @optional string<100> str;
470+
* unsigned short value;
471+
* };
472+
* @endcode
473+
*/
474+
TEST(XCdrTest, optional_string_with_extra_alignment)
475+
{
476+
std::array<char, 18> fail_case_buffer {
477+
0x00, 0x01, 0x00, 0x00, // Encapsulation
478+
0x00, 0x00, 0x08, 0x00, // ShortMemberHeader
479+
0x03, 0x00, 0x00, 0x00, // String length
480+
0x41, 0x42, 0x00, // String
481+
0x00, // Extra alignment byte
482+
0x30, 0x00 // Short
483+
};
484+
485+
EncodingAlgorithmFlag encoding = EncodingAlgorithmFlag::PLAIN_CDR;
486+
Cdr::Endianness endianness = Cdr::Endianness::LITTLE_ENDIANNESS;
487+
FastBuffer fast_buffer(fail_case_buffer.data(), fail_case_buffer.size());
488+
Cdr cdr(fast_buffer, endianness, CdrVersion::XCDRv1);
489+
cdr.read_encapsulation();
490+
ASSERT_EQ(cdr.get_encoding_flag(), encoding);
491+
ASSERT_EQ(cdr.endianness(), endianness);
492+
493+
optional<fixed_string<100>> dvalue;
494+
uint16_t short_dvalue {0};
495+
cdr.deserialize_type(encoding, [&](Cdr& cdr_inner, const MemberId& mid)->bool
496+
{
497+
bool ret_value = true;
498+
499+
switch (mid.id)
500+
{
501+
case 0:
502+
cdr_inner >> dvalue;
503+
break;
504+
case 1:
505+
cdr_inner >> short_dvalue;
506+
break;
507+
default:
508+
ret_value = false;
509+
}
510+
511+
return ret_value;
512+
});
513+
ASSERT_TRUE(dvalue.has_value());
514+
ASSERT_STREQ("AB", dvalue.value());
515+
ASSERT_EQ(0x30, short_dvalue);
516+
}

0 commit comments

Comments
 (0)