@@ -18,9 +18,11 @@ use crate::core::reader::types::{ExternType, FuncType, MemType, ResultType, Tabl
1818use crate :: core:: reader:: WasmReader ;
1919use crate :: core:: sidetable:: Sidetable ;
2020use crate :: core:: utils:: ToUsizeExt ;
21+ use crate :: custom_section:: CustomSection ;
2122use crate :: ValidationError ;
2223
2324pub ( crate ) mod code;
25+ pub ( crate ) mod custom_section;
2426pub ( crate ) mod data;
2527pub ( crate ) mod globals;
2628pub ( crate ) mod read_constant_expression;
@@ -49,7 +51,7 @@ pub struct ValidationInfo<'bytecode> {
4951 pub ( crate ) sidetable : Sidetable ,
5052 /// The start function which is automatically executed during instantiation
5153 pub ( crate ) start : Option < FuncIdx > ,
52- pub ( crate ) custom_sections : Vec < ( & ' bytecode str , & ' bytecode [ u8 ] ) > ,
54+ pub ( crate ) custom_sections : Vec < CustomSection < ' bytecode > > ,
5355 // pub(crate) exports_length: Exported,
5456}
5557
@@ -95,27 +97,21 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
9597 read_next_header ( & mut wasm, & mut header) ?;
9698
9799 let mut custom_sections = Vec :: new ( ) ;
98- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
99- custom_sections. push ( custom_section) ;
100- }
100+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
101101
102102 let types = handle_section ( & mut wasm, & mut header, SectionTy :: Type , |wasm, _| {
103103 wasm. read_vec ( FuncType :: read) . map ( |types| IdxVec :: new ( types) . expect ( "that index space creation never fails because the length of the types vector is encoded as a 32-bit integer in the bytecode" ) )
104104 } ) ?
105105 . unwrap_or_default ( ) ;
106106
107- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
108- custom_sections. push ( custom_section) ;
109- }
107+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
110108
111109 let imports = handle_section ( & mut wasm, & mut header, SectionTy :: Import , |wasm, _| {
112110 wasm. read_vec ( |wasm| Import :: read_and_validate ( wasm, & types) )
113111 } ) ?
114112 . unwrap_or_default ( ) ;
115113
116- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
117- custom_sections. push ( custom_section) ;
118- }
114+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
119115
120116 // The `Function` section only covers module-level (or "local") functions.
121117 // Imported functions have their types known in the `import` section. Both
@@ -137,9 +133,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
137133 let functions = ExtendedIdxVec :: new ( imported_functions. collect ( ) , local_functions)
138134 . map_err ( |IdxVecOverflowError | ValidationError :: TooManyFunctions ) ?;
139135
140- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
141- custom_sections. push ( custom_section) ;
142- }
136+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
143137
144138 let imported_tables = imports. iter ( ) . filter_map ( |m| match m. desc {
145139 ImportDesc :: Table ( table) => Some ( table) ,
@@ -153,9 +147,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
153147 let tables = ExtendedIdxVec :: new ( imported_tables. collect ( ) , local_tables)
154148 . map_err ( |IdxVecOverflowError | ValidationError :: TooManyTables ) ?;
155149
156- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
157- custom_sections. push ( custom_section) ;
158- }
150+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
159151
160152 let imported_memories = imports. iter ( ) . filter_map ( |m| match m. desc {
161153 ImportDesc :: Mem ( mem) => Some ( mem) ,
@@ -174,9 +166,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
174166 return Err ( ValidationError :: UnsupportedMultipleMemoriesProposal ) ;
175167 }
176168
177- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
178- custom_sections. push ( custom_section) ;
179- }
169+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
180170
181171 let imported_global_types: Vec < GlobalType > = imports
182172 . iter ( )
@@ -205,9 +195,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
205195 let globals = ExtendedIdxVec :: new ( imported_globals. collect ( ) , local_globals)
206196 . map_err ( |IdxVecOverflowError | ValidationError :: TooManyGlobals ) ?;
207197
208- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
209- custom_sections. push ( custom_section) ;
210- }
198+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
211199
212200 let exports = handle_section ( & mut wasm, & mut header, SectionTy :: Export , |wasm, _| {
213201 wasm. read_vec ( |wasm| {
@@ -228,9 +216,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
228216 } ,
229217 ) ) ;
230218
231- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
232- custom_sections. push ( custom_section) ;
233- }
219+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
234220
235221 let start = handle_section ( & mut wasm, & mut header, SectionTy :: Start , |wasm, _| {
236222 let func_idx = FuncIdx :: read_and_validate ( wasm, functions. inner ( ) ) ?;
@@ -261,9 +247,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
261247 }
262248 } ) ?;
263249
264- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
265- custom_sections. push ( custom_section) ;
266- }
250+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
267251
268252 let elements = handle_section ( & mut wasm, & mut header, SectionTy :: Element , |wasm, _| {
269253 ElemType :: read_and_validate (
@@ -277,9 +261,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
277261 } ) ?
278262 . unwrap_or_default ( ) ;
279263
280- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
281- custom_sections. push ( custom_section) ;
282- }
264+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
283265
284266 // https://webassembly.github.io/spec/core/binary/modules.html#data-count-section
285267 // As per the official documentation:
@@ -293,9 +275,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
293275 trace ! ( "data count: {dc}" ) ;
294276 }
295277
296- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
297- custom_sections. push ( custom_section) ;
298- }
278+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
299279
300280 let mut sidetable = Sidetable :: new ( ) ;
301281 let func_blocks_stps = handle_section ( & mut wasm, & mut header, SectionTy :: Code , |wasm, h| {
@@ -326,9 +306,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
326306 return Err ( ValidationError :: FunctionAndCodeSectionsHaveDifferentLengths ) ;
327307 }
328308
329- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
330- custom_sections. push ( custom_section) ;
331- }
309+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
332310
333311 let data_section = handle_section ( & mut wasm, & mut header, SectionTy :: Data , |wasm, h| {
334312 // wasm.read_vec(DataSegment::read)
@@ -344,9 +322,7 @@ pub fn validate(wasm: &[u8]) -> Result<ValidationInfo<'_>, ValidationError> {
344322 }
345323 }
346324
347- while let Some ( custom_section) = try_read_custom_section ( & mut wasm, & mut header) ? {
348- custom_sections. push ( custom_section) ;
349- }
325+ read_all_custom_sections ( & mut wasm, & mut header, & mut custom_sections) ?;
350326
351327 // All sections should have been handled
352328 if let Some ( header) = header {
@@ -408,37 +384,27 @@ where
408384 }
409385}
410386
411- fn try_read_custom_section < ' wasm > (
387+ /// Reads the next sections as long as they are custom sections and pushes them
388+ /// into the `custom_sections` vector.
389+ fn read_all_custom_sections < ' wasm > (
412390 wasm : & mut WasmReader < ' wasm > ,
413391 section_header : & mut Option < SectionHeader > ,
414- ) -> Result < Option < ( & ' wasm str , & ' wasm [ u8 ] ) > , ValidationError > {
415- handle_section ( wasm, section_header, SectionTy :: Custom , |wasm, h| {
416- // customsec ::= section_0(custom)
417- // custom ::= name byte*
418- // name ::= b*:vec(byte) => name (if utf8(name) = b*)
419- // vec(B) ::= n:u32 (x:B)^n => x^n
420- let name = wasm. read_name ( ) ?;
421-
422- let section_start = wasm. pc ;
423- let section_end = h
424- . contents
425- . from ( )
426- . checked_add ( h. contents . len ( ) )
427- . ok_or ( ValidationError :: InvalidCustomSectionLength ) ?;
428-
429- let contents = wasm
430- . full_wasm_binary
431- . get ( section_start..section_end)
432- . ok_or ( ValidationError :: InvalidCustomSectionLength ) ?;
433-
434- let section_len = section_end
435- . checked_sub ( section_start)
436- . expect ( "section start <= section end always" ) ;
437-
438- wasm. skip ( section_len) ?;
439-
440- Ok ( ( name, contents) )
441- } )
392+ custom_sections : & mut Vec < CustomSection < ' wasm > > ,
393+ ) -> Result < ( ) , ValidationError > {
394+ let mut read_custom_section = || {
395+ handle_section (
396+ wasm,
397+ section_header,
398+ SectionTy :: Custom ,
399+ CustomSection :: read_and_validate,
400+ )
401+ } ;
402+
403+ while let Some ( custom_section) = read_custom_section ( ) ? {
404+ custom_sections. push ( custom_section) ;
405+ }
406+
407+ Ok ( ( ) )
442408}
443409
444410impl < ' wasm > ValidationInfo < ' wasm > {
@@ -481,7 +447,7 @@ impl<'wasm> ValidationInfo<'wasm> {
481447 /// Returns a list of all custom sections in the bytecode. Every custom
482448 /// section consists of its name and the custom section's bytecode
483449 /// (excluding the name itself).
484- pub fn custom_sections ( & self ) -> & [ ( & ' wasm str , & ' wasm [ u8 ] ) ] {
450+ pub fn custom_sections ( & self ) -> & [ CustomSection < ' wasm > ] {
485451 & self . custom_sections
486452 }
487453}
0 commit comments