Skip to content

Commit

Permalink
fix deserialization of zero size dynamic containers and zero length s…
Browse files Browse the repository at this point in the history
…td::string
  • Loading branch information
farukeryilmaz committed Jan 28, 2024
1 parent d48a0d9 commit 3bc6055
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions include/bytepack/bytepack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
* rigid standardizations. It supports both internally allocated buffers and user-supplied buffers.
*/

#ifndef BYTEPACK_HPP
#define BYTEPACK_HPP
#ifndef BYTEPACK_BYTEPACK_HPP
#define BYTEPACK_BYTEPACK_HPP

#include <bit>
#include <string>
Expand Down Expand Up @@ -111,7 +111,7 @@ class buffer_view

[[nodiscard]] constexpr bool is_empty() const noexcept { return size_ == 0; }

[[nodiscard]] constexpr operator bool() const noexcept { return data_ && size_ > 0; }
[[nodiscard]] constexpr operator bool() const noexcept { return data_ != nullptr && size_ > 0; }

private:
static constexpr std::ptrdiff_t to_ssize(const std::size_t size) noexcept
Expand All @@ -120,7 +120,6 @@ class buffer_view
return static_cast<R>(size);
}

private:
void* data_;
std::size_t size_;
std::ptrdiff_t ssize_; // signed
Expand Down Expand Up @@ -288,7 +287,9 @@ class binary_stream final
requires NetworkSerializableBasic<T>
bool write(const std::vector<T>& vector) noexcept
{
// the vector size is serialized as metadata before the vector data
// When serializing dynamic size containers (if fixed size is not given), always include the container's size as
// metadata before the container data. This is crucial even for empty containers, as it allows the deserializer to
// accurately determine if the container is empty or contains data.
if (buffer_.size() < (write_index_ + sizeof(SizeType) + vector.size() * sizeof(T))) {
// Vector size field and its elements cannot fit in the remaining buffer space
return false;
Expand Down Expand Up @@ -511,8 +512,9 @@ class binary_stream final
bool read(std::vector<T>& vector) noexcept
{
SizeType size_custom{};
// vector size cannot be negative, and zero-size is also unusual, so it's treated as an error.
if (read(size_custom) == false || size_custom < 1) {
// vector size cannot be negative, so it's treated as an error. Zero size is well-defined for dynamic containers if
// they are not serialized with a given fixed size because it indicates an empty container.
if (read(size_custom) == false || size_custom < 0) {
return false;
}
const auto size = static_cast<std::size_t>(size_custom);
Expand Down Expand Up @@ -584,8 +586,9 @@ class binary_stream final
reinterpret_cast<std::uint8_t*>(&str_length) + sizeof(SizeType));
}

// String length cannot be negative, and zero-length is also unusual, so it's treated as an error.
if (str_length < 1) {
// String length cannot be negative, so it's treated as an error. Zero length is well-defined for dynamic strings if
// they are not serialized with a given fixed length because it indicates an empty string.
if (str_length < 0) {
return false;
}

Expand Down Expand Up @@ -670,4 +673,4 @@ class binary_stream final

} // namespace bytepack

#endif // BYTEPACK_HPP
#endif // BYTEPACK_BYTEPACK_HPP

0 comments on commit 3bc6055

Please sign in to comment.