Skip to content

Commit ce5e2f2

Browse files
committed
Fix SpotifyId base 62 and 16 str decoding
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.
1 parent c37ec8c commit ce5e2f2

1 file changed

Lines changed: 37 additions & 4 deletions

File tree

core/src/spotify_id.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ impl SpotifyId {
9898
///
9999
/// [Spotify ID]: https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids
100100
pub fn from_base16(src: &str) -> SpotifyIdResult {
101+
if src.len() != 32 {
102+
return Err(SpotifyIdError::InvalidId.into());
103+
}
101104
let mut dst: u128 = 0;
102105

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

128134
for c in src.as_bytes() {
@@ -133,8 +139,8 @@ impl SpotifyId {
133139
_ => return Err(SpotifyIdError::InvalidId.into()),
134140
} as u128;
135141

136-
dst *= 62;
137-
dst += p;
142+
dst = dst.checked_mul(62).ok_or(SpotifyIdError::InvalidId)?;
143+
dst = dst.checked_add(p).ok_or(SpotifyIdError::InvalidId)?;
138144
}
139145

140146
Ok(Self {
@@ -606,7 +612,7 @@ mod tests {
606612
},
607613
];
608614

609-
static CONV_INVALID: [ConversionCase; 3] = [
615+
static CONV_INVALID: [ConversionCase; 5] = [
610616
ConversionCase {
611617
id: 0,
612618
kind: SpotifyItemType::Unknown,
@@ -631,13 +637,40 @@ mod tests {
631637
154, 27, 28, 251,
632638
],
633639
},
640+
ConversionCase {
641+
id: 0,
642+
kind: SpotifyItemType::Unknown,
643+
// Uri too short
644+
uri: "spotify:azb:aRS48xBl0tH",
645+
// too long, should return error but not panic overflow
646+
base16: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
647+
// too long, should return error but not panic overflow
648+
base62: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
649+
raw: &[
650+
// Invalid length.
651+
154, 27, 28, 251,
652+
],
653+
},
634654
ConversionCase {
635655
id: 0,
636656
kind: SpotifyItemType::Unknown,
637657
// Uri too short
638658
uri: "spotify:azb:aRS48xBl0tH",
639659
base16: "--------------------",
640-
base62: "....................",
660+
// too short to encode a 128 bits int
661+
base62: "aa",
662+
raw: &[
663+
// Invalid length.
664+
154, 27, 28, 251,
665+
],
666+
},
667+
ConversionCase {
668+
id: 0,
669+
kind: SpotifyItemType::Unknown,
670+
uri: "cleary invalid uri",
671+
base16: "--------------------",
672+
// too high of a value, this would need a 132 bits int
673+
base62: "ZZZZZZZZZZZZZZZZZZZZZZ",
641674
raw: &[
642675
// Invalid length.
643676
154, 27, 28, 251,

0 commit comments

Comments
 (0)