Skip to main content

neo_decompiler/nef/parser/
parse.rs

1use crate::error::{NefError, Result};
2
3use super::super::encoding::{read_varbytes, read_varstring};
4use super::super::types::{NefFile, NefHeader};
5use super::super::{CHECKSUM_SIZE, FIXED_HEADER_SIZE, MAGIC, MAX_SCRIPT_LEN, MAX_SOURCE_LEN};
6use super::NefParser;
7
8mod header;
9mod reserved;
10mod script;
11mod trailer;
12
13impl NefParser {
14    /// Parse a NEF container from a byte buffer.
15    ///
16    /// # Errors
17    /// Returns an error if the input is not a valid NEF container, if the script
18    /// exceeds configured limits, or if the checksum does not match.
19    pub fn parse(&self, bytes: &[u8]) -> Result<NefFile> {
20        if bytes.len() as u64 > super::super::MAX_NEF_FILE_SIZE {
21            return Err(NefError::FileTooLarge {
22                size: bytes.len() as u64,
23                max: super::super::MAX_NEF_FILE_SIZE,
24            }
25            .into());
26        }
27        if bytes.len() < FIXED_HEADER_SIZE + CHECKSUM_SIZE {
28            return Err(NefError::TooShort.into());
29        }
30
31        let mut offset = 0usize;
32
33        let magic = header::read_magic(bytes, &mut offset)?;
34        let compiler = header::read_compiler(bytes, &mut offset)?;
35        let source = header::read_source(bytes, &mut offset)?;
36        reserved::expect_reserved_byte_zero(bytes, &mut offset)?;
37
38        let (method_tokens, tokens_len) = self.parse_method_tokens(bytes, offset)?;
39        offset += tokens_len;
40
41        reserved::expect_reserved_word_zero(bytes, &mut offset)?;
42        let script = script::read_script(bytes, &mut offset)?;
43
44        let checksum_start = offset;
45        let checksum = trailer::read_checksum(bytes, checksum_start)?;
46        trailer::verify_checksum(bytes, checksum_start, checksum)?;
47        trailer::expect_end_of_file(bytes, checksum_start + CHECKSUM_SIZE)?;
48
49        Ok(NefFile {
50            header: NefHeader {
51                magic,
52                compiler,
53                source,
54            },
55            method_tokens,
56            script,
57            checksum,
58        })
59    }
60}