Skip to content

Commit 9002322

Browse files
Orycteropes3bk
authored andcommitted
fix panic on overflowing ascii85 decode
Found this bug while fuzzing the crate The range of values that an ascii85 character can take is slightly bigger than what fits in a u32. If a, b, c, d, and e are very high, the multiplication will result in a number that cannot be represented as a u32. This should be considered as a decoding error, but the code didn't check for this case and panicked. Do the computation in a u64 instead, and try to cast it to a u32 at the very end, returning None if the value is invalid.
1 parent 6c5c86a commit 9002322

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

pdf/src/enc.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate as pdf;
77
use crate::error::*;
88
use crate::object::{Object, Resolve, Stream};
99
use crate::primitive::{Primitive, Dictionary};
10-
use std::convert::TryInto;
10+
use std::convert::{TryFrom, TryInto};
1111
use std::io::{Read, Write};
1212
use once_cell::sync::OnceCell;
1313
use datasize::DataSize;
@@ -168,10 +168,12 @@ fn sym_85(byte: u8) -> Option<u8> {
168168
}
169169

170170
fn word_85([a, b, c, d, e]: [u8; 5]) -> Option<[u8; 4]> {
171-
fn s(b: u8) -> Option<u32> { sym_85(b).map(|n| n as u32) }
171+
fn s(b: u8) -> Option<u64> { sym_85(b).map(|n| n as u64) }
172172
let (a, b, c, d, e) = (s(a)?, s(b)?, s(c)?, s(d)?, s(e)?);
173173
let q = (((a * 85 + b) * 85 + c) * 85 + d) * 85 + e;
174-
Some(q.to_be_bytes())
174+
// 85^5 > 256^4, the result might not fit in an u32.
175+
let r = u32::try_from(q).ok()?;
176+
Some(r.to_be_bytes())
175177
}
176178

177179
pub fn decode_85(data: &[u8]) -> Result<Vec<u8>> {

0 commit comments

Comments
 (0)