From 9b7629826f45af70ed2668353ff4d28446cd1417 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Thu, 12 Oct 2023 22:26:53 +0200 Subject: refactor(tvix/castore): factor out node checks Implement `validate()` on `node::Node`, and call it from PathInfo's validate() too. Node-related errors are moved to a ValidateNodeError error type. This additionally adds some more validations for symlink targets (they must not be empty, and not contain null bytes). Change-Id: Ib9b89f1c9c795e868a1533281239bc8a36d97c5d Reviewed-on: https://cl.tvl.fyi/c/depot/+/9715 Autosubmit: flokli Tested-by: BuildkiteCI Reviewed-by: edef --- tvix/store/src/proto/tests/pathinfo.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'tvix/store/src/proto/tests') diff --git a/tvix/store/src/proto/tests/pathinfo.rs b/tvix/store/src/proto/tests/pathinfo.rs index cfecbac3b8..5e1ae9c45b 100644 --- a/tvix/store/src/proto/tests/pathinfo.rs +++ b/tvix/store/src/proto/tests/pathinfo.rs @@ -43,7 +43,7 @@ fn validate_no_node( digest: Bytes::new(), size: 0, }, - Err(ValidatePathInfoError::InvalidNodeDigestLen(0)); + Err(ValidatePathInfoError::InvalidRootNode(castorepb::ValidateNodeError::InvalidDigestLen(0))); "invalid digest length" )] #[test_case( @@ -88,7 +88,7 @@ fn validate_directory( digest: Bytes::new(), ..Default::default() }, - Err(ValidatePathInfoError::InvalidNodeDigestLen(0)); + Err(ValidatePathInfoError::InvalidRootNode(castorepb::ValidateNodeError::InvalidDigestLen(0))); "invalid digest length" )] #[test_case( @@ -120,7 +120,7 @@ fn validate_file( #[test_case( castorepb::SymlinkNode { name: DUMMY_NAME.into(), - ..Default::default() + target: "foo".into(), }, Ok(StorePath::from_str(DUMMY_NAME).expect("must succeed")); "ok" @@ -128,7 +128,7 @@ fn validate_file( #[test_case( castorepb::SymlinkNode { name: "invalid".into(), - ..Default::default() + target: "foo".into(), }, Err(ValidatePathInfoError::InvalidNodeName( "invalid".into(), @@ -239,3 +239,26 @@ fn validate_inconsistent_narinfo_reference_name_digest() { e => panic!("unexpected error: {:?}", e), } } + +/// Create a node with an empty symlink target, and ensure it fails validation. +#[test] +fn validate_symlink_empty_target_invalid() { + let node = castorepb::node::Node::Symlink(castorepb::SymlinkNode { + name: "foo".into(), + target: "".into(), + }); + + node.validate().expect_err("must fail validation"); +} + +/// Create a node with a symlink target including null bytes, and ensure it +/// fails validation. +#[test] +fn validate_symlink_target_null_byte_invalid() { + let node = castorepb::node::Node::Symlink(castorepb::SymlinkNode { + name: "foo".into(), + target: "foo\0".into(), + }); + + node.validate().expect_err("must fail validation"); +} -- cgit 1.4.1