Skip to content

Commit 78501e1

Browse files
committed
Fix some panics uncovered via fuzzing
Closes #9
1 parent 48646c6 commit 78501e1

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

src/lib.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,36 @@ pub fn demangle(mut s: &str) -> Demangle {
117117
valid = false;
118118
}
119119

120+
// only work with ascii text
121+
if inner.bytes().any(|c| c & 0x80 != 0) {
122+
valid = false;
123+
}
124+
120125
let mut elements = 0;
121126
if valid {
122-
let mut chars = inner.chars();
127+
let mut chars = inner.chars().peekable();
123128
while valid {
124-
let mut i = 0;
125-
for c in chars.by_ref() {
126-
if c.is_digit(10) {
127-
i = i * 10 + c as usize - '0' as usize;
128-
} else {
129-
break;
129+
let mut i = 0usize;
130+
while let Some(&c) = chars.peek() {
131+
if !c.is_digit(10) {
132+
break
130133
}
134+
chars.next();
135+
let next = i.checked_mul(10)
136+
.and_then(|i| i.checked_add(c as usize - '0' as usize));
137+
i = match next {
138+
Some(i) => i,
139+
None => {
140+
valid = false;
141+
break
142+
}
143+
};
131144
}
145+
132146
if i == 0 {
133147
valid = chars.next().is_none();
134148
break;
135-
} else if chars.by_ref().take(i - 1).count() != i - 1 {
149+
} else if chars.by_ref().take(i).count() != i {
136150
valid = false;
137151
} else {
138152
elements += 1;
@@ -383,4 +397,16 @@ mod tests {
383397
t!("_ZN3fooE.llvm.9D1C9369", "foo");
384398
t_nohash!("_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", "backtrace::foo");
385399
}
400+
401+
#[test]
402+
fn dont_panic() {
403+
super::demangle("_ZN2222222222222222222222EE").to_string();
404+
super::demangle("_ZN5*70527e27.ll34csaғE").to_string();
405+
super::demangle("_ZN5*70527a54.ll34_$b.1E").to_string();
406+
super::demangle("\
407+
_ZN5~saäb4e\n\
408+
2734cOsbE\n\
409+
5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\
410+
").to_string();
411+
}
386412
}

0 commit comments

Comments
 (0)