diff --git a/core/relinker/CMakeLists.txt b/core/relinker/CMakeLists.txt index c04c4883ad..5865b02a9d 100644 --- a/core/relinker/CMakeLists.txt +++ b/core/relinker/CMakeLists.txt @@ -128,6 +128,7 @@ if(BUILD_TESTING) add_test_executable(buffer_bounds_tests ${CMAKE_CURRENT_SOURCE_DIR}/io/tests/BufferBoundsTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/io/src/ByteReader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/io/src/ByteWriter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/io/src/BufferUtils.cpp ) target_include_directories(buffer_bounds_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/io/include) diff --git a/core/relinker/io/src/ByteWriter.cpp b/core/relinker/io/src/ByteWriter.cpp index 080fd5f0bd..5d7aed2d3c 100644 --- a/core/relinker/io/src/ByteWriter.cpp +++ b/core/relinker/io/src/ByteWriter.cpp @@ -1,21 +1,30 @@ #include #include +#include namespace Io { void ByteWriter::WriteU8(std::vector& buf, std::size_t offset, std::uint8_t v) const { + if (offset >= buf.size()) + throw std::out_of_range("ByteWriter::WriteU8 out of bounds"); buf[offset] = v; } void ByteWriter::WriteU16(std::vector& buf, std::size_t offset, std::uint16_t v) const { + if (offset > buf.size() || buf.size() - offset < 2) + throw std::out_of_range("ByteWriter::WriteU16 out of bounds"); std::memcpy(buf.data() + offset, &v, 2); } void ByteWriter::WriteU32(std::vector& buf, std::size_t offset, std::uint32_t v) const { + if (offset > buf.size() || buf.size() - offset < 4) + throw std::out_of_range("ByteWriter::WriteU32 out of bounds"); std::memcpy(buf.data() + offset, &v, 4); } void ByteWriter::WriteU64(std::vector& buf, std::size_t offset, std::uint64_t v) const { + if (offset > buf.size() || buf.size() - offset < 8) + throw std::out_of_range("ByteWriter::WriteU64 out of bounds"); std::memcpy(buf.data() + offset, &v, 8); } diff --git a/core/relinker/io/tests/BufferBoundsTests.cpp b/core/relinker/io/tests/BufferBoundsTests.cpp index 8cdacaf8ad..2de9beb8bd 100644 --- a/core/relinker/io/tests/BufferBoundsTests.cpp +++ b/core/relinker/io/tests/BufferBoundsTests.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -75,9 +76,14 @@ void writeBounds(const TWrite& write, const std::string& name) { int main() { try { const Io::ByteReader reader; + const Io::ByteWriter writer; readBounds([&](const Bytes& bytes, std::size_t offset) { return reader.ReadU16(bytes, offset); }, "ByteReader::ReadU16"); readBounds([&](const Bytes& bytes, std::size_t offset) { return reader.ReadU32(bytes, offset); }, "ByteReader::ReadU32"); readBounds([&](const Bytes& bytes, std::size_t offset) { return reader.ReadU64(bytes, offset); }, "ByteReader::ReadU64"); + writeBounds([&](Bytes& bytes, std::size_t offset, std::uint8_t value) { writer.WriteU8(bytes, offset, value); }, "ByteWriter::WriteU8"); + writeBounds([&](Bytes& bytes, std::size_t offset, std::uint16_t value) { writer.WriteU16(bytes, offset, value); }, "ByteWriter::WriteU16"); + writeBounds([&](Bytes& bytes, std::size_t offset, std::uint32_t value) { writer.WriteU32(bytes, offset, value); }, "ByteWriter::WriteU32"); + writeBounds([&](Bytes& bytes, std::size_t offset, std::uint64_t value) { writer.WriteU64(bytes, offset, value); }, "ByteWriter::WriteU64"); readBounds(Io::ReadU16, "ReadU16"); readBounds(Io::ReadU32, "ReadU32"); readBounds(Io::ReadU64, "ReadU64");