diff options
author | r-paiva <rui.paiva.10@hotmail.com> | 2021-05-10 21:59:37 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-20 23:53:06 +0200 |
commit | 943f4eb28791b82b311ce864aa1658fb26105f46 (patch) | |
tree | dd2f97f2cc538fb2b22cd31a2f5e09ae421669ac | |
parent | edcfbdf4bd9fa43b1c4164e856996e59b3a40749 (diff) | |
download | serenity-943f4eb28791b82b311ce864aa1658fb26105f46.zip |
LibCore: Let IODevice::can_read_line() buffer until \n or EOF
If a line was larger than 1024 bytes or the file ended without a
newline character, can_read_line would return false.
IODevice::can_read_line() now reads until a newline is found or
EOF is reached.
fixes #5907
-rw-r--r-- | AK/Vector.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/IODevice.cpp | 25 |
2 files changed, 21 insertions, 6 deletions
diff --git a/AK/Vector.h b/AK/Vector.h index fd25487ce6..e75e6a58c9 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -161,8 +161,6 @@ public: return false; } - // NOTE: Vector::is_null() exists for the benefit of String::copy(). - bool is_null() const { return false; } bool is_empty() const { return size() == 0; } ALWAYS_INLINE size_t size() const { return m_size; } size_t capacity() const { return m_capacity; } diff --git a/Userland/Libraries/LibCore/IODevice.cpp b/Userland/Libraries/LibCore/IODevice.cpp index 6dd7e3dc9c..fb45152999 100644 --- a/Userland/Libraries/LibCore/IODevice.cpp +++ b/Userland/Libraries/LibCore/IODevice.cpp @@ -105,14 +105,31 @@ bool IODevice::can_read_line() const { if (m_eof && !m_buffered_data.is_empty()) return true; + if (m_buffered_data.contains_slow('\n')) return true; + if (!can_read_from_fd()) return false; - populate_read_buffer(); - if (m_eof && !m_buffered_data.is_empty()) - return true; - return m_buffered_data.contains_slow('\n'); + + while (true) { + // Populate buffer until a newline is found or we reach EOF. + + auto previous_buffer_size = m_buffered_data.size(); + populate_read_buffer(); + auto new_buffer_size = m_buffered_data.size(); + + if (m_error) + return false; + + if (m_eof) + return !m_buffered_data.is_empty(); + + if (m_buffered_data.contains_in_range('\n', previous_buffer_size, new_buffer_size - 1)) + return true; + } + + return true; } bool IODevice::can_read() const |