rust-bakery / nom-bufreader

BufReader adapter for nom parsers
MIT License
9 stars 5 forks source link

Critical: async_bufreader::BufReader::poll_fill_buf: Destroys data. #10

Open cheako opened 2 years ago

cheako commented 2 years ago

Line 174 s/this.buffer/this.buffer[*this.cap..]/.

cheako commented 2 years ago

https://github.com/rust-bakery/nom-bufreader/blob/c2e48f5b84ef5c330b0aebe1943361009f4c5c49/src/async_bufreader.rs#L174

cheako commented 2 years ago

"AND", you can't use ready! as this is called multiple times in succession. Returning Ready and then Pending is a panic.

cheako commented 2 years ago
diff --git a/src/async_bufreader.rs b/src/async_bufreader.rs
index bb5557c..836c6fa 100644
--- a/src/async_bufreader.rs
+++ b/src/async_bufreader.rs
@@ -171,9 +171,16 @@ impl<R: AsyncRead> AsyncBufRead for BufReader<R> {
             }
         }

-        let read = ready!(this.inner.poll_read(cx, this.buffer))?;
-        *this.cap += read;
-
+        match this.inner.poll_read(cx, &mut this.buffer[*this.cap..]) {
+            Poll::Pending => {
+                /* This is supposed to let the compiler know pos can never be greater than cap... or something */
+                if *this.pos < *this.cap {
+                } else {
+                    return Poll::Pending;
+                }
+            }
+            Poll::Ready(read) => *this.cap += read?,
+        }
         Poll::Ready(Ok(&this.buffer[*this.pos..*this.cap]))
     }