1use alloc::vec::Vec;
2
3use crate::{
4 core::{
5 indices::MemIdx,
6 reader::{
7 section_header::{SectionHeader, SectionTy},
8 types::{
9 data::{DataMode, DataModeActive, DataSegment},
10 global::GlobalType,
11 },
12 WasmReader,
13 },
14 },
15 read_constant_expression::read_constant_expression,
16 validation_stack::ValidationStack,
17 ValidationError,
18};
19
20pub(super) fn validate_data_section(
22 wasm: &mut WasmReader,
23 section_header: SectionHeader,
24 imported_global_types: &[GlobalType],
25 no_of_total_memories: usize,
26 num_funcs: usize,
27) -> Result<Vec<DataSegment>, ValidationError> {
28 assert_eq!(section_header.ty, SectionTy::Data);
29
30 wasm.read_vec(|wasm| {
31 use crate::{NumType, ValType};
32 let mode = wasm.read_var_u32()?;
33 let data_sec: DataSegment = match mode {
34 0 => {
35 trace!("Data section: active {{ memory 0, offset e }}");
37
38 if no_of_total_memories == 0 {
39 return Err(ValidationError::UnknownMemory);
40 }
41
42 let mut valid_stack = ValidationStack::new();
43 let (offset, _) = {
44 read_constant_expression(
45 wasm,
46 &mut valid_stack,
47 imported_global_types,
48 num_funcs,
49 )?
50 };
51
52 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
53
54 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
55
56 DataSegment {
58 mode: DataMode::Active(DataModeActive {
59 memory_idx: 0,
60 offset,
61 }),
62 init: byte_vec,
63 }
64 }
65 1 => {
66 trace!("Data section: passive");
69 DataSegment {
70 mode: DataMode::Passive,
71 init: wasm.read_vec(|el| el.read_u8())?,
72 }
73 }
74 2 => {
75 trace!("Data section: active {{ memory x, offset e }}");
76 let mem_idx = wasm.read_var_u32()? as MemIdx;
77 if mem_idx >= no_of_total_memories {
78 return Err(crate::ValidationError::UnknownMemory);
79 }
80 assert!(
81 mem_idx == 0,
82 "Memory index is not 0 - it's {mem_idx}! Multiple memories are NOT supported"
83 );
84
85 let mut valid_stack = ValidationStack::new();
86 let (offset, _) = {
87 read_constant_expression(
88 wasm,
89 &mut valid_stack,
90 imported_global_types,
91 num_funcs,
92 )?
93 };
94
95 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
96
97 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
98
99 DataSegment {
100 mode: DataMode::Active(DataModeActive {
101 memory_idx: 0,
102 offset,
103 }),
104 init: byte_vec,
105 }
106 }
114 _ => unreachable!(),
115 };
116
117 trace!("{:?}", data_sec.init);
118 Ok(data_sec)
119 })
120}