diff options
Diffstat (limited to 'tvix/store/src')
-rw-r--r-- | tvix/store/src/bin/tvix-store.rs | 1 | ||||
-rw-r--r-- | tvix/store/src/proto/mod.rs | 16 | ||||
-rw-r--r-- | tvix/store/src/proto/tests/pathinfo.rs | 31 | ||||
-rw-r--r-- | tvix/store/src/tests/fixtures.rs | 1 |
4 files changed, 48 insertions, 1 deletions
diff --git a/tvix/store/src/bin/tvix-store.rs b/tvix/store/src/bin/tvix-store.rs index 11f19857dd6f..2f7589b07356 100644 --- a/tvix/store/src/bin/tvix-store.rs +++ b/tvix/store/src/bin/tvix-store.rs @@ -296,6 +296,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { signatures: vec![], reference_names: vec![], }), + deriver: None, }; // put into [PathInfoService], and return the PathInfo that we get back diff --git a/tvix/store/src/proto/mod.rs b/tvix/store/src/proto/mod.rs index 718e24912de1..4ebd4a31908f 100644 --- a/tvix/store/src/proto/mod.rs +++ b/tvix/store/src/proto/mod.rs @@ -48,7 +48,7 @@ pub enum ValidatePathInfoError { #[error("Inconsistent Number of References: {0} (references) vs {1} (narinfo)")] InconsistentNumberOfReferences(usize, usize), - /// A string in narinfo.reference_names does not parse to a StorePath. + /// A string in narinfo.reference_names does not parse to a [store_path::StorePath]. #[error("Invalid reference_name at position {0}: {1}")] InvalidNarinfoReferenceName(usize, String), @@ -60,6 +60,10 @@ pub enum ValidatePathInfoError { [u8; store_path::DIGEST_SIZE], [u8; store_path::DIGEST_SIZE], ), + + /// The deriver field is invalid. + #[error("deriver field is invalid: {0}")] + InvalidDeriverField(store_path::Error), } /// Parses a root node name. @@ -152,6 +156,16 @@ impl PathInfo { } }; + // If the Deriver field is populated, ensure it parses to a + // [store_path::StorePath]. + // We can't check for it to *not* end with .drv, as the .drv files produced by + // recursive Nix end with multiple .drv suffixes, and only one is popped when + // converting to this field. + if let Some(deriver) = &self.deriver { + store_path::StorePath::from_name_and_digest(deriver.name.clone(), &deriver.digest) + .map_err(ValidatePathInfoError::InvalidDeriverField)?; + } + // return the root nix path Ok(root_nix_path) } diff --git a/tvix/store/src/proto/tests/pathinfo.rs b/tvix/store/src/proto/tests/pathinfo.rs index 5e1ae9c45b64..03094ed734ce 100644 --- a/tvix/store/src/proto/tests/pathinfo.rs +++ b/tvix/store/src/proto/tests/pathinfo.rs @@ -262,3 +262,34 @@ fn validate_symlink_target_null_byte_invalid() { node.validate().expect_err("must fail validation"); } + +/// Create a PathInfo with a correct deriver field and ensure it succeeds. +#[test] +fn validate_valid_deriver() { + let mut path_info = PATH_INFO_WITHOUT_NARINFO.clone(); + + // add a valid deriver + path_info.deriver = Some(crate::proto::StorePath { + name: "foo".to_string(), + digest: DUMMY_OUTPUT_HASH.clone(), + }); + + path_info.validate().expect("must validate"); +} + +/// Create a PathInfo with a broken deriver field and ensure it fails. +#[test] +fn validate_invalid_deriver() { + let mut path_info = PATH_INFO_WITHOUT_NARINFO.clone(); + + // add a broken deriver (invalid digest) + path_info.deriver = Some(crate::proto::StorePath { + name: "foo".to_string(), + digest: vec![].into(), + }); + + match path_info.validate().expect_err("must fail validation") { + ValidatePathInfoError::InvalidDeriverField(_) => {} + e => panic!("unexpected error: {:?}", e), + } +} diff --git a/tvix/store/src/tests/fixtures.rs b/tvix/store/src/tests/fixtures.rs index f0d0f35378cf..5290581688e6 100644 --- a/tvix/store/src/tests/fixtures.rs +++ b/tvix/store/src/tests/fixtures.rs @@ -109,6 +109,7 @@ lazy_static! { }), references: vec![DUMMY_OUTPUT_HASH.clone()], narinfo: None, + deriver: None, }; /// A PathInfo message with .narinfo populated. |