@@ -373,6 +373,10 @@ impl ComponentTypes {
373373 /// not encodable in flat types, the values are all lowered to memory, implied by
374374 /// the empty storage
375375 pub fn flat_types_storage ( & self , ty : & InterfaceType , limit : usize ) -> FlatTypesStorage {
376+ assert ! (
377+ limit <= MAX_FLAT_TYPES ,
378+ "limit exceeding maximum flat types not allowed"
379+ ) ;
376380 self . flat_types_storage_inner ( ty, limit)
377381 . unwrap_or_else ( || FlatTypesStorage :: new ( ) )
378382 }
@@ -385,7 +389,7 @@ impl ComponentTypes {
385389 // Helper routines
386390 let push = |storage : & mut FlatTypesStorage , t32 : FlatType , t64 : FlatType | -> bool {
387391 storage. push ( t32, t64) ;
388- ( storage. len as usize ) < limit
392+ ( storage. len as usize ) <= limit
389393 } ;
390394
391395 let push_discrim = |storage : & mut FlatTypesStorage | -> bool {
@@ -394,64 +398,62 @@ impl ComponentTypes {
394398
395399 let push_storage =
396400 |storage : & mut FlatTypesStorage , other : Option < FlatTypesStorage > | -> bool {
397- if let Some ( other) = other {
398- let len = usize:: from ( storage. len ) ;
399- let other_len = usize:: from ( other. len ) ;
400- if len + other_len <= limit {
401- storage. memory32 [ len..len + other_len]
402- . copy_from_slice ( & other. memory32 [ ..other_len] ) ;
403- storage. memory64 [ len..len + other_len]
404- . copy_from_slice ( & other. memory64 [ ..other_len] ) ;
405- storage. len += other. len ;
406- true
407- } else {
408- false
409- }
410- } else {
411- false
412- }
401+ other
402+ . and_then ( |other| {
403+ let len = usize:: from ( storage. len ) ;
404+ let other_len = usize:: from ( other. len ) ;
405+ ( len + other_len <= limit) . then ( || {
406+ storage. memory32 [ len..len + other_len]
407+ . copy_from_slice ( & other. memory32 [ ..other_len] ) ;
408+ storage. memory64 [ len..len + other_len]
409+ . copy_from_slice ( & other. memory64 [ ..other_len] ) ;
410+ storage. len += other. len ;
411+ } )
412+ } )
413+ . is_some ( )
413414 } ;
414415
416+ // Case is broken down as:
417+ // * None => No field
418+ // * Some(None) => Invalid storage (overflow)
419+ // * Some(storage) => Valid storage
415420 let push_storage_variant_case =
416421 |storage : & mut FlatTypesStorage , case : Option < Option < FlatTypesStorage > > | -> bool {
417- if let Some ( case) = case {
418- if let Some ( case) = case {
419- // Discriminant will make size[case] = limit overshoot
420- if case. len as usize >= limit {
421- false
422- } else {
423- // Skip 1 for discriminant
424- let dst = storage
425- . memory32
426- . iter_mut ( )
427- . zip ( & mut storage. memory64 )
428- . skip ( 1 ) ;
429- for ( i, ( ( t32, t64) , ( dst32, dst64) ) ) in case
430- . memory32
431- . iter ( )
432- . take ( case. len as usize )
433- . zip ( case. memory64 . iter ( ) )
434- . zip ( dst)
435- . enumerate ( )
436- {
437- if i + 1 < usize:: from ( storage. len ) {
438- // Populated Index
439- dst32. join ( * t32) ;
440- dst64. join ( * t64) ;
441- } else {
442- // New Index
443- storage. len += 1 ;
444- * dst32 = * t32;
445- * dst64 = * t64;
422+ match case {
423+ None => true ,
424+ Some ( case) => {
425+ case. and_then ( |case| {
426+ // Discriminant will make size[case] = limit overshoot
427+ ( ( 1 + case. len as usize ) <= limit) . then ( || {
428+ // Skip 1 for discriminant
429+ let dst = storage
430+ . memory32
431+ . iter_mut ( )
432+ . zip ( & mut storage. memory64 )
433+ . skip ( 1 ) ;
434+ for ( i, ( ( t32, t64) , ( dst32, dst64) ) ) in case
435+ . memory32
436+ . iter ( )
437+ . take ( case. len as usize )
438+ . zip ( case. memory64 . iter ( ) )
439+ . zip ( dst)
440+ . enumerate ( )
441+ {
442+ if i + 1 < usize:: from ( storage. len ) {
443+ // Populated Index
444+ dst32. join ( * t32) ;
445+ dst64. join ( * t64) ;
446+ } else {
447+ // New Index
448+ storage. len += 1 ;
449+ * dst32 = * t32;
450+ * dst64 = * t64;
451+ }
446452 }
447- }
448- true
449- }
450- } else {
451- true
453+ } )
454+ } )
455+ . is_some ( )
452456 }
453- } else {
454- false
455457 }
456458 } ;
457459
@@ -509,7 +511,7 @@ impl ComponentTypes {
509511 }
510512 InterfaceType :: Option ( i) => {
511513 push_discrim ( storage)
512- && push_storage_variant_case ( storage, Some ( None ) )
514+ && push_storage_variant_case ( storage, None )
513515 && push_storage_variant_case (
514516 storage,
515517 Some ( self . flat_types_storage_inner ( & self [ * i] . ty , limit) ) ,
0 commit comments