@@ -63,6 +63,10 @@ impl Default for Gatekeeper {
6363        Self :: new ( GatekeeperConfig  { 
6464            allow_floats :  true , 
6565            allow_feature_bulk_memory_operations :  false , 
66+             // we allow the reference types proposal during compatibility checking because a subset 
67+             // of it is required since Rust 1.82, but we don't allow any of the instructions specific 
68+             // to the proposal here. Especially `table.grow` and `table.fill` can be abused to cause 
69+             // very long runtime and high memory usage. 
6670            allow_feature_reference_types :  false , 
6771            allow_feature_simd :  false , 
6872            allow_feature_exception_handling :  false , 
@@ -444,4 +448,52 @@ mod tests {
444448            . to_string( ) 
445449            . contains( "Bulk memory operation" ) ) ; 
446450    } 
451+ 
452+     #[ test]  
453+     fn  bulk_table_operations_not_supported ( )  { 
454+         // these operations can take a long time with big tables 
455+         let  deterministic = Arc :: new ( Gatekeeper :: default ( ) ) ; 
456+         let  mut  compiler = make_compiler_config ( ) ; 
457+         compiler. push_middleware ( deterministic) ; 
458+         let  store = Store :: new ( compiler) ; 
459+ 
460+         let  wasm = wat:: parse_str ( 
461+             r#" 
462+             (module 
463+                 (table 2 funcref) 
464+                 (func (export "test") (param $i i32) (result i32) 
465+                     ;; grow table to size of $i 
466+                     ref.null func 
467+                     local.get $i 
468+                     table.grow 0)) 
469+             "# , 
470+         ) 
471+         . unwrap ( ) ; 
472+ 
473+         let  result = Module :: new ( & store,  wasm) ; 
474+         assert ! ( result
475+             . unwrap_err( ) 
476+             . to_string( ) 
477+             . contains( "Reference type operation" ) ) ; 
478+ 
479+         let  wasm = wat:: parse_str ( 
480+             r#" 
481+             (module 
482+                 (table 1000000 funcref) 
483+                 (func (export "test") (param $i i32) 
484+                     ;; fill with nulls 
485+                     i32.const 0 
486+                     ref.null func 
487+                     i32.const 1000000 
488+                     table.fill 0)) 
489+             "# , 
490+         ) 
491+         . unwrap ( ) ; 
492+ 
493+         let  result = Module :: new ( & store,  wasm) ; 
494+         assert ! ( result
495+             . unwrap_err( ) 
496+             . to_string( ) 
497+             . contains( "Reference type operation" ) ) ; 
498+     } 
447499} 
0 commit comments