Skip to content

Commit 9e14fd0

Browse files
committed
Add check for u64 overflows
1 parent 8e40263 commit 9e14fd0

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ impl Sqids {
251251

252252
let alphabet_without_separator: Vec<char> =
253253
alphabet.iter().copied().skip(1).collect();
254-
ret.push(self.to_number(chunks[0], &alphabet_without_separator));
254+
match self.to_number(chunks[0], &alphabet_without_separator) {
255+
Some(value) => ret.push(value),
256+
None => (),
257+
}
255258

256259
if chunks.len() > 1 {
257260
alphabet = Self::shuffle(&alphabet);
@@ -332,15 +335,19 @@ impl Sqids {
332335
id.into_iter().collect()
333336
}
334337

335-
fn to_number(&self, id: &str, alphabet: &[char]) -> u64 {
338+
fn to_number(&self, id: &str, alphabet: &[char]) -> Option<u64> {
336339
let mut result = 0;
337340

338341
for c in id.chars() {
339342
let idx = alphabet.iter().position(|&x| x == c).unwrap();
340-
result = result * alphabet.len() as u64 + idx as u64;
343+
result = result * alphabet.len() as u128 + idx as u128;
341344
}
342345

343-
result
346+
if result <= u64::MAX.into() {
347+
Some(result.try_into().unwrap())
348+
} else {
349+
None
350+
}
344351
}
345352

346353
fn shuffle(alphabet: &[char]) -> Vec<char> {

tests/decoding.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use sqids::*;
2+
3+
#[test]
4+
fn decode_number_maximum_value() {
5+
let sqids = Sqids::default();
6+
let numbers = sqids.decode("ABARpJzdz9");
7+
assert_eq!(numbers, [9_007_199_254_740_991]); // 2 ^ 53
8+
}
9+
10+
#[test]
11+
fn decode_number_overflows() {
12+
let sqids = Sqids::default();
13+
let numbers = sqids.decode("0J4AEXRN106Z0");
14+
assert_eq!(numbers, Vec::<u64>::new());
15+
}

0 commit comments

Comments
 (0)