@@ -11,6 +11,17 @@ use crate::lib::std::vec::Vec;
11
11
use crate :: traits:: { InputLength , InputTake , ToUsize } ;
12
12
use core:: num:: NonZeroUsize ;
13
13
14
+ /// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`.
15
+ ///
16
+ /// Pre-allocating memory is a nice optimization but count fields can't
17
+ /// always be trusted. We should clamp initial capacities to some reasonable
18
+ /// amount. This reduces the risk of a bogus count value triggering a panic
19
+ /// due to an OOM error.
20
+ ///
21
+ /// This does not affect correctness. Nom will always read the full number
22
+ /// of elements regardless of the capacity cap.
23
+ const MAX_INITIAL_CAPACITY : usize = 65536 ;
24
+
14
25
/// Repeats the embedded parser until it fails
15
26
/// and returns the results in a `Vec`.
16
27
///
@@ -362,7 +373,7 @@ where
362
373
return Err ( Err :: Failure ( E :: from_error_kind ( input, ErrorKind :: ManyMN ) ) ) ;
363
374
}
364
375
365
- let mut res = crate :: lib:: std:: vec:: Vec :: with_capacity ( min) ;
376
+ let mut res = crate :: lib:: std:: vec:: Vec :: with_capacity ( min. clamp ( 0 , MAX_INITIAL_CAPACITY ) ) ;
366
377
for count in 0 ..max {
367
378
let len = input. input_len ( ) ;
368
379
match parse. parse ( input. clone ( ) ) {
@@ -529,7 +540,7 @@ where
529
540
{
530
541
move |i : I | {
531
542
let mut input = i. clone ( ) ;
532
- let mut res = crate :: lib:: std:: vec:: Vec :: with_capacity ( count) ;
543
+ let mut res = crate :: lib:: std:: vec:: Vec :: with_capacity ( count. clamp ( 0 , MAX_INITIAL_CAPACITY ) ) ;
533
544
534
545
for _ in 0 ..count {
535
546
let input_ = input. clone ( ) ;
0 commit comments