From 6d5633904f5779a5edab3078851eb19cb1febb53 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 22 Jun 2019 23:07:42 +0200 Subject: [PATCH] CIODevice: Don't discard already-buffered data when there's no more to read. When we had some data already in the CIODevice buffer, we should make sure we always return that data, even if the attempt to ::read() even more data fails. This was causing us to lose partial HTTP payloads. --- LibCore/CIODevice.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/LibCore/CIODevice.cpp b/LibCore/CIODevice.cpp index 6e6c3076ec..18eba4f811 100644 --- a/LibCore/CIODevice.cpp +++ b/LibCore/CIODevice.cpp @@ -29,8 +29,9 @@ ByteBuffer CIODevice::read(int max_size) auto buffer = ByteBuffer::create_uninitialized(max_size); auto* buffer_ptr = (char*)buffer.pointer(); int remaining_buffer_space = buffer.size(); + int taken_from_buffered = 0; if (!m_buffered_data.is_empty()) { - int taken_from_buffered = min(remaining_buffer_space, m_buffered_data.size()); + taken_from_buffered = min(remaining_buffer_space, m_buffered_data.size()); memcpy(buffer_ptr, m_buffered_data.data(), taken_from_buffered); Vector new_buffered_data; new_buffered_data.append(m_buffered_data.data() + taken_from_buffered, m_buffered_data.size() - taken_from_buffered); @@ -42,14 +43,22 @@ ByteBuffer CIODevice::read(int max_size) return buffer; int nread = ::read(m_fd, buffer_ptr, remaining_buffer_space); if (nread < 0) { + if (taken_from_buffered) { + buffer.trim(taken_from_buffered); + return buffer; + } set_error(errno); return {}; } if (nread == 0) { set_eof(true); + if (taken_from_buffered) { + buffer.trim(taken_from_buffered); + return buffer; + } return {}; } - buffer.trim(nread); + buffer.trim(taken_from_buffered + nread); return buffer; }