Browse Source

Streams: Consistent behaviour when reading from stream with error.

The streaming operator doesn't short-circuit, consider the following
snippet:

    void foo(InputStream& stream) {
        int a, b;
        stream >> a >> b;
    }

If the first read fails, the second is called regardless. It should be
well defined what happens in this case: nothing.
asynts 4 years ago
parent
commit
6de63782c7

+ 3 - 1
AK/BitStream.h

@@ -40,8 +40,10 @@ public:
 
     size_t read(Bytes bytes) override
     {
-        size_t nread = 0;
+        if (has_any_error())
+            return 0;
 
+        size_t nread = 0;
         if (bytes.size() >= 1) {
             if (m_next_byte.has_value()) {
                 bytes[0] = m_next_byte.value();

+ 3 - 0
AK/Buffered.h

@@ -57,6 +57,9 @@ public:
 
     size_t read(Bytes bytes) override
     {
+        if (has_any_error())
+            return 0;
+
         auto nread = buffer().trim(m_buffer_remaining).copy_trimmed_to(bytes);
 
         m_buffer_remaining -= nread;

+ 3 - 0
AK/CircularDuplexStream.h

@@ -60,6 +60,9 @@ public:
 
     size_t read(Bytes bytes) override
     {
+        if (has_any_error())
+            return 0;
+
         const auto nread = min(bytes.size(), m_queue.size());
 
         for (size_t idx = 0; idx < nread; ++idx)

+ 6 - 0
AK/MemoryStream.h

@@ -44,6 +44,9 @@ public:
 
     size_t read(Bytes bytes) override
     {
+        if (has_any_error())
+            return 0;
+
         const auto count = min(bytes.size(), remaining());
         __builtin_memcpy(bytes.data(), m_bytes.data() + m_offset, count);
         m_offset += count;
@@ -239,6 +242,9 @@ public:
 
     size_t read(Bytes bytes) override
     {
+        if (has_any_error())
+            return 0;
+
         const auto nread = read_without_consuming(bytes);
 
         m_read_offset += nread;

+ 1 - 0
AK/Stream.h

@@ -75,6 +75,7 @@ namespace AK {
 
 class InputStream : public virtual AK::Detail::Stream {
 public:
+    // Does nothing and returns zero if there is already an error.
     virtual size_t read(Bytes) = 0;
     virtual bool read_or_error(Bytes) = 0;
     virtual bool eof() const = 0;

+ 2 - 2
Libraries/LibCompress/Deflate.cpp

@@ -189,8 +189,8 @@ DeflateDecompressor::~DeflateDecompressor()
 
 size_t DeflateDecompressor::read(Bytes bytes)
 {
-    // FIXME: There are surely a ton of bugs because we don't check for read errors
-    //        very often.
+    if (has_any_error())
+        return 0;
 
     if (m_state == State::Idle) {
         if (m_read_final_bock)

+ 3 - 0
Libraries/LibCompress/Gzip.cpp

@@ -68,6 +68,9 @@ GzipDecompressor::~GzipDecompressor()
 // FIXME: Again, there are surely a ton of bugs because the code doesn't check for read errors.
 size_t GzipDecompressor::read(Bytes bytes)
 {
+    if (has_any_error())
+        return 0;
+
     if (m_current_member.has_value()) {
         size_t nread = current_member().m_stream.read(bytes);
         current_member().m_checksum.update(bytes.trim(nread));

+ 3 - 0
Libraries/LibCore/FileStream.h

@@ -65,6 +65,9 @@ public:
 
     size_t read(Bytes bytes) override
     {
+        if (has_any_error())
+            return 0;
+
         auto nread = m_buffered.bytes().copy_trimmed_to(bytes);
 
         m_buffered.bytes().slice(nread, m_buffered.size() - nread).copy_to(m_buffered);