diff --git a/core/libs/prx/libSceNpCppWebApi/Export.cpp b/core/libs/prx/libSceNpCppWebApi/Export.cpp index 9f389ecfe3..c83b1fd24f 100644 --- a/core/libs/prx/libSceNpCppWebApi/Export.cpp +++ b/core/libs/prx/libSceNpCppWebApi/Export.cpp @@ -1637,12 +1637,16 @@ static void ResetBinary(CommonBinary* self) { } static int SetBinary(CommonBinary* self, const void* data, const std::uint64_t size) { - ResetBinary(self); - if (size == 0) return 0; + if (size == 0) { + ResetBinary(self); + return 0; + } if (data == nullptr) return BinaryInvalidArgument; - void* buffer = std::malloc(size); + if (size > SIZE_MAX) return BinaryOutOfMemory; + void* buffer = std::malloc(static_cast(size)); if (buffer == nullptr) return BinaryOutOfMemory; - std::memcpy(buffer, data, size); + std::memcpy(buffer, data, static_cast(size)); + std::free(self->buffer); self->buffer = buffer; self->size = size; return 0; @@ -1651,11 +1655,16 @@ static int SetBinary(CommonBinary* self, const void* data, const std::uint64_t s static int AppendBinary(CommonBinary* self, const void* data, const std::uint64_t size) { if (size == 0) return 0; if (data == nullptr) return BinaryInvalidArgument; - void* buffer = std::realloc(self->buffer, self->size + size); + if (size > UINT64_MAX - self->size) return BinaryOutOfMemory; + const std::uint64_t total = self->size + size; + if (total > SIZE_MAX) return BinaryOutOfMemory; + auto* buffer = static_cast(std::malloc(static_cast(total))); if (buffer == nullptr) return BinaryOutOfMemory; - std::memcpy(static_cast(buffer) + self->size, data, size); + if (self->size != 0) std::memcpy(buffer, self->buffer, static_cast(self->size)); + std::memcpy(buffer + static_cast(self->size), data, static_cast(size)); + std::free(self->buffer); self->buffer = buffer; - self->size += size; + self->size = total; return 0; } diff --git a/core/libs/tests/GuestNpCppWebApiBinary.cpp b/core/libs/tests/GuestNpCppWebApiBinary.cpp index 7566654ce7..beb8196da0 100644 --- a/core/libs/tests/GuestNpCppWebApiBinary.cpp +++ b/core/libs/tests/GuestNpCppWebApiBinary.cpp @@ -80,14 +80,22 @@ void TestSetAndAppend() { Require(std::memcmp(_ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), "abcde", 5) == 0); Require(_ZN3sce2Np9CppWebApi6Common6Binary9setBinaryEPKvm(binary, nullptr, 1) == kInvalidArgument); - Require(Load(storage, kDataSizeOffset) == 0); - Require(Load(storage, kBufferOffset) == nullptr); + Require(Load(storage, kDataSizeOffset) == 5); + Require(std::memcmp(_ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), "abcde", 5) == 0); Require(_ZN3sce2Np9CppWebApi6Common6Binary9setBinaryEPKvm(binary, nullptr, 0) == 0); Require(_ZN3sce2Np9CppWebApi6Common6Binary12appendBinaryEPKvm(binary, "xy", 2) == 0); Require(Load(storage, kDataSizeOffset) == 2); Require(std::memcmp(_ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), "xy", 2) == 0); + Require(_ZN3sce2Np9CppWebApi6Common6Binary9setBinaryEPKvm(binary, _ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), 2) == 0); + Require(Load(storage, kDataSizeOffset) == 2); + Require(std::memcmp(_ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), "xy", 2) == 0); + + Require(_ZN3sce2Np9CppWebApi6Common6Binary12appendBinaryEPKvm(binary, _ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), 2) == 0); + Require(Load(storage, kDataSizeOffset) == 4); + Require(std::memcmp(_ZNK3sce2Np9CppWebApi6Common6Binary9getBinaryEv(reinterpret_cast(storage.bytes)), "xyxy", 4) == 0); + Require(Load(storage, kReferenceCountOffset) == 0); Require(_ZN3sce2Np9CppWebApi6Common6Binary21intrusive_ptr_add_refEPS3_(binary) == 1); Require(_ZN3sce2Np9CppWebApi6Common6Binary21intrusive_ptr_add_refEPS3_(binary) == 2);