diff --git a/src/lib.rs b/src/lib.rs index 635ad9b..908d3e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ pub const KSUID_EPOCH: i64 = 1_400_000_000; const BASE_62_CHARS: &[u8; 62] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const TOTAL_BYTES: usize = 20; +const TOTAL_BYTES_BASE62: usize = 27; #[derive(Debug)] pub struct Error(String); @@ -237,6 +238,12 @@ pub trait KsuidLike { /// /// ``` fn from_base62(s: &str) -> Result { + if s.len() != TOTAL_BYTES_BASE62 { + return Err(Error(format!( + "Got base62 ksuid of unexpected length {}", + s.len() + ))); + } if let Some(loaded) = base_encode::from_str(s, 62, BASE_62_CHARS) { // Get the last TOTAL_BYTES let loaded = if loaded.len() > TOTAL_BYTES { diff --git a/tests/integration.rs b/tests/integration.rs index a109a9a..9cfabb7 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -203,3 +203,15 @@ fn test_deserialize_from_base62() { assert_eq!(ksuid_obj.id.to_string(), b62); assert_eq!(ksuidms_obj.id.to_string(), b62); } + +#[test] +fn test_deserialize_bad_base62_length() { + let short_b62 = "ZBpBUvZwXKQmoEYga2"; + let long_b62 = "1srOrx2ZWZBpBUvZwXKQmoEYga21srOrx2ZWZBpBUvZwXKQmoEYga2"; + + let result = Ksuid::from_base62(short_b62); + assert!(result.is_err(), "Short base62 strings should fail to parse"); + + let result = Ksuid::from_base62(long_b62); + assert!(result.is_err(), "Long base62 strings should fail to parse"); +}