eProsima / Fast-DDS

The most complete DDS - Proven: Plenty of success cases. Looking for commercial support? Contact info@eprosima.com
https://eprosima.com
Apache License 2.0
2.04k stars 730 forks source link

Deserialization error when XCDR2 and mutable (PL) for member sizes 3, 5, 6 or 7 bytes #4968

Open i-and opened 2 weeks ago

i-and commented 2 weeks ago

Is there an already existing issue for this?

Expected behavior

Receiving data of any size.

Current behavior

For this variant of encoding and member sizes, data is not accepted (discarded).

Steps to reproduce

The HelloWorldExample was used to reproduce this situation (see the patch below). Debugging output has also been added to the stack code. The issue occurs when the size of the array octets of structure HelloWorld from the IDL is 3, 5, 6 or 7.

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorld.cxx b/examples/cpp/dds/HelloWorldExample/HelloWorld.cxx
index 4b415d677..323816a09 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorld.cxx
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorld.cxx
@@ -52,6 +52,9 @@ HelloWorld::~HelloWorld()
 HelloWorld::HelloWorld(
         const HelloWorld& x)
 {
+    m_o1 = x.m_o1;
+    m_octets = x.m_octets;
+    m_o2 = x.m_o2;
     m_index = x.m_index;
     m_message = x.m_message;
 }
