1use alloc::vec::Vec;
2
3use crate::{
4 core::{
5 indices::{FuncIdx, IdxVec, MemIdx, TypeIdx},
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 MemType, ValidationError,
18};
19
20pub(super) fn validate_data_section(
22 wasm: &mut WasmReader,
23 section_header: SectionHeader,
24 imported_global_types: &[GlobalType],
25 c_funcs: &IdxVec<FuncIdx, TypeIdx>,
26 c_mems: &IdxVec<MemIdx, MemType>,
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 let _mem_idx = MemIdx::validate(0, c_mems)?;
39
40 let mut valid_stack = ValidationStack::new();
41 let (offset, _) = {
42 read_constant_expression(
43 wasm,
44 &mut valid_stack,
45 imported_global_types,
46 c_funcs,
47 )?
48 };
49
50 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
51
52 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
53
54 DataSegment {
56 mode: DataMode::Active(DataModeActive {
57 memory_idx: MemIdx::validate(0, c_mems)?,
58 offset,
59 }),
60 init: byte_vec,
61 }
62 }
63 1 => {
64 trace!("Data section: passive");
67 DataSegment {
68 mode: DataMode::Passive,
69 init: wasm.read_vec(|el| el.read_u8())?,
70 }
71 }
72 2 => {
73 trace!("Data section: active {{ memory x, offset e }}");
74 let mem_idx = MemIdx::read_and_validate(wasm, c_mems)?;
75
76 let mut valid_stack = ValidationStack::new();
77 let (offset, _) = {
78 read_constant_expression(
79 wasm,
80 &mut valid_stack,
81 imported_global_types,
82 c_funcs,
83 )?
84 };
85
86 valid_stack.assert_val_types(&[ValType::NumType(NumType::I32)], true)?;
87
88 let byte_vec = wasm.read_vec(|el| el.read_u8())?;
89
90 DataSegment {
91 mode: DataMode::Active(DataModeActive {
92 memory_idx: mem_idx,
93 offset,
94 }),
95 init: byte_vec,
96 }
97 }
105 invalid_mode @ 3.. => {
106 return Err(ValidationError::InvalidDataSegmentMode(invalid_mode))
107 }
108 };
109
110 trace!("{:?}", data_sec.init);
111 Ok(data_sec)
112 })
113}