|
|
@@ -215,6 +215,9 @@ impl<'a> ExactSizeIterator for Decode<'a> {
|
|
|
/// This is a convenience wrapper around `encode`.
|
|
|
#[inline]
|
|
|
pub fn encode_str(input: &str) -> Option<String> {
|
|
|
+ if input.len() > u32::MAX as usize {
|
|
|
+ return None;
|
|
|
+ }
|
|
|
let mut buf = String::with_capacity(input.len());
|
|
|
encode_into(input.chars(), &mut buf).ok().map(|()| buf)
|
|
|
}
|
|
|
@@ -224,6 +227,9 @@ pub fn encode_str(input: &str) -> Option<String> {
|
|
|
/// Return None on overflow, which can only happen on inputs that would take more than
|
|
|
/// 63 encoded bytes, the DNS limit on domain name labels.
|
|
|
pub fn encode(input: &[char]) -> Option<String> {
|
|
|
+ if input.len() > u32::MAX as usize {
|
|
|
+ return None;
|
|
|
+ }
|
|
|
let mut buf = String::with_capacity(input.len());
|
|
|
encode_into(input.iter().copied(), &mut buf)
|
|
|
.ok()
|
|
|
@@ -235,9 +241,9 @@ where
|
|
|
I: Iterator<Item = char> + Clone,
|
|
|
{
|
|
|
// Handle "basic" (ASCII) code points. They are encoded as-is.
|
|
|
- let (mut input_length, mut basic_length) = (0, 0);
|
|
|
+ let (mut input_length, mut basic_length) = (0u32, 0);
|
|
|
for c in input.clone() {
|
|
|
- input_length += 1;
|
|
|
+ input_length = input_length.checked_add(1).ok_or(())?;
|
|
|
if c.is_ascii() {
|
|
|
output.push(c);
|
|
|
basic_length += 1;
|
|
|
@@ -311,3 +317,12 @@ fn value_to_digit(value: u32) -> char {
|
|
|
_ => panic!(),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#[test]
|
|
|
+#[ignore = "slow"]
|
|
|
+#[cfg(target_pointer_width = "64")]
|
|
|
+fn huge_encode() {
|
|
|
+ let mut buf = String::new();
|
|
|
+ assert!(encode_into(std::iter::repeat('ß').take(u32::MAX as usize + 1), &mut buf).is_err());
|
|
|
+ assert_eq!(buf.len(), 0);
|
|
|
+}
|