@@ -59,6 +62,9 @@ HelloWorld::HelloWorld(
 HelloWorld::HelloWorld(
         HelloWorld&& x) noexcept
 {
+    m_o1 = x.m_o1;
+    m_octets = std::move(x.m_octets);
+    m_o2 = x.m_o2;
     m_index = x.m_index;
     m_message = std::move(x.m_message);
 }
@@ -67,6 +73,9 @@ HelloWorld& HelloWorld::operator =(
         const HelloWorld& x)
 {

+    m_o1 = x.m_o1;
+    m_octets = x.m_octets;
+    m_o2 = x.m_o2;
     m_index = x.m_index;
     m_message = x.m_message;
     return *this;
@@ -76,6 +85,9 @@ HelloWorld& HelloWorld::operator =(
         HelloWorld&& x) noexcept
 {

+    m_o1 = x.m_o1;
+    m_octets = std::move(x.m_octets);
+    m_o2 = x.m_o2;
     m_index = x.m_index;
     m_message = std::move(x.m_message);
     return *this;
@@ -84,7 +96,10 @@ HelloWorld& HelloWorld::operator =(
 bool HelloWorld::operator ==(
         const HelloWorld& x) const
 {
-    return (m_index == x.m_index &&
+    return (m_o1 == x.m_o1 &&
+           m_octets == x.m_octets &&
+           m_o2 == x.m_o2 &&
+           m_index == x.m_index &&
            m_message == x.m_message);
 }

@@ -94,6 +109,103 @@ bool HelloWorld::operator !=(
     return !(*this == x);
 }

+/*!
+ * @brief This function sets a value in member o1
+ * @param _o1 New value for member o1
+ */
+void HelloWorld::o1(
+        uint8_t _o1)
+{
+    m_o1 = _o1;
+}
+
+/*!
+ * @brief This function returns the value of member o1
+ * @return Value of member o1
+ */
+uint8_t HelloWorld::o1() const
+{
+    return m_o1;
+}
+
+/*!
+ * @brief This function returns a reference to member o1
+ * @return Reference to member o1
+ */
+uint8_t& HelloWorld::o1()
+{
+    return m_o1;
+}
+
+
+/*!
+ * @brief This function copies the value in member octets
+ * @param _octets New value to be copied in member octets
+ */
+void HelloWorld::octets(
+        const std::array<uint8_t, 3>& _octets)
+{
+    m_octets = _octets;
+}
+
+/*!
+ * @brief This function moves the value in member octets
+ * @param _octets New value to be moved in member octets
+ */
+void HelloWorld::octets(
+        std::array<uint8_t, 3>&& _octets)
+{
+    m_octets = std::move(_octets);
+}
+
+/*!
+ * @brief This function returns a constant reference to member octets
+ * @return Constant reference to member octets
+ */
+const std::array<uint8_t, 3>& HelloWorld::octets() const
+{
+    return m_octets;
+}
+
+/*!
+ * @brief This function returns a reference to member octets
+ * @return Reference to member octets
+ */
+std::array<uint8_t, 3>& HelloWorld::octets()
+{
+    return m_octets;
+}
+
+
+/*!
+ * @brief This function sets a value in member o2
+ * @param _o2 New value for member o2
+ */
+void HelloWorld::o2(
+        uint8_t _o2)
+{
+    m_o2 = _o2;
+}
+
+/*!
+ * @brief This function returns the value of member o2
+ * @return Value of member o2
+ */
+uint8_t HelloWorld::o2() const
+{
+    return m_o2;
+}
+
+/*!
+ * @brief This function returns a reference to member o2
+ * @return Reference to member o2
+ */
+uint8_t& HelloWorld::o2()
+{
+    return m_o2;
+}
+
+
 /*!
  * @brief This function sets a value in member index
  * @param _index New value for member index
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorld.h b/examples/cpp/dds/HelloWorldExample/HelloWorld.h
index 5cd0ddba5..72526fff7 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorld.h
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorld.h
@@ -135,6 +135,73 @@ public:
     eProsima_user_DllExport bool operator !=(
             const HelloWorld& x) const;

+    /*!
+     * @brief This function sets a value in member o1
+     * @param _o1 New value for member o1
+     */
+    eProsima_user_DllExport void o1(
+            uint8_t _o1);
+
+    /*!
+     * @brief This function returns the value of member o1
+     * @return Value of member o1
+     */
+    eProsima_user_DllExport uint8_t o1() const;
+
+    /*!
+     * @brief This function returns a reference to member o1
+     * @return Reference to member o1
+     */
+    eProsima_user_DllExport uint8_t& o1();
+
+
+    /*!
+     * @brief This function copies the value in member octets
+     * @param _octets New value to be copied in member octets
+     */
+    eProsima_user_DllExport void octets(
+            const std::array<uint8_t, 3>& _octets);
+
+    /*!
+     * @brief This function moves the value in member octets
+     * @param _octets New value to be moved in member octets
+     */
+    eProsima_user_DllExport void octets(
+            std::array<uint8_t, 3>&& _octets);
+
+    /*!
+     * @brief This function returns a constant reference to member octets
+     * @return Constant reference to member octets
+     */
+    eProsima_user_DllExport const std::array<uint8_t, 3>& octets() const;
+
+    /*!
+     * @brief This function returns a reference to member octets
+     * @return Reference to member octets
+     */
+    eProsima_user_DllExport std::array<uint8_t, 3>& octets();
+
+
+    /*!
+     * @brief This function sets a value in member o2
+     * @param _o2 New value for member o2
+     */
+    eProsima_user_DllExport void o2(
+            uint8_t _o2);
+
+    /*!
+     * @brief This function returns the value of member o2
+     * @return Value of member o2
+     */
+    eProsima_user_DllExport uint8_t o2() const;
+
+    /*!
+     * @brief This function returns a reference to member o2
+     * @return Reference to member o2
+     */
+    eProsima_user_DllExport uint8_t& o2();
+
+
     /*!
      * @brief This function sets a value in member index
      * @param _index New value for member index
@@ -183,6 +250,9 @@ public:

 private:

+    uint8_t m_o1{0};
+    std::array<uint8_t, 3> m_octets{0};
+    uint8_t m_o2{0};
     uint32_t m_index{0};
     std::string m_message;

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorld.idl b/examples/cpp/dds/HelloWorldExample/HelloWorld.idl
index 0fd2c355a..84e2e039b 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorld.idl
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorld.idl
@@ -1,5 +1,11 @@
+@mutable
 struct HelloWorld
 {
+        octet o1;
+// When size 3,5,6 or 7 - deserialize fail.
+        octet octets[3];
+        octet o2;
+
    unsigned long index;
    string message;
 };
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.hpp b/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.hpp
index 9f346d306..2392b6b1c 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.hpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.hpp
@@ -24,7 +24,7 @@

 #include "HelloWorld.h"

-constexpr uint32_t HelloWorld_max_cdr_typesize {268UL};
+constexpr uint32_t HelloWorld_max_cdr_typesize {316UL};
 constexpr uint32_t HelloWorld_max_key_cdr_typesize {0UL};

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.ipp b/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.ipp
index 42e91f3cc..1e7a3dac6 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.ipp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldCdrAux.ipp
@@ -47,15 +47,24 @@ eProsima_user_DllExport size_t calculate_serialized_size(
     eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding();
     size_t calculated_size {calculator.begin_calculate_type_serialized_size(
                                 eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ?
-                                eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 :
-                                eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR,
+                                eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR2 :
+                                eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR,
                                 current_alignment)};

-        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0),
+        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0x00000000),
+                data.o1(), current_alignment);
+
+        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0x00000001),
+                data.octets(), current_alignment);
+
+        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0x00000002),
+                data.o2(), current_alignment);
+
+        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0x00000003),
                 data.index(), current_alignment);

-        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1),
+        calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0x00000004),
                 data.message(), current_alignment);

@@ -72,12 +81,15 @@ eProsima_user_DllExport void serialize(
     eprosima::fastcdr::Cdr::state current_state(scdr);
     scdr.begin_serialize_type(current_state,
             eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ?
-            eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 :
-            eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR);
+            eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR2 :
+            eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR);

     scdr
-        << eprosima::fastcdr::MemberId(0) << data.index()
-        << eprosima::fastcdr::MemberId(1) << data.message()
+        << eprosima::fastcdr::MemberId(0x00000000) << data.o1()
+        << eprosima::fastcdr::MemberId(0x00000001) << data.octets()
+        << eprosima::fastcdr::MemberId(0x00000002) << data.o2()
+        << eprosima::fastcdr::MemberId(0x00000003) << data.index()
+        << eprosima::fastcdr::MemberId(0x00000004) << data.message()
 ;
     scdr.end_serialize_type(current_state);
 }
@@ -88,18 +100,30 @@ eProsima_user_DllExport void deserialize(
         HelloWorld& data)
 {
     cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ?
-            eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 :
-            eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR,
+            eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR2 :
+            eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR,
             [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool
             {
                 bool ret_value = true;
                 switch (mid.id)
                 {
-                                        case 0:
+                                        case 0x00000000:
+                                                dcdr >> data.o1();
+                                            break;
+
+                                        case 0x00000001:
+                                                dcdr >> data.octets();
+                                            break;
+
+                                        case 0x00000002:
+                                                dcdr >> data.o2();
+                                            break;
+
+                                        case 0x00000003:
                                                 dcdr >> data.index();
                                             break;

-                                        case 1:
+                                        case 0x00000004:
                                                 dcdr >> data.message();
                                             break;

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldPubSubTypes.cxx b/examples/cpp/dds/HelloWorldExample/HelloWorldPubSubTypes.cxx
index 85cb47789..fffb5b5c9 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldPubSubTypes.cxx
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldPubSubTypes.cxx
@@ -73,8 +73,8 @@ bool HelloWorldPubSubType::serialize(
 #if FASTCDR_VERSION_MAJOR > 1
     ser.set_encoding_flag(
         data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ?
-        eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR  :
-        eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2);
+        eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR :
+        eprosima::fastcdr::EncodingAlgorithmFlag::PL_CDR2);
 #endif // FASTCDR_VERSION_MAJOR > 1

     try
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
index 86f3e0009..42d040a3d 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldPublisher.cpp
@@ -44,6 +44,11 @@ bool HelloWorldPublisher::init(
 {
     hello_.index(0);
     hello_.message("HelloWorld");
+    hello_.o1() = 0x01;
+    for(size_t i = 0; i < hello_.octets().size(); ++i) {
+      hello_.octets()[i] = 0x10 + i;
+    }
+    hello_.o2() = 0x02;
     DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
     pqos.name("Participant_pub");
     auto factory = DomainParticipantFactory::get_instance();
@@ -106,6 +111,7 @@ bool HelloWorldPublisher::init(
     {
         publisher_->get_default_datawriter_qos(wqos);
     }
+    wqos.representation().m_value.push_back(XCDR2_DATA_REPRESENTATION);

     writer_ = publisher_->create_datawriter(
         topic_,
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
index 6823a32f4..b2586a479 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldSubscriber.cpp
@@ -106,6 +106,8 @@ bool HelloWorldSubscriber::init(
         subscriber_->get_default_datareader_qos(rqos);
     }

+    rqos.type_consistency().representation.m_value.push_back(XCDR2_DATA_REPRESENTATION);
+
     reader_ = subscriber_->create_datareader(topic_, rqos, &listener_);

     if (reader_ == nullptr)
@@ -158,14 +160,26 @@ void HelloWorldSubscriber::SubListener::on_data_available(
         DataReader* reader)
 {
     SampleInfo info;
-    if (reader->take_next_sample(&hello_, &info) == ReturnCode_t::RETCODE_OK)
+    auto res = reader->take_next_sample(&hello_, &info);
+    if (res == ReturnCode_t::RETCODE_OK)
     {
         if (info.instance_state == ALIVE_INSTANCE_STATE)
         {
             samples_++;
             // Print your structure data here.
-            std::cout << "Message " << hello_.message() << " " << hello_.index() << " RECEIVED" << std::endl;
+            std::cout << "Message " << hello_.message() << " " << hello_.index() << 
+            " o1=" << (int)hello_.o1();
+            for(size_t i = 0; i < hello_.octets().size(); ++i) {
+                std::cout << " octets[" << i << "]=" << (int)hello_.octets()[i];
+            }
+            std::cout << " o2=" << (int)hello_.o2() <<
+            " RECEIVED" << std::endl;
         }
+    } 
+    else 
+    {
+        std::cout << "Error when take_next_sample() in the HelloWorldSubscriber::SubListener::on_data_available() code=" <<
+                res() << std::endl;
     }
 }

diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp b/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
index 35870eb67..bcaebd3cd 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorld_main.cpp
@@ -291,6 +291,8 @@ int main(
         }
     }

+    Log::SetVerbosity(Log::Kind::Warning);
+
     switch (type)
     {
         case 1:
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldv1.cxx b/examples/cpp/dds/HelloWorldExample/HelloWorldv1.cxx
index 90e82ea88..25fdb9cc2 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldv1.cxx
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldv1.cxx
@@ -83,13 +83,19 @@ struct FindType {
 };
 }

-#define HelloWorld_max_cdr_typesize 268ULL;
+#define HelloWorld_max_cdr_typesize 316ULL;

 HelloWorld::HelloWorld()
 {
+    // octet m_o1
+    m_o1 = 0;
+    // octet m_octets
+    memset(&m_octets, 0, ((3)) * 1);
+    // octet m_o2
+    m_o2 = 0;
     // unsigned long m_index
     m_index = 0;
     // /type_d() m_message
@@ -104,6 +110,15 @@ HelloWorld::~HelloWorld()
 HelloWorld::HelloWorld(
         const HelloWorld& x)
 {
+    m_o1 = x.m_o1;
+
+
+    m_octets = x.m_octets;
+
+
+    m_o2 = x.m_o2;
+
+
     m_index = x.m_index;

@@ -114,6 +129,15 @@ HelloWorld::HelloWorld(
 HelloWorld::HelloWorld(
         HelloWorld&& x) noexcept
 {
+    m_o1 = x.m_o1;
+
+
+    m_octets = std::move(x.m_octets);
+
+
+    m_o2 = x.m_o2;
+
+
     m_index = x.m_index;

@@ -124,6 +148,15 @@ HelloWorld::HelloWorld(
 HelloWorld& HelloWorld::operator =(
         const HelloWorld& x)
 {
+    m_o1 = x.m_o1;
+
+
+    m_octets = x.m_octets;
+
+
+    m_o2 = x.m_o2;
+
+
     m_index = x.m_index;

@@ -135,6 +168,15 @@ HelloWorld& HelloWorld::operator =(
 HelloWorld& HelloWorld::operator =(
         HelloWorld&& x) noexcept
 {
+    m_o1 = x.m_o1;
+
+
+    m_octets = std::move(x.m_octets);
+
+
+    m_o2 = x.m_o2;
+
+
     m_index = x.m_index;

@@ -146,7 +188,10 @@ HelloWorld& HelloWorld::operator =(
 bool HelloWorld::operator ==(
         const HelloWorld& x) const
 {
-    return (m_index == x.m_index &&
+    return (m_o1 == x.m_o1 &&
+           m_octets == x.m_octets &&
+           m_o2 == x.m_o2 &&
+           m_index == x.m_index &&
            m_message == x.m_message);
 }

@@ -170,6 +215,16 @@ size_t HelloWorld::getCdrSerializedSize(
     (void)data;
     size_t initial_alignment = current_alignment;

+    current_alignment += 1 + eprosima::fastcdr::Cdr::alignment(current_alignment, 1);
+
+
+    current_alignment += (((3)) * 1) + eprosima::fastcdr::Cdr::alignment(current_alignment, 1);
+
+
+
+    current_alignment += 1 + eprosima::fastcdr::Cdr::alignment(current_alignment, 1);
+
+
     current_alignment += 4 + eprosima::fastcdr::Cdr::alignment(current_alignment, 4);

@@ -183,6 +238,13 @@ size_t HelloWorld::getCdrSerializedSize(
 void HelloWorld::serialize(
         eprosima::fastcdr::Cdr& scdr) const
 {
+    scdr << m_o1;
+
+    scdr << m_octets;
+
+
+    scdr << m_o2;
+
     scdr << m_index;

     scdr << m_message.c_str();
@@ -192,6 +254,18 @@ void HelloWorld::serialize(
 void HelloWorld::deserialize(
         eprosima::fastcdr::Cdr& dcdr)
 {
+    dcdr >> m_o1;
+
+
+
+    dcdr >> m_octets;
+
+
+
+    dcdr >> m_o2;
+
+
+
     dcdr >> m_index;

@@ -213,6 +287,103 @@ void HelloWorld::serializeKey(
     (void) scdr;
 }

+/*!
+ * @brief This function sets a value in member o1
+ * @param _o1 New value for member o1
+ */
+void HelloWorld::o1(
+        uint8_t _o1)
+{
+    m_o1 = _o1;
+}
+
+/*!
+ * @brief This function returns the value of member o1
+ * @return Value of member o1
+ */
+uint8_t HelloWorld::o1() const
+{
+    return m_o1;
+}
+
+/*!
+ * @brief This function returns a reference to member o1
+ * @return Reference to member o1
+ */
+uint8_t& HelloWorld::o1()
+{
+    return m_o1;
+}
+
+
+/*!
+ * @brief This function copies the value in member octets
+ * @param _octets New value to be copied in member octets
+ */
+void HelloWorld::octets(
+        const std::array<uint8_t, 3>& _octets)
+{
+    m_octets = _octets;
+}
+
+/*!
+ * @brief This function moves the value in member octets
+ * @param _octets New value to be moved in member octets
+ */
+void HelloWorld::octets(
+        std::array<uint8_t, 3>&& _octets)
+{
+    m_octets = std::move(_octets);
+}
+
+/*!
+ * @brief This function returns a constant reference to member octets
+ * @return Constant reference to member octets
+ */
+const std::array<uint8_t, 3>& HelloWorld::octets() const
+{
+    return m_octets;
+}
+
+/*!
+ * @brief This function returns a reference to member octets
+ * @return Reference to member octets
+ */
+std::array<uint8_t, 3>& HelloWorld::octets()
+{
+    return m_octets;
+}
+
+
+/*!
+ * @brief This function sets a value in member o2
+ * @param _o2 New value for member o2
+ */
+void HelloWorld::o2(
+        uint8_t _o2)
+{
+    m_o2 = _o2;
+}
+
+/*!
+ * @brief This function returns the value of member o2
+ * @return Value of member o2
+ */
+uint8_t HelloWorld::o2() const
+{
+    return m_o2;
+}
+
+/*!
+ * @brief This function returns a reference to member o2
+ * @return Reference to member o2
+ */
+uint8_t& HelloWorld::o2()
+{
+    return m_o2;
+}
+
+
 /*!
  * @brief This function sets a value in member index
  * @param _index New value for member index
diff --git a/examples/cpp/dds/HelloWorldExample/HelloWorldv1.h b/examples/cpp/dds/HelloWorldExample/HelloWorldv1.h
index 9f6f726e0..75675a453 100644
--- a/examples/cpp/dds/HelloWorldExample/HelloWorldv1.h
+++ b/examples/cpp/dds/HelloWorldExample/HelloWorldv1.h
@@ -131,6 +131,73 @@ public:
     eProsima_user_DllExport bool operator !=(
             const HelloWorld& x) const;

+    /*!
+     * @brief This function sets a value in member o1
+     * @param _o1 New value for member o1
+     */
+    eProsima_user_DllExport void o1(
+            uint8_t _o1);
+
+    /*!
+     * @brief This function returns the value of member o1
+     * @return Value of member o1
+     */
+    eProsima_user_DllExport uint8_t o1() const;
+
+    /*!
+     * @brief This function returns a reference to member o1
+     * @return Reference to member o1
+     */
+    eProsima_user_DllExport uint8_t& o1();
+
+
+    /*!
+     * @brief This function copies the value in member octets
+     * @param _octets New value to be copied in member octets
+     */
+    eProsima_user_DllExport void octets(
+            const std::array<uint8_t, 3>& _octets);
+
+    /*!
+     * @brief This function moves the value in member octets
+     * @param _octets New value to be moved in member octets
+     */
+    eProsima_user_DllExport void octets(
+            std::array<uint8_t, 3>&& _octets);
+
+    /*!
+     * @brief This function returns a constant reference to member octets
+     * @return Constant reference to member octets
+     */
+    eProsima_user_DllExport const std::array<uint8_t, 3>& octets() const;
+
+    /*!
+     * @brief This function returns a reference to member octets
+     * @return Reference to member octets
+     */
+    eProsima_user_DllExport std::array<uint8_t, 3>& octets();
+
+
+    /*!
+     * @brief This function sets a value in member o2
+     * @param _o2 New value for member o2
+     */
+    eProsima_user_DllExport void o2(
+            uint8_t _o2);
+
+    /*!
+     * @brief This function returns the value of member o2
+     * @return Value of member o2
+     */
+    eProsima_user_DllExport uint8_t o2() const;
+
+    /*!
+     * @brief This function returns a reference to member o2
+     * @return Reference to member o2
+     */
+    eProsima_user_DllExport uint8_t& o2();
+
+
     /*!
      * @brief This function sets a value in member index
      * @param _index New value for member index
@@ -231,6 +298,9 @@ public:

 private:

+    uint8_t m_o1;
+    std::array<uint8_t, 3> m_octets;
+    uint8_t m_o2;
     uint32_t m_index;
     std::string m_message;

diff --git a/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp b/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp
index 8b0e49e95..f3b6180aa 100644
--- a/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp
+++ b/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp
@@ -344,6 +344,8 @@ private:
             {
                 if (!deserialize_sample(item))
                 {
+                    EPROSIMA_LOG_ERROR(RTPS_READER,
+                            "Error deserialize_sample() for change " << item->sequenceNumber << " from " << item->writerGUID << std::endl);
                     // Decrement length of collections
                     data_values_.length(current_slot_);
                     sample_infos_.length(current_slot_);

Fast DDS version/commit

v2.14.1

Platform/Architecture

Ubuntu Focal 20.04 amd64

Transport layer

Default configuration, UDPv4 & SHM

Additional context

No response

XML configuration file

No response

Relevant log output

Starting 
Subscriber running. Please press enter to stop the Subscriber
Subscriber matched.
2024-06-18 20:44:51.746 [RTPS_READER Error] Error deserialize_sample() for change 2 from 01.0f.4e.06.e5.d5.1e.bc.00.00.00.00|0.0.1.3
 -> Function add_sample
Error when take_next_sample() in the HelloWorldSubscriber::SubListener::on_data_available() code=11
Error when take_next_sample() in the HelloWorldSubscriber::SubListener::on_data_available() code=11
2024-06-18 20:44:52.746 [RTPS_READER Error] Error deserialize_sample() for change 3 from 01.0f.4e.06.e5.d5.1e.bc.00.00.00.00|0.0.1.3
 -> Function add_sample
Error when take_next_sample() in the HelloWorldSubscriber::SubListener::on_data_available() code=11
2024-06-18 20:44:53.747 [RTPS_READER Error] Error deserialize_sample() for change 4 from 01.0f.4e.06.e5.d5.1e.bc.00.00.00.00|0.0.1.3
 -> Function add_sample
Error when take_next_sample() in the HelloWorldSubscriber::SubListener::on_data_available() code=11
.....................

Network traffic capture

No response

elianalf commented 2 weeks ago

Hi @i-and, thanks for reporting.

Most likely, there is a bug in the deserialization when the extensibility of the message type is MUTABLE. I will label this issue as a bug and we will review the serialization and deserialization in case the type is not FINAL. In the meantime, you can always use the type as FINAL.