Commit 9ffbfda8 authored by Harris Hancock's avatar Harris Hancock

Fix bug where Array/VectorOutputStream::write() assumed adjecent buffers were their own

parent 6f83d325
...@@ -175,5 +175,27 @@ KJ_TEST("InputStream::readAllText() / readAllBytes()") { ...@@ -175,5 +175,27 @@ KJ_TEST("InputStream::readAllText() / readAllBytes()") {
} }
} }
KJ_TEST("ArrayOutputStream::write() does not assume adjacent write buffer is its own") {
// Previously, if ArrayOutputStream::write(src, size) saw that `src` equaled its fill position, it
// would assume that the write was already in its buffer. This assumption was buggy if the write
// buffer was directly adjacent in memory to the ArrayOutputStream's buffer, and the
// ArrayOutputStream was full (i.e., its fill position was one-past-the-end).
//
// VectorOutputStream also suffered a similar bug, but it is much harder to test, since it
// performs its own allocation.
kj::byte buffer[10] = { 0 };
ArrayOutputStream output(arrayPtr(buffer, buffer + 5));
// Succeeds and fills the ArrayOutputStream.
output.write(buffer + 5, 5);
// Previously this threw an inscrutable "size <= array.end() - fillPos" requirement failure.
KJ_EXPECT_THROW_MESSAGE(
"backing array was not large enough for the data written",
output.write(buffer + 5, 5));
}
} // namespace } // namespace
} // namespace kj } // namespace kj
...@@ -271,7 +271,7 @@ ArrayPtr<byte> ArrayOutputStream::getWriteBuffer() { ...@@ -271,7 +271,7 @@ ArrayPtr<byte> ArrayOutputStream::getWriteBuffer() {
} }
void ArrayOutputStream::write(const void* src, size_t size) { void ArrayOutputStream::write(const void* src, size_t size) {
if (src == fillPos) { if (src == fillPos && fillPos != array.end()) {
// Oh goody, the caller wrote directly into our buffer. // Oh goody, the caller wrote directly into our buffer.
KJ_REQUIRE(size <= array.end() - fillPos, size, fillPos, array.end() - fillPos); KJ_REQUIRE(size <= array.end() - fillPos, size, fillPos, array.end() - fillPos);
fillPos += size; fillPos += size;
...@@ -299,7 +299,7 @@ ArrayPtr<byte> VectorOutputStream::getWriteBuffer() { ...@@ -299,7 +299,7 @@ ArrayPtr<byte> VectorOutputStream::getWriteBuffer() {
} }
void VectorOutputStream::write(const void* src, size_t size) { void VectorOutputStream::write(const void* src, size_t size) {
if (src == fillPos) { if (src == fillPos && fillPos != vector.end()) {
// Oh goody, the caller wrote directly into our buffer. // Oh goody, the caller wrote directly into our buffer.
KJ_REQUIRE(size <= vector.end() - fillPos, size, fillPos, vector.end() - fillPos); KJ_REQUIRE(size <= vector.end() - fillPos, size, fillPos, vector.end() - fillPos);
fillPos += size; fillPos += size;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment