Skip to content

Commit c517814

Browse files
authored
Merge pull request #7 from Racum/number-overflow
Fix u64 overflow when decoding
2 parents 8e40263 + c1d4240 commit c517814

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG
22

3+
**v0.4.2:**
4+
- Fix u64 overflow
5+
36
**v0.4.1:**
47
- Derive `Clone` trait [[PR #6](https://github.com/sqids/sqids-rust/pull/6)]
58
- Cargo update

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "Generate short unique ids from numbers."
44
repository = "https://github.com/sqids/sqids-rust"
55
documentation = "https://docs.rs/sqids"
66
homepage = "https://sqids.org/rust"
7-
version = "0.4.1"
7+
version = "0.4.2"
88
license = "MIT"
99
edition = "2021"
1010
readme = "README.md"

src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,9 @@ 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+
if let Some(value) = self.to_number(chunks[0], &alphabet_without_separator) {
255+
ret.push(value)
256+
}
255257

256258
if chunks.len() > 1 {
257259
alphabet = Self::shuffle(&alphabet);
@@ -332,15 +334,19 @@ impl Sqids {
332334
id.into_iter().collect()
333335
}
334336

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

338340
for c in id.chars() {
339341
let idx = alphabet.iter().position(|&x| x == c).unwrap();
340-
result = result * alphabet.len() as u64 + idx as u64;
342+
result = result * alphabet.len() as u128 + idx as u128;
341343
}
342344

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

346352
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)