@@ -215,6 +215,9 @@ impl<'a> ExactSizeIterator for Decode<'a> {
215215/// This is a convenience wrapper around `encode`.
216216#[ inline]
217217pub fn encode_str ( input : & str ) -> Option < String > {
218+ if input. len ( ) > u32:: MAX as usize {
219+ return None ;
220+ }
218221 let mut buf = String :: with_capacity ( input. len ( ) ) ;
219222 encode_into ( input. chars ( ) , & mut buf) . ok ( ) . map ( |( ) | buf)
220223}
@@ -224,6 +227,9 @@ pub fn encode_str(input: &str) -> Option<String> {
224227/// Return None on overflow, which can only happen on inputs that would take more than
225228/// 63 encoded bytes, the DNS limit on domain name labels.
226229pub fn encode ( input : & [ char ] ) -> Option < String > {
230+ if input. len ( ) > u32:: MAX as usize {
231+ return None ;
232+ }
227233 let mut buf = String :: with_capacity ( input. len ( ) ) ;
228234 encode_into ( input. iter ( ) . copied ( ) , & mut buf)
229235 . ok ( )
@@ -235,9 +241,9 @@ where
235241 I : Iterator < Item = char > + Clone ,
236242{
237243 // Handle "basic" (ASCII) code points. They are encoded as-is.
238- let ( mut input_length, mut basic_length) = ( 0 , 0 ) ;
244+ let ( mut input_length, mut basic_length) = ( 0u32 , 0 ) ;
239245 for c in input. clone ( ) {
240- input_length += 1 ;
246+ input_length = input_length . checked_add ( 1 ) . ok_or ( ( ) ) ? ;
241247 if c. is_ascii ( ) {
242248 output. push ( c) ;
243249 basic_length += 1 ;
@@ -311,3 +317,12 @@ fn value_to_digit(value: u32) -> char {
311317 _ => panic ! ( ) ,
312318 }
313319}
320+
321+ #[ test]
322+ #[ ignore = "slow" ]
323+ #[ cfg( target_pointer_width = "64" ) ]
324+ fn huge_encode ( ) {
325+ let mut buf = String :: new ( ) ;
326+ assert ! ( encode_into( std:: iter:: repeat( 'ß' ) . take( u32 :: MAX as usize + 1 ) , & mut buf) . is_err( ) ) ;
327+ assert_eq ! ( buf. len( ) , 0 ) ;
328+ }
0 commit comments