about summary refs log tree commit diff
path: root/tvix/nix-compat/src/nar/writer
diff options
context:
space:
mode:
authoredef <edef@edef.eu>2023-10-15T14·59+0000
committeredef <edef@edef.eu>2023-10-18T11·40+0000
commit6638f4d4ea6848fe6fc2dc89271f0b6950764729 (patch)
tree470e909133069a49403298d182972c9fff8c7a82 /tvix/nix-compat/src/nar/writer
parent08b98b7503edbde5277ce11faf48b94ca2f1c0b7 (diff)
feat(tvix/nix-compat): NAR reader r/6853
Change-Id: I50d51baf62c0419eaf17f0dc262f728aaff9794d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9688
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/nix-compat/src/nar/writer')
-rw-r--r--tvix/nix-compat/src/nar/writer/async.rs2
-rw-r--r--tvix/nix-compat/src/nar/writer/mod.rs2
-rw-r--r--tvix/nix-compat/src/nar/writer/sync.rs2
-rw-r--r--tvix/nix-compat/src/nar/writer/wire.rs110
4 files changed, 2 insertions, 114 deletions
diff --git a/tvix/nix-compat/src/nar/writer/async.rs b/tvix/nix-compat/src/nar/writer/async.rs
index 2a77fa736677..2b73e56737ce 100644
--- a/tvix/nix-compat/src/nar/writer/async.rs
+++ b/tvix/nix-compat/src/nar/writer/async.rs
@@ -30,7 +30,7 @@
 //! # });
 //! ```
 
