feat(tvix/nix-compat/nar/writer): check for more data in reader

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>
This commit is contained in:
Florian Klink 2023-05-08 19:23:33 +03:00 committed by flokli
parent a4b8f14332
commit b46f2b52c7

View file

@ -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)?;