refactor(tvix/store): use bytes for node names and symlink targets
Some paths might use names that are not valid UTF-8. We should be able to represent them. We don't actually need to touch the PathInfo structures, as they need to represent StorePaths, which come with their own harder restrictions, which can't encode non-UTF8 data. While this doesn't change any of the wire format of the gRPC messages, it does however change the interface of tvix_eval::EvalIO - its read_dir() method does now return a list of Vec<u8>, rather than SmolStr. Maybe this should be OsString instead? Change-Id: I821016d9a58ec441ee081b0b9f01c9240723af0b Reviewed-on: https://cl.tvl.fyi/c/depot/+/8974 Autosubmit: flokli <flokli@flokli.de> Reviewed-by: raitobezarius <tvl@lahfa.xyz> Tested-by: BuildkiteCI
This commit is contained in:
parent
638f3e874d
commit
72e82ffcb1
27 changed files with 245 additions and 253 deletions
|
|
@ -67,21 +67,21 @@ impl<'a, 'w> Node<'a, 'w> {
|
|||
}
|
||||
|
||||
/// Make this node a symlink.
|
||||
pub fn symlink(mut self, target: &str) -> io::Result<()> {
|
||||
pub fn symlink(mut self, target: &[u8]) -> io::Result<()> {
|
||||
debug_assert!(
|
||||
target.len() <= wire::MAX_TARGET_LEN,
|
||||
"target.len() > {}",
|
||||
wire::MAX_TARGET_LEN
|
||||
);
|
||||
debug_assert!(
|
||||
!target.contains('\0'),
|
||||
!target.contains(&b'\0'),
|
||||
"invalid target characters: {target:?}"
|
||||
);
|
||||
debug_assert!(!target.is_empty(), "empty target");
|
||||
|
||||
self.write(&wire::TOK_SYM)?;
|
||||
self.write(&target.len().to_le_bytes())?;
|
||||
self.write(target.as_bytes())?;
|
||||
self.write(target)?;
|
||||
self.pad(target.len() as u64)?;
|
||||
self.write(&wire::TOK_PAR)?;
|
||||
Ok(())
|
||||
|
|
@ -136,11 +136,11 @@ impl<'a, 'w> Node<'a, 'w> {
|
|||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
type Name = String;
|
||||
type Name = Vec<u8>;
|
||||
#[cfg(not(debug_assertions))]
|
||||
type Name = ();
|
||||
|
||||
fn into_name(_name: &str) -> Name {
|
||||
fn into_name(_name: &[u8]) -> Name {
|
||||
#[cfg(debug_assertions)]
|
||||
_name.to_owned()
|
||||
}
|
||||
|
|
@ -163,17 +163,18 @@ impl<'a, 'w> Directory<'a, 'w> {
|
|||
///
|
||||
/// The entry is simply another [`Node`], which can then be filled like the
|
||||
/// root of a NAR (including, of course, by nesting directories).
|
||||
pub fn entry(&mut self, name: &str) -> io::Result<Node<'_, 'w>> {
|
||||
pub fn entry(&mut self, name: &[u8]) -> io::Result<Node<'_, 'w>> {
|
||||
debug_assert!(
|
||||
name.len() <= wire::MAX_NAME_LEN,
|
||||
"name.len() > {}",
|
||||
wire::MAX_NAME_LEN
|
||||
);
|
||||
debug_assert!(!["", ".", ".."].contains(&name), "invalid name: {name:?}");
|
||||
debug_assert!(
|
||||
!name.contains(['/', '\0']),
|
||||
"invalid name characters: {name:?}"
|
||||
);
|
||||
debug_assert!(name != b"", "name may not be empty");
|
||||
debug_assert!(name != b".", "invalid name: {name:?}");
|
||||
debug_assert!(name != b"..", "invalid name: {name:?}");
|
||||
|
||||
debug_assert!(!name.contains(&b'/'), "invalid name characters: {name:?}");
|
||||
debug_assert!(!name.contains(&b'\0'), "invalid name characters: {name:?}");
|
||||
|
||||
match self.prev_name {
|
||||
None => {
|
||||
|
|
@ -187,7 +188,7 @@ impl<'a, 'w> Directory<'a, 'w> {
|
|||
"misordered names: {_prev_name:?} >= {name:?}"
|
||||
);
|
||||
_prev_name.clear();
|
||||
_prev_name.push_str(name);
|
||||
_prev_name.append(&mut name.to_vec());
|
||||
}
|
||||
self.node.write(&wire::TOK_PAR)?;
|
||||
}
|
||||
|
|
@ -195,7 +196,7 @@ impl<'a, 'w> Directory<'a, 'w> {
|
|||
|
||||
self.node.write(&wire::TOK_ENT)?;
|
||||
self.node.write(&name.len().to_le_bytes())?;
|
||||
self.node.write(name.as_bytes())?;
|
||||
self.node.write(name)?;
|
||||
self.node.pad(name.len() as u64)?;
|
||||
self.node.write(&wire::TOK_NOD)?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue