From 33277e7025e7b7a33db3b16073531be079976c09 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Fri, 8 Nov 2024 10:06:12 +0100 Subject: [PATCH] Fail when trying to serialize `std::string` with null characters on its content (#245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refs #21362. Add test. Signed-off-by: Miguel Company * Refs #21362. Fix Cdr behavior. Signed-off-by: Miguel Company * Refs #21362. Fix FastCDR behavior. Signed-off-by: Miguel Company * Refs #21362. Fix dll export. Signed-off-by: Miguel Company * Refs #21362. Leave implementation in header. Signed-off-by: Miguel Company * Refs #21362. Apply suggestion. Signed-off-by: Miguel Company Co-authored-by: Mario Domínguez López <116071334+Mario-DL@users.noreply.github.com> --------- Signed-off-by: Miguel Company Co-authored-by: Mario Domínguez López <116071334+Mario-DL@users.noreply.github.com> (cherry picked from commit 5cc8c55d967d88aff67a0e35ee82a4576362842d) --- include/fastcdr/Cdr.h | 18 +++++++++++++++++- include/fastcdr/FastCdr.h | 29 +++++++++++++++++++++++------ test/cdr/SimpleTest.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/include/fastcdr/Cdr.h b/include/fastcdr/Cdr.h index 33ebadbc..b0984f2d 100644 --- a/include/fastcdr/Cdr.h +++ b/include/fastcdr/Cdr.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -703,12 +704,27 @@ class Cdr * @param string_t The string that will be serialized in the buffer. * @return Reference to the eprosima::fastcdr::Cdr object. * @exception exception::NotEnoughMemoryException This exception is thrown when trying to serialize a position that exceeds the internal memory size. + * @exception exception::BadParamException This exception is thrown when trying to serialize a string with null characters. */ TEMPLATE_SPEC Cdr& serialize( const std::string& string_t) { - return serialize(string_t.c_str()); + // An empty string is serialized as a 0 length string. + if (string_t.empty()) + { + return serialize(static_cast(0)); + } + + // Check there are no null characters in the string. + const char* c_str = string_t.c_str(); + const auto str_len = strlen(c_str); + if (string_t.size() > str_len) + { + throw exception::BadParamException("The string contains null characters"); + } + + return serialize_sequence(c_str, str_len + 1); } /*! diff --git a/include/fastcdr/FastCdr.h b/include/fastcdr/FastCdr.h index d009e99c..42e73252 100644 --- a/include/fastcdr/FastCdr.h +++ b/include/fastcdr/FastCdr.h @@ -15,10 +15,9 @@ #ifndef _FASTCDR_FASTCDR_H_ #define _FASTCDR_FASTCDR_H_ -#include "fastcdr_dll.h" -#include "FastBuffer.h" -#include "exceptions/NotEnoughMemoryException.h" -#include +#include +#include +#include #include #include @@ -28,7 +27,10 @@ #include #endif // if !__APPLE__ && !__FreeBSD__ && !__VXWORKS__ -#include +#include "fastcdr_dll.h" +#include "FastBuffer.h" +#include "exceptions/NotEnoughMemoryException.h" +#include "exceptions/BadParamException.h" namespace eprosima { namespace fastcdr { @@ -883,12 +885,27 @@ class Cdr_DllAPI FastCdr * @param string_t The string that will be serialized in the buffer. * @return Reference to the eprosima::fastcdr::FastCdr object. * @exception exception::NotEnoughMemoryException This exception is thrown when trying to serialize in a position that exceeds the internal memory size. + * @exception exception::BadParamException This exception is thrown when trying to serialize a string with null characters. */ inline FastCdr& serialize( const std::string& string_t) { - return serialize(string_t.c_str()); + // An empty string is serialized as a 0 length string. + if (string_t.empty()) + { + return serialize(static_cast(0)); + } + + // Check there are no null characters in the string. + const char* c_str = string_t.c_str(); + const auto str_len = strlen(c_str); + if (string_t.size() > str_len) + { + throw exception::BadParamException("The string contains null characters"); + } + + return serialize(c_str); } /*! diff --git a/test/cdr/SimpleTest.cpp b/test/cdr/SimpleTest.cpp index 9a9b70a5..db154832 100644 --- a/test/cdr/SimpleTest.cpp +++ b/test/cdr/SimpleTest.cpp @@ -7047,3 +7047,33 @@ TEST(FastCDRTests, ZeroSequenceAtTheEnd) cdr_des_bool >> value >> bool_zero_sequence; }); } + +TEST(CDRTests, StringWithNullChars) +{ + std::string str{ "Hello World" }; + str[5] = '\0'; + char buffer[256]; + FastBuffer cdrbuffer(buffer, 256); + Cdr cdr_ser(cdrbuffer); + + EXPECT_THROW( + { + cdr_ser << str; + }, + BadParamException); +} + +TEST(FastCDRTests, StringWithNullChars) +{ + std::string str{ "Hello World" }; + str[5] = '\0'; + char buffer[256]; + FastBuffer cdrbuffer(buffer, 256); + FastCdr cdr_ser(cdrbuffer); + + EXPECT_THROW( + { + cdr_ser << str; + }, + BadParamException); +}