From a794790203b48ac50490f4fa0bfd66cbbb7e29c4 Mon Sep 17 00:00:00 2001 From: Brian Olsen Date: Sun, 28 Jul 2024 19:50:20 +0200 Subject: fix(tvix/nix-compat): Fix panic in nixbase32 decoding The decode function didn't check that the input had a valid length and so would panic when given input with invalid length. Change-Id: Ie27d006b8fe20f005b4a47a1763821a61e9a95c7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12051 Reviewed-by: aspen Tested-by: BuildkiteCI Autosubmit: Brian Olsen --- tvix/nix-compat/src/nixbase32.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tvix/nix-compat/src/nixbase32.rs') diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs index b7ffc1dc2bcd..8d34e4cedce6 100644 --- a/tvix/nix-compat/src/nixbase32.rs +++ b/tvix/nix-compat/src/nixbase32.rs @@ -62,6 +62,12 @@ pub fn decode(input: impl AsRef<[u8]>) -> Result, DecodeError> { let input = input.as_ref(); let output_len = decode_len(input.len()); + if input.len() != encode_len(output_len) { + return Err(DecodeError { + position: input.len().min(encode_len(output_len)), + kind: DecodeKind::Length, + }); + } let mut output: Vec = vec![0x00; output_len]; decode_inner(input, &mut output)?; @@ -163,6 +169,10 @@ mod tests { #[case::invalid_encoding_1("zz", None)] // this is an even more specific example - it'd decode as 00000000 11 #[case::invalid_encoding_2("c0", None)] + // This has an invalid length + #[case::invalid_encoding_3("0", None)] + // This has an invalid length + #[case::invalid_encoding_4("0zz", None)] #[test] fn decode(#[case] enc: &str, #[case] dec: Option<&[u8]>) { match dec { @@ -201,6 +211,11 @@ mod tests { #[test] fn decode_len() { assert_eq!(super::decode_len(0), 0); + assert_eq!(super::decode_len(1), 0); + assert_eq!(super::decode_len(2), 1); + assert_eq!(super::decode_len(3), 1); + assert_eq!(super::decode_len(4), 2); + assert_eq!(super::decode_len(5), 3); assert_eq!(super::decode_len(32), 20); } } -- cgit 1.4.1