Skip to content

Commit

Permalink
Fix SpotifyId base 62 and 16 str decoding
Browse files Browse the repository at this point in the history
A SpotifyId is expected to be a 128 bits integer and can be parsed from a
base 62 or 16 string. However the parsing functions only checked the validity of
the characters of the string, but not its length. This could result in integer
overflows or the parsing of incorrect strings as Spotify ids.

This commit add some checks to the length of the input string passed to the
parse functions, and also checks for integer overflows in case of base62
encoded strings.
  • Loading branch information
lelloman committed Jan 3, 2024
1 parent ccd1a72 commit 9024fa8
Showing 1 changed file with 37 additions and 4 deletions.
41 changes: 37 additions & 4 deletions core/src/spotify_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ impl SpotifyId {
///
/// [Spotify ID]: https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids
pub fn from_base16(src: &str) -> SpotifyIdResult {
if src.len() > 32 {
return Err(SpotifyIdError::InvalidId.into());
}
let mut dst: u128 = 0;

for c in src.as_bytes() {
Expand All @@ -127,6 +130,9 @@ impl SpotifyId {
///
/// [Spotify ID]: https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids
pub fn from_base62(src: &str) -> SpotifyIdResult {
if src.len() != 22 {
return Err(SpotifyIdError::InvalidId.into());
}
let mut dst: u128 = 0;

for c in src.as_bytes() {
Expand All @@ -137,8 +143,8 @@ impl SpotifyId {
_ => return Err(SpotifyIdError::InvalidId.into()),
} as u128;

dst *= 62;
dst += p;
dst = dst.checked_mul(62).ok_or(SpotifyIdError::InvalidId)?;
dst = dst.checked_add(p).ok_or(SpotifyIdError::InvalidId)?;
}

Ok(Self {
Expand Down Expand Up @@ -610,7 +616,7 @@ mod tests {
},
];

static CONV_INVALID: [ConversionCase; 3] = [
static CONV_INVALID: [ConversionCase; 5] = [
ConversionCase {
id: 0,
kind: SpotifyItemType::Unknown,
Expand All @@ -635,13 +641,40 @@ mod tests {
154, 27, 28, 251,
],
},
ConversionCase {
id: 0,
kind: SpotifyItemType::Unknown,
// Uri too short
uri: "spotify:azb:aRS48xBl0tH",
// too long, should return error but not panic overflow
base16: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
// too long, should return error but not panic overflow
base62: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
raw: &[
// Invalid length.
154, 27, 28, 251,
],
},
ConversionCase {
id: 0,
kind: SpotifyItemType::Unknown,
// Uri too short
uri: "spotify:azb:aRS48xBl0tH",
base16: "--------------------",
base62: "....................",
// too short to encode a 128 bits int
base62: "aa",
raw: &[
// Invalid length.
154, 27, 28, 251,
],
},
ConversionCase {
id: 0,
kind: SpotifyItemType::Unknown,
uri: "cleary invalid uri",
base16: "--------------------",
// too high of a value, this would need a 132 bits int
base62: "ZZZZZZZZZZZZZZZZZZZZZZ",
raw: &[
// Invalid length.
154, 27, 28, 251,
Expand Down

0 comments on commit 9024fa8

Please sign in to comment.