-use super::wire;
+use crate::nar::wire;
 use bstr::ByteSlice;
 use futures_util::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
 use std::{
diff --git a/tvix/nix-compat/src/nar/writer/mod.rs b/tvix/nix-compat/src/nar/writer/mod.rs
index 79f78f37fc40..bf81ccd4df32 100644
--- a/tvix/nix-compat/src/nar/writer/mod.rs
+++ b/tvix/nix-compat/src/nar/writer/mod.rs
@@ -1,7 +1,5 @@
 pub use sync::*;
 
-mod wire;
-
 pub mod sync;
 
 #[cfg(feature = "async")]
diff --git a/tvix/nix-compat/src/nar/writer/sync.rs b/tvix/nix-compat/src/nar/writer/sync.rs
index 996815149dd6..9290e4a5bdfe 100644
--- a/tvix/nix-compat/src/nar/writer/sync.rs
+++ b/tvix/nix-compat/src/nar/writer/sync.rs
@@ -28,7 +28,7 @@
 //! # Ok::<(), std::io::Error>(())
 //! ```
 
-use super::wire;
+use crate::nar::wire;
 use bstr::ByteSlice;
 use std::io::{
     self, BufRead,
diff --git a/tvix/nix-compat/src/nar/writer/wire.rs b/tvix/nix-compat/src/nar/writer/wire.rs
deleted file mode 100644
index a6c19f0759c3..000000000000
--- a/tvix/nix-compat/src/nar/writer/wire.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-//! NAR wire format, without I/O details, since those differ between
-//! the synchronous and asynchronous implementations.
-//!
-//! The wire format is an S-expression format, encoded onto the wire
-//! using simple encoding rules.
-//!
-//! # Encoding
-//!
-//! Lengths are represented as 64-bit unsigned integers in little-endian
-//! format. Byte strings, including file contents and syntactic strings
-//! part of the grammar, are prefixed by their 64-bit length, and padded
-//! to 8-byte (64-bit) alignment with zero bytes. The zero-length string
-//! is therefore encoded as eight zero bytes representing its length.
-//!
-//! # Grammar
-//!
-//! The NAR grammar is as follows:
-//! ```plain
-//! archive ::= "nix-archive-1" node
-//!
-//! node ::= "(" "type" "symlink" "target" string ")"
-//!      ||= "(" "type" "regular" ("executable" "")? "contents" string ")"
-//!      ||= "(" "type" "directory" entry* ")"
-//!
-//! entry ::= "entry" "(" "name" string "node" node ")"
-//! ```
-//!
-//! We rewrite it to pull together the purely syntactic elements into
-//! unified tokens, producing an equivalent grammar that can be parsed
-//! and serialized more elegantly:
-//! ```plain
-//! archive ::= TOK_NAR node
-//! node ::= TOK_SYM string             TOK_PAR
-//!      ||= (TOK_REG | TOK_EXE) string TOK_PAR
-//!      ||= TOK_DIR entry*             TOK_PAR
-//!
-//! entry ::= TOK_ENT string TOK_NOD node TOK_PAR
-//!
-//! TOK_NAR ::= "nix-archive-1" "(" "type"
-//! TOK_SYM ::= "symlink" "target"
-//! TOK_REG ::= "regular" "contents"
-//! TOK_EXE ::= "regular" "executable" ""
-//! TOK_DIR ::= "directory"
-//! TOK_ENT ::= "entry" "(" "name"
-//! TOK_NOD ::= "node" "(" "type"
-//! TOK_PAR ::= ")"
-//! ```
-//!
-//! # Restrictions
-//!
-//! NOTE: These restrictions are not (and cannot be) enforced by this module,
-//! but must be enforced by its consumers, [super::reader] and [super::writer].
-//!
-//! Directory entry names cannot have the reserved names `.` and `..`, nor contain
-//! forward slashes. They must appear in strictly ascending lexicographic order
-//! within a directory, and can be at most [MAX_NAME_LEN] bytes in length.
-//!
-//! Symlink targets can be at most [MAX_TARGET_LEN] bytes in length.
-//!
-//! Neither is permitted to be empty, or contain null bytes.
-
-// These values are the standard Linux length limits
-/// Maximum length of a directory entry name
-pub const MAX_NAME_LEN: usize = 255;
-/// Maximum length of a symlink target
-pub const MAX_TARGET_LEN: usize = 4095;
-
-#[cfg(test)]
-fn token(xs: &[&str]) -> Vec<u8> {
-    let mut out = vec![];
-    for x in xs {
-        let len = x.len() as u64;
-        out.extend_from_slice(&len.to_le_bytes());
-        out.extend_from_slice(x.as_bytes());
-
-        let n = x.len() & 7;
-        if n != 0 {
-            const ZERO: [u8; 8] = [0; 8];
-            out.extend_from_slice(&ZERO[n..]);
-        }
-    }
-    out
-}
-
-pub const TOK_NAR: [u8; 56] = *b"\x0d\0\0\0\0\0\0\0nix-archive-1\0\0\0\x01\0\0\0\0\0\0\0(\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0type\0\0\0\0";
-pub const TOK_SYM: [u8; 32] = *b"\x07\0\0\0\0\0\0\0symlink\0\x06\0\0\0\0\0\0\0target\0\0";
-pub const TOK_REG: [u8; 32] = *b"\x07\0\0\0\0\0\0\0regular\0\x08\0\0\0\0\0\0\0contents";
-pub const TOK_EXE: [u8; 64] = *b"\x07\0\0\0\0\0\0\0regular\0\x0a\0\0\0\0\0\0\0executable\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0contents";
-pub const TOK_DIR: [u8; 24] = *b"\x09\0\0\0\0\0\0\0directory\0\0\0\0\0\0\0";
-pub const TOK_ENT: [u8; 48] = *b"\x05\0\0\0\0\0\0\0entry\0\0\0\x01\0\0\0\0\0\0\0(\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0name\0\0\0\0";
-pub const TOK_NOD: [u8; 48] = *b"\x04\0\0\0\0\0\0\0node\0\0\0\0\x01\0\0\0\0\0\0\0(\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0type\0\0\0\0";
-pub const TOK_PAR: [u8; 16] = *b"\x01\0\0\0\0\0\0\0)\0\0\0\0\0\0\0";
-
-#[test]
-fn tokens() {
-    let cases: &[(&[u8], &[&str])] = &[
-        (&TOK_NAR, &["nix-archive-1", "(", "type"]),
-        (&TOK_SYM, &["symlink", "target"]),
-        (&TOK_REG, &["regular", "contents"]),
-        (&TOK_EXE, &["regular", "executable", "", "contents"]),
-        (&TOK_DIR, &["directory"]),
-        (&TOK_ENT, &["entry", "(", "name"]),
-        (&TOK_NOD, &["node", "(", "type"]),
-        (&TOK_PAR, &[")"]),
-    ];
-
-    for &(tok, xs) in cases {
-        assert_eq!(tok, token(xs));
-    }
-}