about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-05-08T16·23+0300
committerflokli <flokli@flokli.de>2023-05-10T06·15+0000
commitb46f2b52c72603071bd9551aaa18b528da4cd380 (patch)
tree2510e985a7fc4cbeb8dc912e750a740f824f53a9
parenta4b8f14332971c4d9061264a45856076186f181d (diff)
feat(tvix/nix-compat/nar/writer): check for more data in reader r/6129
We already returned UnexpectedEof in case the reader stopped returning
bytes too early, but similarly we should also fail if there's still
bytes left to be read in the reader passed.

We normally use the NAR writer to produce new NAR files, so the readers
point to the blobs we actually want to render, and having some data left
in there should be an error.

If for some reason the reader points to more data than just the blob,
the `.take` method can be used to limit it to the (known) size.

Change-Id: I9e8fa0a6dd9c794492abb6dc9e55995e619cb3bb
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8553
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
-rw-r--r--tvix/nix-compat/src/nar/writer/mod.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/tvix/nix-compat/src/nar/writer/mod.rs b/tvix/nix-compat/src/nar/writer/mod.rs
index 9f9640e273bb..f24b69883876 100644
--- a/tvix/nix-compat/src/nar/writer/mod.rs
+++ b/tvix/nix-compat/src/nar/writer/mod.rs
@@ -28,7 +28,11 @@
 //! # Ok::<(), std::io::Error>(())
 //! ```
 
-use std::io::{self, BufRead, ErrorKind::UnexpectedEof, Write};
+use std::io::{
+    self, BufRead,
+    ErrorKind::{InvalidInput, UnexpectedEof},
+    Write,
+};
 
 mod wire;
 
@@ -108,6 +112,15 @@ impl<'a, 'w> Node<'a, 'w> {
             reader.consume(n);
         }
 
+        // bail if there's still data left in the passed reader.
+        // This uses the same code as [BufRead::has_data_left] (unstable).
+        if reader.fill_buf().map(|b| !b.is_empty())? {
+            return Err(io::Error::new(
+                InvalidInput,
+                "reader contained more data than specified size",
+            ));
+        }
+
         self.pad(size)?;
         self.write(&wire::TOK_PAR)?;