Skip to main content

baedeker_core/binary/
startsec.rs

1// Copyright (C) 2026 Industrial Algebra
2// SPDX-License-Identifier: Apache-2.0
3
4//! Start section parsing.
5//!
6//! Decodes the optional start function index from the start section.
7//! See [Spec §5.5.11](https://webassembly.github.io/spec/core/binary/modules.html#start-section).
8
9use crate::binary::leb128::{self, Cursor};
10use crate::binary::section::RawSection;
11use crate::error::{ByteOffset, DecodeContext, DecodeError, DecodeErrorKind};
12use crate::types::FuncIdx;
13
14pub fn parse_start_section(section: &RawSection<'_>) -> Result<FuncIdx, DecodeError> {
15    let mut cursor = Cursor::new(section.data);
16    let func_idx = leb128::decode_u32(&mut cursor).map_err(|mut e| {
17        e.context = DecodeContext::StartSection;
18        e.offset = ByteOffset(section.offset + e.offset.0);
19        e
20    })?;
21
22    if !cursor.is_empty() {
23        return Err(DecodeError {
24            offset: ByteOffset(section.offset + cursor.position()),
25            context: DecodeContext::StartSection,
26            kind: DecodeErrorKind::SectionSizeMismatch {
27                expected: section.data.len() as u32,
28                consumed: cursor.position() as u32,
29            },
30        });
31    }
32
33    Ok(FuncIdx(func_idx))
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use crate::binary::section::SectionId;
40
41    fn raw_start_section(data: &[u8]) -> RawSection<'_> {
42        RawSection {
43            id: SectionId::Start,
44            offset: 30,
45            data,
46        }
47    }
48
49    #[test]
50    fn parse_start_section_with_single_function_index() {
51        let section = raw_start_section(&[0x02]);
52        let start = parse_start_section(&section).unwrap();
53        assert_eq!(start, FuncIdx(2));
54    }
55
56    #[test]
57    fn reject_trailing_bytes() {
58        let section = raw_start_section(&[0x00, 0x00]);
59        let err = parse_start_section(&section).unwrap_err();
60        assert!(matches!(
61            err.kind,
62            DecodeErrorKind::SectionSizeMismatch { .. }
63        ));
64    }
65}