feat(tvix/derivation): more checks for output hashes and encoding
Change-Id: Idebad60c3bf9daf94d04a36bb73ac0dd767f9e79 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7856 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									083e24bbb1
								
							
						
					
					
						commit
						9822fa387a
					
				
					 5 changed files with 33 additions and 2 deletions
				
			
		
							
								
								
									
										1
									
								
								tvix/Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								tvix/Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -2318,6 +2318,7 @@ name = "tvix-derivation"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "anyhow",
 | 
					 "anyhow",
 | 
				
			||||||
 | 
					 "data-encoding",
 | 
				
			||||||
 "glob",
 | 
					 "glob",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6879,6 +6879,10 @@ rec {
 | 
				
			||||||
            name = "anyhow";
 | 
					            name = "anyhow";
 | 
				
			||||||
            packageId = "anyhow";
 | 
					            packageId = "anyhow";
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            name = "data-encoding";
 | 
				
			||||||
 | 
					            packageId = "data-encoding";
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            name = "glob";
 | 
					            name = "glob";
 | 
				
			||||||
            packageId = "glob";
 | 
					            packageId = "glob";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
anyhow = "1.0.68"
 | 
					anyhow = "1.0.68"
 | 
				
			||||||
 | 
					data-encoding = "2.3.3"
 | 
				
			||||||
glob = "0.3.0"
 | 
					glob = "0.3.0"
 | 
				
			||||||
serde = { version = "1.0", features = ["derive"] }
 | 
					serde = { version = "1.0", features = ["derive"] }
 | 
				
			||||||
sha2 = "0.10.6"
 | 
					sha2 = "0.10.6"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,4 +47,10 @@ pub enum DerivationError {
 | 
				
			||||||
pub enum OutputError {
 | 
					pub enum OutputError {
 | 
				
			||||||
    #[error("Invalid ouput path {0}: {1}")]
 | 
					    #[error("Invalid ouput path {0}: {1}")]
 | 
				
			||||||
    InvalidOutputPath(String, ParseStorePathError),
 | 
					    InvalidOutputPath(String, ParseStorePathError),
 | 
				
			||||||
 | 
					    #[error("Invalid hash encoding: {0}")]
 | 
				
			||||||
 | 
					    InvalidHashEncoding(String, data_encoding::DecodeError),
 | 
				
			||||||
 | 
					    #[error("Invalid hash algo: {0}")]
 | 
				
			||||||
 | 
					    InvalidHashAlgo(String),
 | 
				
			||||||
 | 
					    #[error("Invalid Digest size {0} for algo {1}")]
 | 
				
			||||||
 | 
					    InvalidDigestSizeForAlgo(usize, String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use tvix_store::store_path::StorePath;
 | 
					use tvix_store::{nixbase32::NIXBASE32, store_path::StorePath};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::OutputError;
 | 
					use crate::OutputError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,26 @@ impl Output {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn validate(&self, validate_output_paths: bool) -> Result<(), OutputError> {
 | 
					    pub fn validate(&self, validate_output_paths: bool) -> Result<(), OutputError> {
 | 
				
			||||||
        // TODO: add validation for hash, hashAlgo
 | 
					        if let Some(hash) = &self.hash {
 | 
				
			||||||
 | 
					            // try to decode digest
 | 
				
			||||||
 | 
					            let result = NIXBASE32.decode(&hash.digest.as_bytes());
 | 
				
			||||||
 | 
					            match result {
 | 
				
			||||||
 | 
					                Err(e) => return Err(OutputError::InvalidHashEncoding(hash.digest.clone(), e)),
 | 
				
			||||||
 | 
					                Ok(digest) => {
 | 
				
			||||||
 | 
					                    if hash.algo != "sha1" && hash.algo != "sha256" {
 | 
				
			||||||
 | 
					                        return Err(OutputError::InvalidHashAlgo(hash.algo.to_string()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (hash.algo == "sha1" && digest.len() != 20)
 | 
				
			||||||
 | 
					                        || (hash.algo == "sha256" && digest.len() != 32)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return Err(OutputError::InvalidDigestSizeForAlgo(
 | 
				
			||||||
 | 
					                            digest.len(),
 | 
				
			||||||
 | 
					                            hash.algo.to_string(),
 | 
				
			||||||
 | 
					                        ));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if validate_output_paths {
 | 
					        if validate_output_paths {
 | 
				
			||||||
            if let Err(e) = StorePath::from_absolute_path(&self.path) {
 | 
					            if let Err(e) = StorePath::from_absolute_path(&self.path) {
 | 
				
			||||||
                return Err(OutputError::InvalidOutputPath(self.path.to_string(), e));
 | 
					                return Err(OutputError::InvalidOutputPath(self.path.to_string(), e));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue