Skip to content

Commit 263ddba

Browse files
fix: check for overflows in body::base64::encoded_len
1 parent d2435b9 commit 263ddba

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

src/body/base64.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ pub fn encode(b: &[u8], w: &mut dyn Write) -> fmt::Result {
6161

6262
/// Predict how many bytes [`encode`] is going to write given a `input_len` input length.
6363
///
64+
/// # Panics
65+
///
66+
/// Panics if any of the internal calculations overflow.
67+
///
6468
/// # Examples
6569
///
6670
/// ```rust
@@ -70,15 +74,25 @@ pub fn encode(b: &[u8], w: &mut dyn Write) -> fmt::Result {
7074
/// assert_eq!(encoded_len(300), 410);
7175
/// ```
7276
pub const fn encoded_len(input_len: usize) -> usize {
73-
let mut base64_len = input_len / 3 * 4;
77+
// FIXME: use `Option::expect` with MSRV >= 1.83
78+
macro_rules! checked {
79+
($val:expr) => {
80+
match $val {
81+
Some(val) => val,
82+
None => panic!("overflow"),
83+
}
84+
};
85+
}
86+
87+
let mut base64_len = checked!((input_len / 3).checked_mul(4));
7488
if input_len % 3 != 0 {
75-
base64_len += 4;
89+
base64_len = checked!(base64_len.checked_add(4));
7690
}
7791
let mut crlf_len = base64_len / LINE_LEN * CRLF.len();
7892
if crlf_len >= CRLF.len() && base64_len % LINE_LEN == 0 {
7993
crlf_len -= CRLF.len();
8094
}
81-
base64_len + crlf_len
95+
checked!(base64_len.checked_add(crlf_len))
8296
}
8397

8498
#[cfg(test)]
@@ -176,4 +190,10 @@ mod tests {
176190
);
177191
assert_eq!(output.len(), encoded_len(input.len()));
178192
}
193+
194+
#[test]
195+
#[should_panic(expected = "overflow")]
196+
fn overflow() {
197+
encoded_len(usize::MAX);
198+
}
179199
}

0 commit comments

Comments
 (0)