/build/source/src/validation/modules/indices.rs
Line | Count | Source |
1 | | use crate::{ |
2 | | core::{ |
3 | | decoding::reader::WasmDecoder, |
4 | | structure::modules::indices::{ |
5 | | DataIdx, ElemIdx, FuncIdx, GlobalIdx, Idx, IdxVec, LocalIdx, MemIdx, TableIdx, TypeIdx, |
6 | | }, |
7 | | }, |
8 | | FuncType, ValType, ValidationError, |
9 | | }; |
10 | | |
11 | | impl TypeIdx { |
12 | | /// Validates that a given index is a valid type index. |
13 | | /// |
14 | | /// On success a new [`TypeIdx`] is returned, otherwise a |
15 | | /// [`ValidationError`] is returned. |
16 | 9.57k | pub fn validate( |
17 | 9.57k | index: u32, |
18 | 9.57k | c_types: &IdxVec<TypeIdx, FuncType>, |
19 | 9.57k | ) -> Result<Self, ValidationError> { |
20 | 9.57k | c_types |
21 | 9.57k | .validate_index(index) |
22 | 9.57k | .ok_or(ValidationError::InvalidTypeIdx(index)) |
23 | 9.57k | } |
24 | | |
25 | | /// Reads a type index from Wasm code and validates that it is a valid index |
26 | | /// for a given types vector. |
27 | 9.44k | pub fn decode_and_validate( |
28 | 9.44k | wasm: &mut WasmDecoder, |
29 | 9.44k | c_types: &IdxVec<TypeIdx, FuncType>, |
30 | 9.44k | ) -> Result<Self, ValidationError> { |
31 | 9.44k | let index9.43k = wasm.decode_var_u32()?4 ; |
32 | 9.43k | Self::validate(index, c_types) |
33 | 9.44k | } |
34 | | } |
35 | | |
36 | | impl FuncIdx { |
37 | | /// Validates that a given index is a valid function index. |
38 | | /// |
39 | | /// On success a new [`FuncIdx`] is returned, otherwise a |
40 | | /// [`ValidationError`] is returned. |
41 | 9.22k | pub fn validate<T>(index: u32, c_funcs: &IdxVec<FuncIdx, T>) -> Result<Self, ValidationError> { |
42 | 9.22k | c_funcs |
43 | 9.22k | .validate_index(index) |
44 | 9.22k | .ok_or(ValidationError::InvalidFuncIdx(index)) |
45 | 9.22k | } |
46 | | |
47 | | /// Reads a function index from Wasm code and validates that it is a valid |
48 | | /// index for a given functions vector. |
49 | 9.22k | pub fn decode_and_validate<T>( |
50 | 9.22k | wasm: &mut WasmDecoder, |
51 | 9.22k | c_funcs: &IdxVec<FuncIdx, T>, |
52 | 9.22k | ) -> Result<Self, ValidationError> { |
53 | 9.22k | let index9.22k = wasm.decode_var_u32()?2 ; |
54 | 9.22k | Self::validate(index, c_funcs) |
55 | 9.22k | } |
56 | | } |
57 | | |
58 | | impl TableIdx { |
59 | | /// Validates that a given index is a valid table index. |
60 | | /// |
61 | | /// On success a new [`TableIdx`] is returned, otherwise a |
62 | | /// [`ValidationError`] is returned. |
63 | 1.25k | pub fn validate<T>( |
64 | 1.25k | index: u32, |
65 | 1.25k | c_tables: &IdxVec<TableIdx, T>, |
66 | 1.25k | ) -> Result<Self, ValidationError> { |
67 | 1.25k | c_tables |
68 | 1.25k | .validate_index(index) |
69 | 1.25k | .ok_or(ValidationError::InvalidTableIdx(index)) |
70 | 1.25k | } |
71 | | |
72 | | /// Reads a table index from Wasm code and validates that it is a valid |
73 | | /// index for a given tables vector. |
74 | 955 | pub fn decode_and_validate<T>( |
75 | 955 | wasm: &mut WasmDecoder, |
76 | 955 | c_tables: &IdxVec<TableIdx, T>, |
77 | 955 | ) -> Result<Self, ValidationError> { |
78 | 955 | let index = wasm.decode_var_u32()?0 ; |
79 | 955 | Self::validate(index, c_tables) |
80 | 955 | } |
81 | | } |
82 | | |
83 | | impl MemIdx { |
84 | | /// Validates that a given index is a valid memory index. |
85 | | /// |
86 | | /// On success a new [`MemIdx`] is returned, otherwise a [`ValidationError`] |
87 | | /// is returned. |
88 | 5.22k | pub fn validate<T>(index: u32, c_mems: &IdxVec<MemIdx, T>) -> Result<Self, ValidationError> { |
89 | 5.22k | c_mems |
90 | 5.22k | .validate_index(index) |
91 | 5.22k | .ok_or(ValidationError::InvalidMemIdx(index)) |
92 | 5.22k | } |
93 | | |
94 | | /// Reads a memory index from Wasm code and validates that it is a valid |
95 | | /// index for a given memories vector. |
96 | 85 | pub fn decode_and_validate<T>( |
97 | 85 | wasm: &mut WasmDecoder, |
98 | 85 | c_mems: &IdxVec<MemIdx, T>, |
99 | 85 | ) -> Result<Self, ValidationError> { |
100 | 85 | let index = wasm.decode_var_u32()?0 ; |
101 | 85 | Self::validate(index, c_mems) |
102 | 85 | } |
103 | | } |
104 | | |
105 | | impl GlobalIdx { |
106 | | /// Validates that a given index is a valid global index. |
107 | | /// |
108 | | /// On success a new [`GlobalIdx`] is returned, otherwise a |
109 | | /// [`ValidationError`] is returned. |
110 | 318 | pub fn validate<T>( |
111 | 318 | index: u32, |
112 | 318 | c_globals: &IdxVec<GlobalIdx, T>, |
113 | 318 | ) -> Result<Self, ValidationError> { |
114 | 318 | c_globals |
115 | 318 | .validate_index(index) |
116 | 318 | .ok_or(ValidationError::InvalidGlobalIdx(index)) |
117 | 318 | } |
118 | | |
119 | | /// Reads a global index from Wasm code and validates that it is a valid |
120 | | /// index for a given globals vector. |
121 | 318 | pub fn decode_and_validate<T>( |
122 | 318 | wasm: &mut WasmDecoder, |
123 | 318 | c_globals: &IdxVec<GlobalIdx, T>, |
124 | 318 | ) -> Result<Self, ValidationError> { |
125 | 318 | let index = wasm.decode_var_u32()?0 ; |
126 | 318 | Self::validate(index, c_globals) |
127 | 318 | } |
128 | | } |
129 | | |
130 | | impl ElemIdx { |
131 | | /// Validates that a given index is a valid element index. |
132 | | /// |
133 | | /// On success a new [`ElemIdx`] is returned, otherwise a |
134 | | /// [`ValidationError`] is returned. |
135 | 231 | pub fn validate<T>(index: u32, c_elems: &IdxVec<ElemIdx, T>) -> Result<Self, ValidationError> { |
136 | 231 | c_elems |
137 | 231 | .validate_index(index) |
138 | 231 | .ok_or(ValidationError::InvalidElemIdx(index)) |
139 | 231 | } |
140 | | |
141 | | /// Reads an element index from Wasm code and validates that it is a valid |
142 | | /// index for a given elements vector. |
143 | 231 | pub fn decode_and_validate<T>( |
144 | 231 | wasm: &mut WasmDecoder, |
145 | 231 | c_elems: &IdxVec<ElemIdx, T>, |
146 | 231 | ) -> Result<Self, ValidationError> { |
147 | 231 | let index = wasm.decode_var_u32()?0 ; |
148 | 231 | Self::validate(index, c_elems) |
149 | 231 | } |
150 | | } |
151 | | |
152 | | impl DataIdx { |
153 | | /// Validates that a given index is a valid data index. |
154 | | /// |
155 | | /// On success a new [`DataIdx`] is returned, otherwise a |
156 | | /// [`ValidationError`] is returned. |
157 | 121 | pub fn validate(index: u32, data_count: u32) -> Result<Self, ValidationError> { |
158 | 121 | (index < data_count) |
159 | 121 | .then_some(<Self as Idx>::new(index)) |
160 | 121 | .ok_or(ValidationError::InvalidDataIdx(index)) |
161 | 121 | } |
162 | | |
163 | | /// Reads a data index from Wasm code and validates that it is a valid |
164 | | /// by comparing it to the total number of data segments. |
165 | 121 | pub fn decode_and_validate( |
166 | 121 | wasm: &mut WasmDecoder, |
167 | 121 | data_count: u32, |
168 | 121 | ) -> Result<Self, ValidationError> { |
169 | 121 | let index = wasm.decode_var_u32()?0 ; |
170 | 121 | Self::validate(index, data_count) |
171 | 121 | } |
172 | | } |
173 | | |
174 | | impl LocalIdx { |
175 | | /// Reads a local index from Wasm code and validates that it is valid for a |
176 | | /// given slice of locals. |
177 | 7.93k | pub fn decode_and_validate( |
178 | 7.93k | wasm: &mut WasmDecoder, |
179 | 7.93k | locals_of_current_function: &[ValType], |
180 | 7.93k | ) -> Result<Self, ValidationError> { |
181 | 7.93k | let index = wasm.decode_var_u32()?0 ; |
182 | 7.93k | let index_as_usize = usize::try_from(index).expect("architecture to be at least 32 bits"); |
183 | | |
184 | 7.93k | match locals_of_current_function.get(index_as_usize) { |
185 | 7.91k | Some(_local) => Ok(Self(index)), |
186 | 20 | None => Err(ValidationError::InvalidLocalIdx(index)), |
187 | | } |
188 | 7.93k | } |
189 | | } |