Handle allocation errors during message deserialization (#313) (#419)

Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>

Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
Co-authored-by: Michel Hidalgo <michel@ekumenlabs.com>
This commit is contained in:
Jacob Perron 2022-09-20 13:17:30 -07:00 committed by GitHub
parent 440b191ae6
commit 6d6b78f28d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View file

@ -127,6 +127,32 @@ align_int_(size_t __align, T __int) noexcept
return (__int - 1u + __align) & ~(__align - 1);
}
inline void resize_field(
const rosidl_typesupport_introspection_cpp::MessageMember * member,
void * field,
size_t size)
{
if (!member->resize_function) {
throw std::runtime_error("unexpected error: resize function is null");
}
member->resize_function(field, size);
}
inline void resize_field(
const rosidl_typesupport_introspection_c__MessageMember * member,
void * field,
size_t size)
{
if (!member->resize_function) {
throw std::runtime_error("unexpected error: resize function is null");
}
if (!member->resize_function(field, size)) {
throw std::runtime_error("unable to resize field");
}
}
template<typename T>
static inline T *
align_ptr_(size_t __align, T * __ptr) noexcept
@ -315,7 +341,7 @@ inline void deserialize_field<std::wstring>(
size = static_cast<uint32_t>(member->array_size_);
} else {
deser >> size;
member->resize_function(field, size);
resize_field(member, field, size);
}
for (size_t i = 0; i < size; ++i) {
void * element = member->get_function(field, i);
@ -342,7 +368,9 @@ void deserialize_field(
auto & data = *reinterpret_cast<typename GenericCSequence<T>::type *>(field);
int32_t dsize = 0;
deser >> dsize;
GenericCSequence<T>::init(&data, dsize);
if (!GenericCSequence<T>::init(&data, dsize)) {
throw std::runtime_error("unable initialize generic sequence");
}
deser.deserializeA(reinterpret_cast<T *>(data.data), dsize);
}
}

View file

@ -1445,6 +1445,9 @@ extern "C" rmw_ret_t rmw_deserialize(
} catch (rmw_cyclonedds_cpp::Exception & e) {
RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("rmw_serialize: %s", e.what());
ok = false;
} catch (std::runtime_error & e) {
RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("rmw_serialize: %s", e.what());
ok = false;
}
return ok ? RMW_RET_OK : RMW_RET_ERROR;