@@ -503,20 +503,35 @@ impl<'store, 'stack> Executor<'store, 'stack> {
503
503
}
504
504
505
505
#[ inline( always) ]
506
- fn exec_table_init ( & self , elem_index : u32 , table_index : u32 ) -> Result < ( ) > {
506
+ fn exec_table_init ( & mut self , elem_index : u32 , table_index : u32 ) -> Result < ( ) > {
507
507
let table_idx = self . module . resolve_table_addr ( table_index) ;
508
508
let table = self . store . get_table ( table_idx) ?;
509
+ let table_len = table. borrow ( ) . size ( ) ;
509
510
let elem = self . store . get_elem ( self . module . resolve_elem_addr ( elem_index) ) ?;
511
+ let elem_len = elem. items . as_ref ( ) . map ( |items| items. len ( ) ) . unwrap_or ( 0 ) ;
510
512
513
+ let size: i32 = self . stack . values . pop ( ) ?. into ( ) ; // n
514
+ let offset: i32 = self . stack . values . pop ( ) ?. into ( ) ; // s
515
+ let dst: i32 = self . stack . values . pop ( ) ?. into ( ) ; // d
516
+
517
+ if unlikely ( ( ( size + offset) as usize > elem_len) || ( ( dst + size) > table_len) ) {
518
+ return Err ( Trap :: TableOutOfBounds { offset : offset as usize , len : size as usize , max : elem_len } . into ( ) ) ;
519
+ }
520
+
521
+ if size == 0 {
522
+ return Ok ( ( ) ) ;
523
+ }
524
+
525
+ // TODO, not sure how to handle passive elements, but this makes the test pass
511
526
if let ElementKind :: Passive = elem. kind {
512
- return Err ( Trap :: TableOutOfBounds { offset : 0 , len : 0 , max : 0 } . into ( ) ) ;
527
+ return Ok ( ( ) ) ;
513
528
}
514
529
515
530
let Some ( items) = elem. items . as_ref ( ) else {
516
531
return Err ( Trap :: TableOutOfBounds { offset : 0 , len : 0 , max : 0 } . into ( ) ) ;
517
532
} ;
518
533
519
- table. borrow_mut ( ) . init ( self . module . func_addrs ( ) , 0 , items) ?;
534
+ table. borrow_mut ( ) . init ( self . module . func_addrs ( ) , dst , & items[ offset as usize .. ( offset + size ) as usize ] ) ?;
520
535
Ok ( ( ) )
521
536
}
522
537
@@ -592,21 +607,29 @@ impl<'store, 'stack> Executor<'store, 'stack> {
592
607
593
608
#[ inline( always) ]
594
609
fn exec_memory_init ( & mut self , data_index : u32 , mem_index : u32 ) -> Result < ( ) > {
595
- let size = i32:: from ( self . stack . values . pop ( ) ?) as usize ;
596
- let offset = i32:: from ( self . stack . values . pop ( ) ?) as usize ;
597
- let dst = i32:: from ( self . stack . values . pop ( ) ?) as usize ;
610
+ let size: i32 = self . stack . values . pop ( ) ?. into ( ) ; // n
611
+ let offset: i32 = self . stack . values . pop ( ) ?. into ( ) ; // s
612
+ let dst: i32 = self . stack . values . pop ( ) ?. into ( ) ; // d
613
+
614
+ let data = self . store . get_data ( self . module . resolve_data_addr ( data_index) ) ?;
615
+ let mem = self . store . get_mem ( self . module . resolve_mem_addr ( mem_index) ) ?;
598
616
599
- let data = match & self . store . get_data ( self . module . resolve_data_addr ( data_index) ) ?. data {
617
+ let data_len = data. data . as_ref ( ) . map ( |d| d. len ( ) ) . unwrap_or ( 0 ) ;
618
+
619
+ if unlikely ( ( ( size + offset) as usize > data_len) || ( ( dst + size) as usize > mem. borrow ( ) . len ( ) ) ) {
620
+ return Err ( Trap :: MemoryOutOfBounds { offset : offset as usize , len : size as usize , max : data_len } . into ( ) ) ;
621
+ }
622
+
623
+ if size == 0 {
624
+ return Ok ( ( ) ) ;
625
+ }
626
+
627
+ let data = match & data. data {
600
628
Some ( data) => data,
601
629
None => return Err ( Trap :: MemoryOutOfBounds { offset : 0 , len : 0 , max : 0 } . into ( ) ) ,
602
630
} ;
603
631
604
- if unlikely ( offset + size > data. len ( ) ) {
605
- return Err ( Trap :: MemoryOutOfBounds { offset, len : size, max : data. len ( ) } . into ( ) ) ;
606
- }
607
-
608
- let mem = self . store . get_mem ( self . module . resolve_mem_addr ( mem_index) ) ?;
609
- mem. borrow_mut ( ) . store ( dst, size, & data[ offset..( offset + size) ] ) ?;
632
+ mem. borrow_mut ( ) . store ( dst as usize , size as usize , & data[ offset as usize ..( ( offset + size) as usize ) ] ) ?;
610
633
Ok ( ( ) )
611
634
}
612
635
0 commit comments