about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Olsen <brian@maven-group.org>2024-07-28T17·50+0200
committerclbot <clbot@tvl.fyi>2024-07-28T20·55+0000
commita794790203b48ac50490f4fa0bfd66cbbb7e29c4 (patch)
tree29a6dda053e58798c817d3d3d593d7cd5363cc2c
parenta982f734775de733c2fde60cc2689cbaf57d8515 (diff)
fix(tvix/nix-compat): Fix panic in nixbase32 decoding r/8421
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 <root@gws.fyi>
Tested-by: BuildkiteCI
Autosubmit: Brian Olsen <me@griff.name>
-rw-r--r--tvix/nix-compat/src/nixbase32.rs15
1 files changed, 15 insertions, 0 deletions
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<Vec<u8>, 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<u8> = 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);
     }
 }