From 4218e4dc0e5834f354b61e31aabc2cb4006d409c Mon Sep 17 00:00:00 2001 From: edef Date: Fri, 10 Nov 2023 18:32:40 +0000 Subject: feat(nix-compat/nixbase32): use data_encoding::DecodeError Rather than having our own error type, just make decoding errors use the same common error type. Change-Id: Ie2c86972f3745c695253adc3214444ac0ab8db6e Reviewed-on: https://cl.tvl.fyi/c/depot/+/9995 Reviewed-by: flokli Tested-by: BuildkiteCI --- tvix/nix-compat/src/narinfo.rs | 2 +- tvix/nix-compat/src/nixbase32.rs | 48 +++++++++++++++++------------------ tvix/nix-compat/src/nixhash/mod.rs | 2 +- tvix/nix-compat/src/store_path/mod.rs | 6 ++--- 4 files changed, 28 insertions(+), 30 deletions(-) (limited to 'tvix') diff --git a/tvix/nix-compat/src/narinfo.rs b/tvix/nix-compat/src/narinfo.rs index 4bca115a95..d10d0d9752 100644 --- a/tvix/nix-compat/src/narinfo.rs +++ b/tvix/nix-compat/src/narinfo.rs @@ -465,7 +465,7 @@ pub enum Error { MissingPrefixForHash(String), #[error("unable to decode {0}: {1}")] - UnableToDecodeHash(String, nixbase32::Nixbase32DecodeError), + UnableToDecodeHash(String, data_encoding::DecodeError), #[error("unable to parse signature #{0}: {1}")] UnableToParseSignature(usize, SignatureError), diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs index babf768add..79b4750d95 100644 --- a/tvix/nix-compat/src/nixbase32.rs +++ b/tvix/nix-compat/src/nixbase32.rs @@ -9,21 +9,10 @@ use std::fmt::Write; -use thiserror::Error; +use data_encoding::{DecodeError, DecodeKind}; const ALPHABET: &[u8; 32] = b"0123456789abcdfghijklmnpqrsvwxyz"; -/// Errors that can occur while decoding nixbase32-encoded data. -#[derive(Debug, Eq, PartialEq, Error)] -pub enum Nixbase32DecodeError { - #[error("character {0:x} not in alphabet")] - CharacterNotInAlphabet(u8), - #[error("nonzero carry")] - NonzeroCarry, - #[error("invalid length")] - InvalidLength, -} - /// Returns encoded input pub fn encode(input: &[u8]) -> String { let output_len = encode_len(input.len()); @@ -69,7 +58,7 @@ const BASE32_ORD: [u8; 256] = { }; /// Returns decoded input -pub fn decode(input: impl AsRef<[u8]>) -> Result, Nixbase32DecodeError> { +pub fn decode(input: impl AsRef<[u8]>) -> Result, DecodeError> { let input = input.as_ref(); let output_len = decode_len(input.len()); @@ -79,13 +68,14 @@ pub fn decode(input: impl AsRef<[u8]>) -> Result, Nixbase32DecodeError> Ok(output) } -pub fn decode_fixed( - input: impl AsRef<[u8]>, -) -> Result<[u8; K], Nixbase32DecodeError> { +pub fn decode_fixed(input: impl AsRef<[u8]>) -> Result<[u8; K], DecodeError> { let input = input.as_ref(); if input.len() != encode_len(K) { - return Err(Nixbase32DecodeError::InvalidLength); + return Err(DecodeError { + position: input.len().min(encode_len(K)), + kind: DecodeKind::Length, + }); } let mut output = [0; K]; @@ -93,7 +83,7 @@ pub fn decode_fixed( Ok(output) } -fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), Nixbase32DecodeError> { +fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), DecodeError> { // loop over all characters in reverse, and keep the iteration count in n. let mut carry = 0; let mut mask = 0; @@ -111,22 +101,27 @@ fn decode_inner(input: &[u8], output: &mut [u8]) -> Result<(), Nixbase32DecodeEr } if mask == 0xFF { - let c = find_invalid(input); - return Err(Nixbase32DecodeError::CharacterNotInAlphabet(c)); + return Err(DecodeError { + position: find_invalid(input), + kind: DecodeKind::Symbol, + }); } // if we're at the end, but have a nonzero carry, the encoding is invalid. if carry != 0 { - return Err(Nixbase32DecodeError::NonzeroCarry); + return Err(DecodeError { + position: 0, + kind: DecodeKind::Trailing, + }); } Ok(()) } -fn find_invalid(input: &[u8]) -> u8 { - for &c in input { +fn find_invalid(input: &[u8]) -> usize { + for (i, &c) in input.iter().enumerate() { if !ALPHABET.contains(&c) { - return c; + return i; } } @@ -187,7 +182,10 @@ mod tests { ); assert_eq!( super::decode_fixed::<32>("00").unwrap_err(), - super::Nixbase32DecodeError::InvalidLength + super::DecodeError { + position: 2, + kind: super::DecodeKind::Length + } ); } diff --git a/tvix/nix-compat/src/nixhash/mod.rs b/tvix/nix-compat/src/nixhash/mod.rs index d2c1d0bd20..f699a4cd95 100644 --- a/tvix/nix-compat/src/nixhash/mod.rs +++ b/tvix/nix-compat/src/nixhash/mod.rs @@ -92,7 +92,7 @@ pub enum Error { #[error("invalid base16 encoding: {0}")] InvalidBase16Encoding(data_encoding::DecodeError), #[error("invalid base32 encoding: {0}")] - InvalidBase32Encoding(nixbase32::Nixbase32DecodeError), + InvalidBase32Encoding(data_encoding::DecodeError), #[error("invalid base64 encoding: {0}")] InvalidBase64Encoding(data_encoding::DecodeError), #[error("conflicting hash algo: {0} (hash_algo) vs {1} (inline)")] diff --git a/tvix/nix-compat/src/store_path/mod.rs b/tvix/nix-compat/src/store_path/mod.rs index fe4cf9f583..3eb8877d6e 100644 --- a/tvix/nix-compat/src/store_path/mod.rs +++ b/tvix/nix-compat/src/store_path/mod.rs @@ -1,5 +1,5 @@ -use crate::nixbase32::{self, Nixbase32DecodeError}; -use data_encoding::BASE64; +use crate::nixbase32; +use data_encoding::{DecodeError, BASE64}; use std::{ fmt, path::PathBuf, @@ -28,7 +28,7 @@ pub enum Error { #[error("Dash is missing between hash and name")] MissingDash, #[error("Hash encoding is invalid: {0}")] - InvalidHashEncoding(Nixbase32DecodeError), + InvalidHashEncoding(DecodeError), #[error("Invalid length")] InvalidLength, #[error( -- cgit 1.4.1