1use crate::bytecode_constants::*;
6use crate::interpreter::common::*;
7use crate::interpreter::instruction_decoder::*;
8use num_traits::FromPrimitive;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12pub const NODE_TYPE_HEADER_SZ: usize = 9;
15
16const MINIMUM_BYTECODE_SZ: usize = HEADER_SZ * 3;
19
20const DEBUG_FLAG_SZ: usize = 1;
22
23fn get_symbol_table_and_instruction_debug_bytecode(
27 bytecode: Vec<u8>,
28) -> Result<(HashMap<u32, String>, Vec<u8>, Option<Vec<u8>>), BytecodeError> {
29 if bytecode.len() < MINIMUM_BYTECODE_SZ {
30 return Err(BytecodeError::UnexpectedEnd);
31 }
32
33 let (version, bytecode) = read_and_remove_header(bytecode, BIND_MAGIC_NUM)?;
35 if version != BYTECODE_VERSION {
36 return Err(BytecodeError::InvalidVersion(version));
37 }
38
39 let (debug_flag_byte, bytecode) = read_and_remove_debug_flag(bytecode)?;
41
42 let (symbol_table_sz, mut symbol_table_bytecode) =
45 read_and_remove_header(bytecode, SYMB_MAGIC_NUM)?;
46 if symbol_table_bytecode.len() < symbol_table_sz as usize + HEADER_SZ {
47 return Err(BytecodeError::IncorrectSectionSize);
48 }
49
50 let mut inst_bytecode = symbol_table_bytecode.split_off(symbol_table_sz as usize);
52
53 let inst_bytecode_size = u32::from_le_bytes(get_u32_bytes(&inst_bytecode, 4)?);
55 if inst_bytecode.len() < inst_bytecode_size as usize + HEADER_SZ {
56 return Err(BytecodeError::IncorrectSectionSize);
57 }
58
59 let debug_bytecode = if debug_flag_byte == BYTECODE_ENABLE_DEBUG {
62 let debug_result = inst_bytecode.split_off(inst_bytecode_size as usize + HEADER_SZ);
63 let (debug_sz, debug_result_vec) = read_and_remove_header(debug_result, DEBG_MAGIC_NUM)?;
64 if debug_result_vec.len() != debug_sz as usize {
65 return Err(BytecodeError::IncorrectSectionSize);
66 }
67 Some(debug_result_vec)
68 } else {
69 None
70 };
71
72 Ok((read_symbol_table(symbol_table_bytecode)?, inst_bytecode, debug_bytecode))
73}
74
75fn split_off_parent(
78 mut bytecode: Vec<u8>,
79 expect_primary: bool,
80 symbol_table: &HashMap<u32, String>,
81) -> Result<(bool, Parent, Vec<u8>), BytecodeError> {
82 let (is_optional, node_id, node_inst_sz) =
84 verify_and_read_node_header(&bytecode, expect_primary)?;
85 if bytecode.len() < NODE_TYPE_HEADER_SZ + node_inst_sz as usize {
86 return Err(BytecodeError::IncorrectParentSectionSize);
87 }
88
89 if !symbol_table.contains_key(&node_id) {
90 return Err(BytecodeError::MissingParentIdInSymbolTable);
91 }
92
93 let mut node_instructions = bytecode.split_off(NODE_TYPE_HEADER_SZ);
94 let remaining_bytecode = node_instructions.split_off(node_inst_sz as usize);
95 let decoded_instructions =
96 InstructionDecoder::new(symbol_table, &node_instructions).decode()?;
97 Ok((
98 is_optional,
99 Parent {
100 name_id: node_id,
101 instructions: node_instructions,
102 decoded_instructions: decoded_instructions,
103 },
104 remaining_bytecode,
105 ))
106}
107
108#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
109pub enum DecodedRules {
110 Normal(DecodedBindRules),
111 Composite(DecodedCompositeBindRules),
112}
113
114impl DecodedRules {
115 pub fn new(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
116 let (symbol_table, inst_bytecode, debug_bytecode) =
117 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
118 let parsed_magic_num = u32::from_be_bytes(get_u32_bytes(&inst_bytecode, 0)?);
119 if parsed_magic_num == COMPOSITE_MAGIC_NUM {
120 return Ok(DecodedRules::Composite(DecodedCompositeBindRules::new(
121 symbol_table,
122 inst_bytecode,
123 decode_debug_bytecode(debug_bytecode)?,
124 )?));
125 }
126 Ok(DecodedRules::Normal(DecodedBindRules::new(
127 symbol_table,
128 inst_bytecode,
129 decode_debug_bytecode(debug_bytecode)?,
130 )?))
131 }
132}
133
134#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
135pub struct DecodedDebugInfo {
136 pub symbol_table: HashMap<u32, String>,
137}
138
139impl DecodedDebugInfo {
140 pub fn new(debug_bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
141 let (debug_sz, debug_sym_bytecode) =
143 read_and_remove_header(debug_bytecode, DBSY_MAGIC_NUM)?;
144 if debug_sym_bytecode.len() != debug_sz as usize {
145 return Err(BytecodeError::IncorrectSectionSize);
146 }
147 let symbol_table = read_symbol_table(debug_sym_bytecode)?;
149
150 Ok(DecodedDebugInfo { symbol_table: symbol_table })
151 }
152}
153
154pub fn decode_debug_bytecode(
156 debug_bytecode: Option<Vec<u8>>,
157) -> Result<Option<DecodedDebugInfo>, BytecodeError> {
158 if debug_bytecode.is_none() {
159 return Ok(None);
160 }
161 let bytecode = debug_bytecode.unwrap();
162 if bytecode.is_empty() {
163 return Ok(None);
164 }
165 return Ok(Some(DecodedDebugInfo::new(bytecode)?));
166}
167
168#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
171pub struct DecodedBindRules {
172 pub symbol_table: HashMap<u32, String>,
173 pub instructions: Vec<u8>,
174 pub decoded_instructions: Vec<DecodedInstruction>,
175 pub debug_info: Option<DecodedDebugInfo>,
176}
177
178impl DecodedBindRules {
179 pub fn new(
180 symbol_table: HashMap<u32, String>,
181 inst_bytecode: Vec<u8>,
182 debug_info: Option<DecodedDebugInfo>,
183 ) -> Result<Self, BytecodeError> {
184 let (inst_sz, inst_bytecode) =
186 read_and_remove_header(inst_bytecode, INSTRUCTION_MAGIC_NUM)?;
187
188 if inst_bytecode.len() != inst_sz as usize {
189 return Err(BytecodeError::IncorrectSectionSize);
190 }
191
192 let decoded_instructions =
193 InstructionDecoder::new(&symbol_table, &inst_bytecode).decode()?;
194
195 Ok(DecodedBindRules {
196 symbol_table: symbol_table,
197 instructions: inst_bytecode,
198 decoded_instructions: decoded_instructions,
199 debug_info: debug_info,
200 })
201 }
202
203 pub fn from_bytecode(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
204 let (symbol_table, inst_bytecode, debug_bytecode) =
205 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
206 DecodedBindRules::new(symbol_table, inst_bytecode, decode_debug_bytecode(debug_bytecode)?)
207 }
208}
209
210#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
211pub struct Parent {
212 pub name_id: u32,
214 pub instructions: Vec<u8>,
215 pub decoded_instructions: Vec<DecodedInstruction>,
216}
217
218#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
221pub struct DecodedCompositeBindRules {
222 pub symbol_table: HashMap<u32, String>,
223 pub device_name_id: u32,
224 pub primary_parent: Parent,
225 pub additional_parents: Vec<Parent>,
226 pub optional_parents: Vec<Parent>,
227 pub debug_info: Option<DecodedDebugInfo>,
228}
229
230impl DecodedCompositeBindRules {
231 pub fn new(
232 symbol_table: HashMap<u32, String>,
233 composite_inst_bytecode: Vec<u8>,
234 debug_info: Option<DecodedDebugInfo>,
235 ) -> Result<Self, BytecodeError> {
236 let (composite_inst_sz, mut composite_inst_bytecode) =
239 read_and_remove_header(composite_inst_bytecode, COMPOSITE_MAGIC_NUM)?;
240 if composite_inst_bytecode.len() != composite_inst_sz as usize {
241 return Err(BytecodeError::IncorrectSectionSize);
242 }
243
244 let device_name_id = u32::from_le_bytes(get_u32_bytes(&composite_inst_bytecode, 0)?);
246 if !symbol_table.contains_key(&device_name_id) {
247 return Err(BytecodeError::MissingDeviceNameInSymbolTable);
248 }
249
250 let node_bytecode = composite_inst_bytecode.split_off(4);
252
253 let (_, primary_parent, mut node_bytecode) =
255 split_off_parent(node_bytecode, true, &symbol_table)?;
256
257 let mut additional_parents: Vec<Parent> = vec![];
259 let mut optional_parents: Vec<Parent> = vec![];
260 while !node_bytecode.is_empty() {
261 let (is_optional, parent, remaining) =
262 split_off_parent(node_bytecode, false, &symbol_table)?;
263 node_bytecode = remaining;
264 if is_optional {
265 optional_parents.push(parent);
266 } else {
267 additional_parents.push(parent);
268 }
269 }
270
271 Ok(DecodedCompositeBindRules {
272 symbol_table: symbol_table,
273 device_name_id: device_name_id,
274 primary_parent: primary_parent,
275 additional_parents: additional_parents,
276 optional_parents: optional_parents,
277 debug_info: debug_info,
278 })
279 }
280
281 pub fn from_bytecode(bytecode: Vec<u8>) -> Result<Self, BytecodeError> {
282 let (symbol_table, inst_bytecode, debug_bytecode) =
283 get_symbol_table_and_instruction_debug_bytecode(bytecode)?;
284 DecodedCompositeBindRules::new(
285 symbol_table,
286 inst_bytecode,
287 decode_debug_bytecode(debug_bytecode)?,
288 )
289 }
290}
291
292fn get_u32_bytes(bytecode: &Vec<u8>, idx: usize) -> Result<[u8; 4], BytecodeError> {
293 if idx + 4 > bytecode.len() {
294 return Err(BytecodeError::UnexpectedEnd);
295 }
296
297 let mut bytes: [u8; 4] = [0; 4];
298 bytes.copy_from_slice(&bytecode[idx..(4 + idx)]);
299 Ok(bytes)
300}
301
302fn read_and_remove_header(
304 mut bytecode: Vec<u8>,
305 magic_num: u32,
306) -> Result<(u32, Vec<u8>), BytecodeError> {
307 let parsed_magic_num = u32::from_be_bytes(get_u32_bytes(&bytecode, 0)?);
308 if parsed_magic_num != magic_num {
309 return Err(BytecodeError::InvalidHeader(magic_num, parsed_magic_num));
310 }
311
312 let val = u32::from_le_bytes(get_u32_bytes(&bytecode, 4)?);
313 Ok((val, bytecode.split_off(HEADER_SZ)))
314}
315
316fn read_and_remove_debug_flag(mut bytecode: Vec<u8>) -> Result<(u8, Vec<u8>), BytecodeError> {
318 let debug_flag_byte = bytecode[0];
319 if debug_flag_byte != BYTECODE_DISABLE_DEBUG && debug_flag_byte != BYTECODE_ENABLE_DEBUG {
320 return Err(BytecodeError::InvalidDebugFlag(debug_flag_byte));
321 }
322 Ok((debug_flag_byte, bytecode.split_off(DEBUG_FLAG_SZ)))
323}
324
325fn verify_and_read_node_header(
327 bytecode: &Vec<u8>,
328 expect_primary: bool,
329) -> Result<(bool, u32, u32), BytecodeError> {
330 if bytecode.len() < NODE_TYPE_HEADER_SZ {
331 return Err(BytecodeError::UnexpectedEnd);
332 }
333
334 let is_optional = match FromPrimitive::from_u8(bytecode[0]) {
335 Some(RawParentType::Primary) => {
336 if !expect_primary {
337 return Err(BytecodeError::MultiplePrimaryParents);
338 }
339
340 false
341 }
342 Some(RawParentType::Additional) => {
343 if expect_primary {
344 return Err(BytecodeError::InvalidPrimaryParent);
345 }
346
347 false
348 }
349 Some(RawParentType::Optional) => {
350 if expect_primary {
351 return Err(BytecodeError::InvalidPrimaryParent);
352 }
353
354 true
355 }
356 None => {
357 return Err(BytecodeError::InvalidParentType(bytecode[0]));
358 }
359 };
360
361 let node_id = u32::from_le_bytes(get_u32_bytes(bytecode, 1)?);
362 let inst_sz = u32::from_le_bytes(get_u32_bytes(bytecode, 5)?);
363 Ok((is_optional, node_id, inst_sz))
364}
365
366fn read_string(iter: &mut BytecodeIter) -> Result<String, BytecodeError> {
367 let mut str_bytes = vec![];
368
369 loop {
372 let byte = *next_u8(iter)?;
373 if byte == 0 {
374 break;
375 }
376
377 str_bytes.push(byte);
378 if str_bytes.len() > MAX_STRING_LENGTH {
379 return Err(BytecodeError::InvalidStringLength);
380 }
381 }
382
383 if str_bytes.is_empty() {
384 return Err(BytecodeError::EmptyString);
385 }
386
387 String::from_utf8(str_bytes).map_err(|_| BytecodeError::Utf8ConversionFailure)
388}
389
390fn read_symbol_table(bytecode: Vec<u8>) -> Result<HashMap<u32, String>, BytecodeError> {
391 let mut iter = bytecode.iter();
392
393 let mut symbol_table = HashMap::new();
394 let mut expected_key = SYMB_TBL_START_KEY;
395 while let Some(key) = try_next_u32(&mut iter)? {
396 if key != expected_key {
397 return Err(BytecodeError::InvalidSymbolTableKey(key));
398 }
399
400 let str_val = read_string(&mut iter)?;
403 symbol_table.insert(key, str_val);
404 expected_key += 1;
405 }
406
407 Ok(symbol_table)
408}
409
410#[cfg(test)]
411mod test {
412 use super::*;
413 use crate::compiler::Symbol;
414 use crate::interpreter::test_common::*;
415 use crate::parser::bind_library;
416
417 fn append_section_header(bytecode: &mut Vec<u8>, magic_num: u32, sz: u32) {
418 bytecode.extend_from_slice(&magic_num.to_be_bytes());
419 bytecode.extend_from_slice(&sz.to_le_bytes());
420 }
421
422 fn append_node_header(bytecode: &mut Vec<u8>, node_type: RawParentType, node_id: u32, sz: u32) {
423 bytecode.push(node_type as u8);
424 bytecode.extend_from_slice(&node_id.to_le_bytes());
425 bytecode.extend_from_slice(&sz.to_le_bytes());
426 }
427
428 #[test]
429 fn test_invalid_header() {
430 let mut bytecode: Vec<u8> = vec![0x41, 0x49, 0x4E, 0x44, 0x02, 0, 0, 0];
432 bytecode.push(BYTECODE_DISABLE_DEBUG);
433 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
434 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
435 assert_eq!(
436 Err(BytecodeError::InvalidHeader(BIND_MAGIC_NUM, 0x41494E44)),
437 DecodedRules::new(bytecode)
438 );
439
440 let mut bytecode: Vec<u8> = vec![0x42, 0x49, 0x4E, 0x44, 0x03, 0, 0, 0];
442 bytecode.push(BYTECODE_DISABLE_DEBUG);
443 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
444 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
445 assert_eq!(Err(BytecodeError::InvalidVersion(3)), DecodedRules::new(bytecode));
446
447 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
449 bytecode.push(BYTECODE_DISABLE_DEBUG);
450 append_section_header(&mut bytecode, 0xAAAAAAAA, 0);
451 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
452 assert_eq!(
453 Err(BytecodeError::InvalidHeader(SYMB_MAGIC_NUM, 0xAAAAAAAA)),
454 DecodedRules::new(bytecode)
455 );
456
457 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
459 bytecode.push(BYTECODE_DISABLE_DEBUG);
460 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
461 append_section_header(&mut bytecode, 0xAAAAAAAA, 0);
462 assert_eq!(
463 Err(BytecodeError::InvalidHeader(INSTRUCTION_MAGIC_NUM, 0xAAAAAAAA)),
464 DecodedRules::new(bytecode)
465 );
466
467 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
469 bytecode.push(BYTECODE_ENABLE_DEBUG);
470 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
471 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
472 append_section_header(&mut bytecode, 0x44454241, 0);
473 assert_eq!(
474 Err(BytecodeError::InvalidHeader(DEBG_MAGIC_NUM, 0x44454241)),
475 DecodedRules::new(bytecode)
476 );
477
478 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
480 bytecode.push(BYTECODE_ENABLE_DEBUG);
481 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
482 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
483 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 8);
484 append_section_header(&mut bytecode, 0x44454247, 0);
485 assert_eq!(
486 Err(BytecodeError::InvalidHeader(DBSY_MAGIC_NUM, 0x44454247)),
487 DecodedRules::new(bytecode)
488 );
489 }
490
491 #[test]
492 fn test_long_string() {
493 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
494 bytecode.push(BYTECODE_DISABLE_DEBUG);
495
496 let mut long_str: [u8; 275] = [0x41; 275];
497 long_str[274] = 0;
498
499 let symbol_section_sz = long_str.len() + 4;
500 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, symbol_section_sz as u32);
501
502 bytecode.extend_from_slice(&[1, 0, 0, 0]);
503 bytecode.extend_from_slice(&long_str);
504
505 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
506 assert_eq!(Err(BytecodeError::InvalidStringLength), DecodedRules::new(bytecode));
507 }
508
509 #[test]
510 fn test_unexpected_end() {
511 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
512 bytecode.push(BYTECODE_DISABLE_DEBUG);
513 bytecode.extend_from_slice(&SYMB_MAGIC_NUM.to_be_bytes());
514 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
515 }
516
517 #[test]
518 fn test_string_with_no_zero_terminator() {
519 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
520 bytecode.push(BYTECODE_DISABLE_DEBUG);
521 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 14);
522
523 let invalid_str: [u8; 10] = [0x41; 10];
524 bytecode.extend_from_slice(&[1, 0, 0, 0]);
525 bytecode.extend_from_slice(&invalid_str);
526
527 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
528
529 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
530 }
531
532 #[test]
533 fn test_duplicate_key() {
534 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
535 bytecode.push(BYTECODE_DISABLE_DEBUG);
536 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 14);
537
538 let str_1: [u8; 3] = [0x41, 0x42, 0];
539 bytecode.extend_from_slice(&[1, 0, 0, 0]);
540 bytecode.extend_from_slice(&str_1);
541
542 let str_2: [u8; 3] = [0x42, 0x43, 0];
543 bytecode.extend_from_slice(&[1, 0, 0, 0]);
544 bytecode.extend_from_slice(&str_2);
545
546 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
547 assert_eq!(Err(BytecodeError::InvalidSymbolTableKey(1)), DecodedRules::new(bytecode));
548 }
549
550 #[test]
551 fn test_invalid_key() {
552 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
553 bytecode.push(BYTECODE_DISABLE_DEBUG);
554 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 15);
555
556 let str_1: [u8; 4] = [0x41, 0x45, 0x60, 0];
557 bytecode.extend_from_slice(&[1, 0, 0, 0]);
558 bytecode.extend_from_slice(&str_1);
559
560 let str_2: [u8; 3] = [0x42, 0x43, 0];
561 bytecode.extend_from_slice(&[5, 0, 0, 0]);
562 bytecode.extend_from_slice(&str_2);
563
564 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
565 assert_eq!(Err(BytecodeError::InvalidSymbolTableKey(5)), DecodedRules::new(bytecode));
566 }
567
568 #[test]
569 fn test_cutoff_symbol_table_key() {
570 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
571 bytecode.push(BYTECODE_DISABLE_DEBUG);
572 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
573
574 let str_1: [u8; 3] = [0x41, 0x42, 0];
575 bytecode.extend_from_slice(&[1, 0, 0, 0]);
576 bytecode.extend_from_slice(&str_1);
577
578 bytecode.extend_from_slice(&[2, 0]);
579 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
580
581 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
582 }
583
584 #[test]
585 fn test_incorrect_inst_size() {
586 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
587 bytecode.push(BYTECODE_DISABLE_DEBUG);
588 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
589 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
590 bytecode.push(0x30);
591 assert_eq!(Err(BytecodeError::IncorrectSectionSize), DecodedRules::new(bytecode));
592 }
593
594 #[test]
595 fn test_minimum_size_bytecode() {
596 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
597 bytecode.push(BYTECODE_DISABLE_DEBUG);
598 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
599 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
600 assert_eq!(
601 DecodedRules::Normal(DecodedBindRules {
602 symbol_table: HashMap::new(),
603 instructions: vec![],
604 decoded_instructions: vec![],
605 debug_info: None,
606 }),
607 DecodedRules::new(bytecode).unwrap()
608 );
609 }
610
611 #[test]
612 fn test_incorrect_size_symbol_table() {
613 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
614 bytecode.push(BYTECODE_DISABLE_DEBUG);
615 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, u32::MAX);
616 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, 0);
617 assert_eq!(Err(BytecodeError::IncorrectSectionSize), DecodedRules::new(bytecode));
618 }
619
620 #[test]
621 fn test_instructions() {
622 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
623 bytecode.push(BYTECODE_DISABLE_DEBUG);
624 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
625
626 let instructions = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0, 0x10];
627 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
628 bytecode.extend_from_slice(&instructions);
629 let bind_rules = DecodedBindRules::from_bytecode(bytecode).unwrap();
630 assert_eq!(instructions.to_vec(), bind_rules.instructions);
631 }
632
633 #[test]
634 fn test_enable_debug_flag_empty_debug_info_section() {
635 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
636 bytecode.push(BYTECODE_ENABLE_DEBUG);
637 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
638
639 let instructions = [0x30];
640 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
641 bytecode.extend_from_slice(&instructions);
642 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0);
643
644 let rules = DecodedBindRules {
645 symbol_table: HashMap::new(),
646 instructions: vec![0x30],
647 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
648 debug_info: None,
649 };
650
651 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
652 }
653
654 #[test]
655 fn test_enable_debug_flag_empty_debug_symb_section() {
656 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
657 bytecode.push(BYTECODE_ENABLE_DEBUG);
658 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
659
660 let instructions = [0x30];
661 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
662 bytecode.extend_from_slice(&instructions);
663 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 8);
664 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0);
665
666 let rules = DecodedBindRules {
667 symbol_table: HashMap::new(),
668 instructions: vec![0x30],
669 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
670 debug_info: Some(DecodedDebugInfo { symbol_table: HashMap::new() }),
671 };
672
673 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
674 }
675
676 #[test]
677 fn test_enable_debug_flag() {
678 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
679 bytecode.push(BYTECODE_ENABLE_DEBUG);
680 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
681
682 let instructions = [0x30];
683 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
684 bytecode.extend_from_slice(&instructions);
685
686 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
687 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
688
689 let str_1: [u8; 22] = [
690 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
692 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
693 ];
694 bytecode.extend_from_slice(&[1, 0, 0, 0]);
695 bytecode.extend_from_slice(&str_1);
696
697 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
698 expected_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
699
700 let rules = DecodedBindRules {
701 symbol_table: HashMap::new(),
702 instructions: vec![0x30],
703 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
704 debug_info: Some(DecodedDebugInfo { symbol_table: expected_symbol_table }),
705 };
706
707 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
708 }
709
710 #[test]
711 fn test_missing_debug_flag() {
712 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
713 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
714
715 let instructions = [0x01, 0x01, 0x05, 0, 0, 0, 0x01, 0x16, 0, 0, 0];
716 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
717 bytecode.extend_from_slice(&instructions);
718
719 assert_eq!(Err(BytecodeError::InvalidDebugFlag(0x53)), DecodedRules::new(bytecode));
720 }
721
722 #[test]
723 fn test_invalid_debug_flag() {
724 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
725 bytecode.push(0x03);
726 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
727
728 let instructions = [0x01, 0x01, 0x05, 0, 0, 0, 0x01, 0x16, 0, 0, 0];
729 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
730 bytecode.extend_from_slice(&instructions);
731
732 assert_eq!(Err(BytecodeError::InvalidDebugFlag(0x03)), DecodedRules::new(bytecode));
733 }
734
735 #[test]
736 fn test_value_key_missing_in_symbols() {
737 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
738 bytecode.push(BYTECODE_DISABLE_DEBUG);
739 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
740
741 let instructions = [0x01, 0x00, 0, 0, 0, 0x05, 0x10, 0, 0, 0, 0];
742 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
743 bytecode.extend_from_slice(&instructions);
744
745 assert_eq!(
746 Err(BytecodeError::MissingEntryInSymbolTable(0x05000000)),
747 DecodedRules::new(bytecode)
748 );
749 }
750
751 #[test]
752 fn test_valid_bytecode() {
753 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
754 bytecode.push(BYTECODE_DISABLE_DEBUG);
755 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
756
757 let str_1: [u8; 5] = [0x57, 0x52, 0x45, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
759 bytecode.extend_from_slice(&str_1);
760
761 let str_2: [u8; 5] = [0x44, 0x55, 0x43, 0x4B, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
763 bytecode.extend_from_slice(&str_2);
764
765 let instructions = [
766 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0, 0x10, 0x11, 0x01, 0, 0, 0, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0,
768 0, 0x30, 0x20, 0x11, 0x01, 0, 0, 0, 0x00, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0,
771 0, 0x30, 0x20, 0x10, 0x02, 0, 0, 0, 0x30, 0x30, 0x20, ];
775 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
776 bytecode.extend_from_slice(&instructions);
777
778 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
779 expected_symbol_table.insert(1, "WREN".to_string());
780 expected_symbol_table.insert(2, "DUCK".to_string());
781
782 let expected_decoded_inst = vec![
783 DecodedInstruction::Condition(DecodedCondition {
784 is_equal: true,
785 lhs: Symbol::NumberValue(0x05000000),
786 rhs: Symbol::NumberValue(0x10000010),
787 }),
788 DecodedInstruction::Jump(Some(DecodedCondition {
789 is_equal: true,
790 lhs: Symbol::NumberValue(0x05000000),
791 rhs: Symbol::NumberValue(0x10),
792 })),
793 DecodedInstruction::UnconditionalAbort,
794 DecodedInstruction::Label,
795 DecodedInstruction::Jump(Some(DecodedCondition {
796 is_equal: true,
797 lhs: Symbol::Key("WREN".to_string(), bind_library::ValueType::Str),
798 rhs: Symbol::StringValue("DUCK".to_string()),
799 })),
800 DecodedInstruction::UnconditionalAbort,
801 DecodedInstruction::Label,
802 DecodedInstruction::Jump(None),
803 DecodedInstruction::UnconditionalAbort,
804 DecodedInstruction::UnconditionalAbort,
805 DecodedInstruction::Label,
806 ];
807
808 let rules = DecodedBindRules {
809 symbol_table: expected_symbol_table,
810 instructions: instructions.to_vec(),
811 decoded_instructions: expected_decoded_inst,
812 debug_info: None,
813 };
814 assert_eq!(DecodedRules::Normal(rules), DecodedRules::new(bytecode).unwrap());
815 }
816
817 #[test]
818 fn test_enable_debug_composite() {
819 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
820 bytecode.push(BYTECODE_ENABLE_DEBUG);
821 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
822
823 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
825 bytecode.extend_from_slice(&device_name);
826
827 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
829 bytecode.extend_from_slice(&primary_node_name);
830
831 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
833 bytecode.extend_from_slice(&node_name_1);
834
835 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
837 bytecode.extend_from_slice(&node_name_2);
838
839 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
840 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
841 let additional_node_inst_2 = [0x30, 0x30];
842
843 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
844 + ((NODE_TYPE_HEADER_SZ * 3)
845 + primary_node_inst.len()
846 + additional_node_inst_1.len()
847 + additional_node_inst_2.len()) as u32;
848 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
849
850 bytecode.extend_from_slice(&[1, 0, 0, 0]);
852
853 append_node_header(
855 &mut bytecode,
856 RawParentType::Primary,
857 2,
858 primary_node_inst.len() as u32,
859 );
860 bytecode.extend_from_slice(&primary_node_inst);
861 append_node_header(
862 &mut bytecode,
863 RawParentType::Additional,
864 3,
865 additional_node_inst_1.len() as u32,
866 );
867 bytecode.extend_from_slice(&additional_node_inst_1);
868 append_node_header(
869 &mut bytecode,
870 RawParentType::Additional,
871 4,
872 additional_node_inst_2.len() as u32,
873 );
874 bytecode.extend_from_slice(&additional_node_inst_2);
875
876 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
877 expected_symbol_table.insert(1, "IBIS".to_string());
878 expected_symbol_table.insert(2, "RAIL".to_string());
879 expected_symbol_table.insert(3, "COOT".to_string());
880 expected_symbol_table.insert(4, "PLOVER".to_string());
881
882 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
883 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
884
885 let str_1: [u8; 22] = [
886 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
888 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
889 ];
890 bytecode.extend_from_slice(&[1, 0, 0, 0]);
891 bytecode.extend_from_slice(&str_1);
892
893 let mut debug_symbol_table: HashMap<u32, String> = HashMap::new();
894 debug_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
895
896 let rules = DecodedCompositeBindRules {
897 symbol_table: expected_symbol_table,
898 device_name_id: 1,
899 primary_parent: Parent {
900 name_id: 2,
901 instructions: primary_node_inst.to_vec(),
902 decoded_instructions: vec![
903 DecodedInstruction::UnconditionalAbort,
904 DecodedInstruction::Condition(DecodedCondition {
905 is_equal: true,
906 lhs: Symbol::NumberValue(0x5000000),
907 rhs: Symbol::NumberValue(0x200010),
908 }),
909 ],
910 },
911 additional_parents: vec![
912 Parent {
913 name_id: 3,
914 instructions: additional_node_inst_1.to_vec(),
915 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
916 is_equal: false,
917 lhs: Symbol::NumberValue(0x2000000),
918 rhs: Symbol::NumberValue(0x10000000),
919 })],
920 },
921 Parent {
922 name_id: 4,
923 instructions: additional_node_inst_2.to_vec(),
924 decoded_instructions: vec![
925 DecodedInstruction::UnconditionalAbort,
926 DecodedInstruction::UnconditionalAbort,
927 ],
928 },
929 ],
930 optional_parents: vec![],
931 debug_info: Some(DecodedDebugInfo { symbol_table: debug_symbol_table }),
932 };
933 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
934 }
935
936 #[test]
937 fn test_enable_debug_composite_with_optional() {
938 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
939 bytecode.push(BYTECODE_ENABLE_DEBUG);
940 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
941
942 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
944 bytecode.extend_from_slice(&device_name);
945
946 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
948 bytecode.extend_from_slice(&primary_node_name);
949
950 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
952 bytecode.extend_from_slice(&node_name_1);
953
954 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
956 bytecode.extend_from_slice(&node_name_2);
957
958 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
959 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
960 let optional_node_inst_1 = [0x30, 0x30];
961
962 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
963 + ((NODE_TYPE_HEADER_SZ * 3)
964 + primary_node_inst.len()
965 + additional_node_inst_1.len()
966 + optional_node_inst_1.len()) as u32;
967 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
968
969 bytecode.extend_from_slice(&[1, 0, 0, 0]);
971
972 append_node_header(
974 &mut bytecode,
975 RawParentType::Primary,
976 2,
977 primary_node_inst.len() as u32,
978 );
979 bytecode.extend_from_slice(&primary_node_inst);
980 append_node_header(
981 &mut bytecode,
982 RawParentType::Additional,
983 3,
984 additional_node_inst_1.len() as u32,
985 );
986 bytecode.extend_from_slice(&additional_node_inst_1);
987 append_node_header(
988 &mut bytecode,
989 RawParentType::Optional,
990 4,
991 optional_node_inst_1.len() as u32,
992 );
993 bytecode.extend_from_slice(&optional_node_inst_1);
994
995 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
996 expected_symbol_table.insert(1, "IBIS".to_string());
997 expected_symbol_table.insert(2, "RAIL".to_string());
998 expected_symbol_table.insert(3, "COOT".to_string());
999 expected_symbol_table.insert(4, "PLOVER".to_string());
1000
1001 append_section_header(&mut bytecode, DEBG_MAGIC_NUM, 0x22);
1002 append_section_header(&mut bytecode, DBSY_MAGIC_NUM, 0x1A);
1003
1004 let str_1: [u8; 22] = [
1005 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x42, 0x49, 0x4e, 0x44, 0x5f, 0x50,
1007 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0,
1008 ];
1009 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1010 bytecode.extend_from_slice(&str_1);
1011
1012 let mut debug_symbol_table: HashMap<u32, String> = HashMap::new();
1013 debug_symbol_table.insert(1, "fuchsia.BIND_PROTOCOL".to_string());
1014
1015 let rules = DecodedCompositeBindRules {
1016 symbol_table: expected_symbol_table,
1017 device_name_id: 1,
1018 primary_parent: Parent {
1019 name_id: 2,
1020 instructions: primary_node_inst.to_vec(),
1021 decoded_instructions: vec![
1022 DecodedInstruction::UnconditionalAbort,
1023 DecodedInstruction::Condition(DecodedCondition {
1024 is_equal: true,
1025 lhs: Symbol::NumberValue(0x5000000),
1026 rhs: Symbol::NumberValue(0x200010),
1027 }),
1028 ],
1029 },
1030 additional_parents: vec![Parent {
1031 name_id: 3,
1032 instructions: additional_node_inst_1.to_vec(),
1033 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1034 is_equal: false,
1035 lhs: Symbol::NumberValue(0x2000000),
1036 rhs: Symbol::NumberValue(0x10000000),
1037 })],
1038 }],
1039 optional_parents: vec![Parent {
1040 name_id: 4,
1041 instructions: optional_node_inst_1.to_vec(),
1042 decoded_instructions: vec![
1043 DecodedInstruction::UnconditionalAbort,
1044 DecodedInstruction::UnconditionalAbort,
1045 ],
1046 }],
1047 debug_info: Some(DecodedDebugInfo { symbol_table: debug_symbol_table }),
1048 };
1049 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1050 }
1051
1052 #[test]
1053 fn test_valid_composite_bind() {
1054 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1055 bytecode.push(BYTECODE_DISABLE_DEBUG);
1056 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
1057
1058 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1060 bytecode.extend_from_slice(&device_name);
1061
1062 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1064 bytecode.extend_from_slice(&primary_node_name);
1065
1066 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1068 bytecode.extend_from_slice(&node_name_1);
1069
1070 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
1072 bytecode.extend_from_slice(&node_name_2);
1073
1074 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1075 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1076 let additional_node_inst_2 = [0x30, 0x30];
1077
1078 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1079 + ((NODE_TYPE_HEADER_SZ * 3)
1080 + primary_node_inst.len()
1081 + additional_node_inst_1.len()
1082 + additional_node_inst_2.len()) as u32;
1083 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1084
1085 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1087
1088 append_node_header(
1090 &mut bytecode,
1091 RawParentType::Primary,
1092 2,
1093 primary_node_inst.len() as u32,
1094 );
1095 bytecode.extend_from_slice(&primary_node_inst);
1096 append_node_header(
1097 &mut bytecode,
1098 RawParentType::Additional,
1099 3,
1100 additional_node_inst_1.len() as u32,
1101 );
1102 bytecode.extend_from_slice(&additional_node_inst_1);
1103 append_node_header(
1104 &mut bytecode,
1105 RawParentType::Additional,
1106 4,
1107 additional_node_inst_2.len() as u32,
1108 );
1109 bytecode.extend_from_slice(&additional_node_inst_2);
1110
1111 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1112 expected_symbol_table.insert(1, "IBIS".to_string());
1113 expected_symbol_table.insert(2, "RAIL".to_string());
1114 expected_symbol_table.insert(3, "COOT".to_string());
1115 expected_symbol_table.insert(4, "PLOVER".to_string());
1116
1117 let rules = DecodedCompositeBindRules {
1118 symbol_table: expected_symbol_table,
1119 device_name_id: 1,
1120 primary_parent: Parent {
1121 name_id: 2,
1122 instructions: primary_node_inst.to_vec(),
1123 decoded_instructions: vec![
1124 DecodedInstruction::UnconditionalAbort,
1125 DecodedInstruction::Condition(DecodedCondition {
1126 is_equal: true,
1127 lhs: Symbol::NumberValue(0x5000000),
1128 rhs: Symbol::NumberValue(0x200010),
1129 }),
1130 ],
1131 },
1132 additional_parents: vec![
1133 Parent {
1134 name_id: 3,
1135 instructions: additional_node_inst_1.to_vec(),
1136 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1137 is_equal: false,
1138 lhs: Symbol::NumberValue(0x2000000),
1139 rhs: Symbol::NumberValue(0x10000000),
1140 })],
1141 },
1142 Parent {
1143 name_id: 4,
1144 instructions: additional_node_inst_2.to_vec(),
1145 decoded_instructions: vec![
1146 DecodedInstruction::UnconditionalAbort,
1147 DecodedInstruction::UnconditionalAbort,
1148 ],
1149 },
1150 ],
1151 optional_parents: vec![],
1152 debug_info: None,
1153 };
1154 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1155 }
1156
1157 #[test]
1158 fn test_valid_composite_bind_with_optional() {
1159 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1160 bytecode.push(BYTECODE_DISABLE_DEBUG);
1161 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 38);
1162
1163 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1165 bytecode.extend_from_slice(&device_name);
1166
1167 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1169 bytecode.extend_from_slice(&primary_node_name);
1170
1171 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1173 bytecode.extend_from_slice(&node_name_1);
1174
1175 let node_name_2: [u8; 7] = [0x50, 0x4C, 0x4F, 0x56, 0x45, 0x52, 0]; bytecode.extend_from_slice(&[4, 0, 0, 0]);
1177 bytecode.extend_from_slice(&node_name_2);
1178
1179 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1180 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1181 let optional_node_inst_1 = [0x30, 0x30];
1182
1183 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1184 + ((NODE_TYPE_HEADER_SZ * 3)
1185 + primary_node_inst.len()
1186 + additional_node_inst_1.len()
1187 + optional_node_inst_1.len()) as u32;
1188 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1189
1190 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1192
1193 append_node_header(
1195 &mut bytecode,
1196 RawParentType::Primary,
1197 2,
1198 primary_node_inst.len() as u32,
1199 );
1200 bytecode.extend_from_slice(&primary_node_inst);
1201 append_node_header(
1202 &mut bytecode,
1203 RawParentType::Additional,
1204 3,
1205 additional_node_inst_1.len() as u32,
1206 );
1207 bytecode.extend_from_slice(&additional_node_inst_1);
1208 append_node_header(
1209 &mut bytecode,
1210 RawParentType::Optional,
1211 4,
1212 optional_node_inst_1.len() as u32,
1213 );
1214 bytecode.extend_from_slice(&optional_node_inst_1);
1215
1216 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1217 expected_symbol_table.insert(1, "IBIS".to_string());
1218 expected_symbol_table.insert(2, "RAIL".to_string());
1219 expected_symbol_table.insert(3, "COOT".to_string());
1220 expected_symbol_table.insert(4, "PLOVER".to_string());
1221
1222 let rules = DecodedCompositeBindRules {
1223 symbol_table: expected_symbol_table,
1224 device_name_id: 1,
1225 primary_parent: Parent {
1226 name_id: 2,
1227 instructions: primary_node_inst.to_vec(),
1228 decoded_instructions: vec![
1229 DecodedInstruction::UnconditionalAbort,
1230 DecodedInstruction::Condition(DecodedCondition {
1231 is_equal: true,
1232 lhs: Symbol::NumberValue(0x5000000),
1233 rhs: Symbol::NumberValue(0x200010),
1234 }),
1235 ],
1236 },
1237 additional_parents: vec![Parent {
1238 name_id: 3,
1239 instructions: additional_node_inst_1.to_vec(),
1240 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1241 is_equal: false,
1242 lhs: Symbol::NumberValue(0x2000000),
1243 rhs: Symbol::NumberValue(0x10000000),
1244 })],
1245 }],
1246 optional_parents: vec![Parent {
1247 name_id: 4,
1248 instructions: optional_node_inst_1.to_vec(),
1249 decoded_instructions: vec![
1250 DecodedInstruction::UnconditionalAbort,
1251 DecodedInstruction::UnconditionalAbort,
1252 ],
1253 }],
1254 debug_info: None,
1255 };
1256 assert_eq!(DecodedRules::Composite(rules), DecodedRules::new(bytecode).unwrap());
1257 }
1258
1259 #[test]
1260 fn test_primary_node_only() {
1261 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1262 bytecode.push(BYTECODE_DISABLE_DEBUG);
1263 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1264
1265 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1267 bytecode.extend_from_slice(&device_name);
1268
1269 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1271 bytecode.extend_from_slice(&primary_node_name);
1272
1273 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1274
1275 let composite_insts_sz =
1276 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1277 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1278
1279 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1281
1282 append_node_header(
1284 &mut bytecode,
1285 RawParentType::Primary,
1286 2,
1287 primary_node_inst.len() as u32,
1288 );
1289 bytecode.extend_from_slice(&primary_node_inst);
1290
1291 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1292 expected_symbol_table.insert(1, "IBIS".to_string());
1293 expected_symbol_table.insert(2, "COOT".to_string());
1294
1295 assert_eq!(
1296 DecodedRules::Composite(DecodedCompositeBindRules {
1297 symbol_table: expected_symbol_table,
1298 device_name_id: 1,
1299 primary_parent: Parent {
1300 name_id: 2,
1301 instructions: primary_node_inst.to_vec(),
1302 decoded_instructions: vec![
1303 DecodedInstruction::UnconditionalAbort,
1304 DecodedInstruction::Condition(DecodedCondition {
1305 is_equal: true,
1306 lhs: Symbol::NumberValue(0x5000000),
1307 rhs: Symbol::NumberValue(0x200010),
1308 }),
1309 ],
1310 },
1311 additional_parents: vec![],
1312 optional_parents: vec![],
1313 debug_info: None,
1314 }),
1315 DecodedRules::new(bytecode).unwrap()
1316 );
1317 }
1318
1319 #[test]
1320 fn test_missing_device_name() {
1321 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1322 bytecode.push(BYTECODE_DISABLE_DEBUG);
1323 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
1324
1325 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1327 bytecode.extend_from_slice(&primary_node_name);
1328
1329 let primary_node_inst = [0x30];
1330 let composite_insts_sz =
1331 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1332 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1333 bytecode.extend_from_slice(&[2, 0, 0, 0]);
1334
1335 append_node_header(
1336 &mut bytecode,
1337 RawParentType::Primary,
1338 1,
1339 primary_node_inst.len() as u32,
1340 );
1341 bytecode.extend_from_slice(&primary_node_inst);
1342
1343 assert_eq!(Err(BytecodeError::MissingDeviceNameInSymbolTable), DecodedRules::new(bytecode));
1344 }
1345
1346 #[test]
1347 fn test_missing_node_name() {
1348 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1349 bytecode.push(BYTECODE_DISABLE_DEBUG);
1350 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 9);
1351
1352 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1354 bytecode.extend_from_slice(&primary_node_name);
1355
1356 let primary_node_inst = [0x30];
1357 let composite_insts_sz =
1358 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1359 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1360 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1361
1362 append_node_header(
1363 &mut bytecode,
1364 RawParentType::Primary,
1365 2,
1366 primary_node_inst.len() as u32,
1367 );
1368 bytecode.extend_from_slice(&primary_node_inst);
1369
1370 assert_eq!(Err(BytecodeError::MissingParentIdInSymbolTable), DecodedRules::new(bytecode));
1371 }
1372
1373 #[test]
1374 fn test_missing_primary_node() {
1375 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1376 bytecode.push(BYTECODE_DISABLE_DEBUG);
1377 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1378
1379 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1381 bytecode.extend_from_slice(&device_name);
1382
1383 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1385 bytecode.extend_from_slice(&primary_node_name);
1386
1387 let additional_node_name: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1389 bytecode.extend_from_slice(&additional_node_name);
1390
1391 let additional_node_inst_1 = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1392 let additional_node_inst_2 = [0x30];
1393
1394 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1395 + ((NODE_TYPE_HEADER_SZ * 2)
1396 + additional_node_inst_1.len()
1397 + additional_node_inst_2.len()) as u32;
1398 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1399
1400 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1402
1403 append_node_header(
1405 &mut bytecode,
1406 RawParentType::Additional,
1407 2,
1408 additional_node_inst_1.len() as u32,
1409 );
1410 bytecode.extend_from_slice(&additional_node_inst_1);
1411 append_node_header(
1412 &mut bytecode,
1413 RawParentType::Additional,
1414 3,
1415 additional_node_inst_2.len() as u32,
1416 );
1417 bytecode.extend_from_slice(&additional_node_inst_2);
1418
1419 assert_eq!(Err(BytecodeError::InvalidPrimaryParent), DecodedRules::new(bytecode));
1420 }
1421
1422 #[test]
1423 fn test_primary_node_incorrect_order() {
1424 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1425 bytecode.push(BYTECODE_DISABLE_DEBUG);
1426 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1427
1428 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1430 bytecode.extend_from_slice(&device_name);
1431
1432 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1434 bytecode.extend_from_slice(&primary_node_name);
1435
1436 let additional_node_name: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1438 bytecode.extend_from_slice(&additional_node_name);
1439
1440 let primary_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1441 let additional_node_inst = [0x30];
1442
1443 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1444 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1445 as u32;
1446 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1447
1448 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1450
1451 append_node_header(
1453 &mut bytecode,
1454 RawParentType::Additional,
1455 3,
1456 additional_node_inst.len() as u32,
1457 );
1458 bytecode.extend_from_slice(&additional_node_inst);
1459 append_node_header(
1460 &mut bytecode,
1461 RawParentType::Primary,
1462 2,
1463 primary_node_inst.len() as u32,
1464 );
1465 bytecode.extend_from_slice(&primary_node_inst);
1466
1467 assert_eq!(Err(BytecodeError::InvalidPrimaryParent), DecodedRules::new(bytecode));
1468 }
1469
1470 #[test]
1471 fn test_multiple_primary_nodes() {
1472 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1473 bytecode.push(BYTECODE_DISABLE_DEBUG);
1474 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 29);
1475
1476 let device_name: [u8; 5] = [0x4C, 0x4F, 0x4F, 0x4E, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1478 bytecode.extend_from_slice(&device_name);
1479
1480 let primary_node_name: [u8; 6] = [0x47, 0x52, 0x45, 0x42, 0x45, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1482 bytecode.extend_from_slice(&primary_node_name);
1483
1484 let primary_node_name_2: [u8; 6] = [0x53, 0x43, 0x41, 0x55, 0x50, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1486 bytecode.extend_from_slice(&primary_node_name_2);
1487
1488 let primary_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x01, 0, 0, 0, 0x10];
1489 let primary_node_inst_2 = [0x30];
1490
1491 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1492 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + primary_node_inst_2.len())
1493 as u32;
1494 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1495
1496 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1498
1499 append_node_header(
1501 &mut bytecode,
1502 RawParentType::Primary,
1503 2,
1504 primary_node_inst.len() as u32,
1505 );
1506 bytecode.extend_from_slice(&primary_node_inst);
1507 append_node_header(
1508 &mut bytecode,
1509 RawParentType::Primary,
1510 3,
1511 primary_node_inst_2.len() as u32,
1512 );
1513 bytecode.extend_from_slice(&primary_node_inst_2);
1514
1515 assert_eq!(Err(BytecodeError::MultiplePrimaryParents), DecodedRules::new(bytecode));
1516 }
1517
1518 #[test]
1519 fn test_invalid_node_type() {
1520 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1521 bytecode.push(BYTECODE_DISABLE_DEBUG);
1522 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1523
1524 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1526 bytecode.extend_from_slice(&device_name);
1527
1528 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1530 bytecode.extend_from_slice(&primary_node_name);
1531
1532 let primary_node_inst = [0x30];
1533
1534 let composite_insts_sz =
1535 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1536 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1537
1538 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1540
1541 bytecode.push(0x53);
1543 bytecode.extend_from_slice(&[2, 0, 0, 0]);
1544 bytecode.extend_from_slice(&(primary_node_inst.len() as u32).to_le_bytes());
1545 bytecode.extend_from_slice(&primary_node_inst);
1546
1547 assert_eq!(Err(BytecodeError::InvalidParentType(0x53)), DecodedRules::new(bytecode));
1548 }
1549
1550 #[test]
1551 fn test_incorrect_node_section_sz_overlap() {
1552 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1553 bytecode.push(BYTECODE_DISABLE_DEBUG);
1554 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 27);
1555
1556 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1558 bytecode.extend_from_slice(&device_name);
1559
1560 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1562 bytecode.extend_from_slice(&primary_node_name);
1563
1564 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1566 bytecode.extend_from_slice(&node_name_1);
1567
1568 let primary_node_inst = [0x30];
1569 let additional_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1570
1571 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1572 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1573 as u32;
1574 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1575
1576 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1578
1579 append_node_header(&mut bytecode, RawParentType::Primary, 2, 7);
1582 bytecode.extend_from_slice(&primary_node_inst);
1583
1584 append_node_header(
1585 &mut bytecode,
1586 RawParentType::Additional,
1587 3,
1588 additional_node_inst.len() as u32,
1589 );
1590 bytecode.extend_from_slice(&additional_node_inst);
1591
1592 assert_eq!(
1594 Err(BytecodeError::InvalidOp(RawParentType::Additional as u8)),
1595 DecodedRules::new(bytecode)
1596 );
1597 }
1598
1599 #[test]
1600 fn test_incorrect_node_section_sz_undersize() {
1601 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1602 bytecode.push(BYTECODE_DISABLE_DEBUG);
1603 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 27);
1604
1605 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1607 bytecode.extend_from_slice(&device_name);
1608
1609 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1611 bytecode.extend_from_slice(&primary_node_name);
1612
1613 let node_name_1: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[3, 0, 0, 0]);
1615 bytecode.extend_from_slice(&node_name_1);
1616
1617 let primary_node_inst = [0x30];
1618 let additional_node_inst = [0x02, 0x01, 0, 0, 0, 0x02, 0x02, 0, 0, 0x10];
1619
1620 let composite_insts_sz = COMPOSITE_NAME_ID_BYTES
1621 + ((NODE_TYPE_HEADER_SZ * 2) + primary_node_inst.len() + additional_node_inst.len())
1622 as u32;
1623 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1624
1625 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1627
1628 append_node_header(
1629 &mut bytecode,
1630 RawParentType::Primary,
1631 2,
1632 primary_node_inst.len() as u32,
1633 );
1634 bytecode.extend_from_slice(&primary_node_inst);
1635
1636 append_node_header(&mut bytecode, RawParentType::Additional, 3, 1);
1638 bytecode.extend_from_slice(&additional_node_inst);
1639
1640 assert_eq!(Err(BytecodeError::UnexpectedEnd), DecodedRules::new(bytecode));
1642 }
1643
1644 #[test]
1645 fn test_incorrect_node_section_sz_oversize() {
1646 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1647 bytecode.push(BYTECODE_DISABLE_DEBUG);
1648 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1649
1650 let device_name: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1652 bytecode.extend_from_slice(&device_name);
1653
1654 let primary_node_name: [u8; 5] = [0x43, 0x4F, 0x4F, 0x54, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1656 bytecode.extend_from_slice(&primary_node_name);
1657
1658 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1659
1660 let composite_insts_sz =
1661 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1662 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1663
1664 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1666
1667 append_node_header(&mut bytecode, RawParentType::Primary, 2, 50);
1669 bytecode.extend_from_slice(&primary_node_inst);
1670
1671 assert_eq!(Err(BytecodeError::IncorrectParentSectionSize), DecodedRules::new(bytecode));
1672 }
1673
1674 #[test]
1675 fn test_composite_header_in_noncomposite_bytecode() {
1676 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1677 bytecode.push(BYTECODE_DISABLE_DEBUG);
1678 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 18);
1679
1680 let str_1: [u8; 5] = [0x49, 0x42, 0x49, 0x53, 0]; bytecode.extend_from_slice(&[1, 0, 0, 0]);
1682 bytecode.extend_from_slice(&str_1);
1683
1684 let primary_node_name: [u8; 5] = [0x52, 0x41, 0x49, 0x4C, 0]; bytecode.extend_from_slice(&[2, 0, 0, 0]);
1686 bytecode.extend_from_slice(&primary_node_name);
1687
1688 let primary_node_inst = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x01, 0x10, 0, 0x20, 0];
1689
1690 let composite_insts_sz =
1691 COMPOSITE_NAME_ID_BYTES + (NODE_TYPE_HEADER_SZ + primary_node_inst.len()) as u32;
1692 append_section_header(&mut bytecode, COMPOSITE_MAGIC_NUM, composite_insts_sz);
1693
1694 bytecode.extend_from_slice(&[1, 0, 0, 0]);
1696
1697 append_node_header(
1699 &mut bytecode,
1700 RawParentType::Primary,
1701 2,
1702 primary_node_inst.len() as u32,
1703 );
1704 bytecode.extend_from_slice(&primary_node_inst);
1705
1706 assert_eq!(
1707 Err(BytecodeError::InvalidHeader(INSTRUCTION_MAGIC_NUM, COMPOSITE_MAGIC_NUM)),
1708 DecodedBindRules::from_bytecode(bytecode)
1709 );
1710 }
1711
1712 #[test]
1713 fn test_inst_header_in_composite_bytecode() {
1714 let mut bytecode: Vec<u8> = BIND_HEADER.to_vec();
1715 bytecode.push(BYTECODE_DISABLE_DEBUG);
1716 append_section_header(&mut bytecode, SYMB_MAGIC_NUM, 0);
1717
1718 let instructions = [0x30, 0x01, 0x01, 0, 0, 0, 0x05, 0x10, 0, 0, 0x10];
1719 append_section_header(&mut bytecode, INSTRUCTION_MAGIC_NUM, instructions.len() as u32);
1720 bytecode.extend_from_slice(&instructions);
1721
1722 assert_eq!(
1723 Err(BytecodeError::InvalidHeader(COMPOSITE_MAGIC_NUM, INSTRUCTION_MAGIC_NUM)),
1724 DecodedCompositeBindRules::from_bytecode(bytecode)
1725 );
1726 }
1727
1728 #[test]
1729 fn test_composite_with_compiler() {
1730 use crate::compiler::{
1731 CompiledBindRules, CompositeBindRules, CompositeParent, Symbol, SymbolicInstruction,
1732 SymbolicInstructionInfo,
1733 };
1734 use crate::parser::bind_library::ValueType;
1735
1736 let primary_node_inst = vec![SymbolicInstructionInfo {
1737 location: None,
1738 instruction: SymbolicInstruction::UnconditionalAbort,
1739 }];
1740
1741 let additional_node_inst = vec![
1742 SymbolicInstructionInfo {
1743 location: None,
1744 instruction: SymbolicInstruction::AbortIfEqual {
1745 lhs: Symbol::Key("bobolink".to_string(), ValueType::Bool),
1746 rhs: Symbol::BoolValue(false),
1747 },
1748 },
1749 SymbolicInstructionInfo {
1750 location: None,
1751 instruction: SymbolicInstruction::AbortIfNotEqual {
1752 lhs: Symbol::Key("grackle".to_string(), ValueType::Number),
1753 rhs: Symbol::NumberValue(1),
1754 },
1755 },
1756 ];
1757
1758 let bytecode = CompiledBindRules::CompositeBind(CompositeBindRules {
1759 device_name: "blackbird".to_string(),
1760 symbol_table: HashMap::new(),
1761 primary_parent: CompositeParent {
1762 name: "meadowlark".to_string(),
1763 instructions: primary_node_inst,
1764 },
1765 additional_parents: vec![CompositeParent {
1766 name: "cowbird".to_string(),
1767 instructions: additional_node_inst,
1768 }],
1769 optional_parents: vec![],
1770 enable_debug: false,
1771 })
1772 .encode_to_bytecode()
1773 .unwrap();
1774
1775 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1776 expected_symbol_table.insert(1, "blackbird".to_string());
1777 expected_symbol_table.insert(2, "meadowlark".to_string());
1778 expected_symbol_table.insert(3, "cowbird".to_string());
1779 expected_symbol_table.insert(4, "bobolink".to_string());
1780 expected_symbol_table.insert(5, "grackle".to_string());
1781
1782 let primary_node_inst = [0x30];
1783 let additional_node_inst = [
1784 0x02, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x01, 0x1, 0x0, 0x0, 0x0, ];
1787
1788 assert_eq!(
1789 DecodedRules::Composite(DecodedCompositeBindRules {
1790 symbol_table: expected_symbol_table,
1791 device_name_id: 1,
1792 primary_parent: Parent {
1793 name_id: 2,
1794 instructions: primary_node_inst.to_vec(),
1795 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
1796 },
1797 additional_parents: vec![Parent {
1798 name_id: 3,
1799 instructions: additional_node_inst.to_vec(),
1800 decoded_instructions: vec![
1801 DecodedInstruction::Condition(DecodedCondition {
1802 is_equal: false,
1803 lhs: Symbol::Key("bobolink".to_string(), ValueType::Str),
1804 rhs: Symbol::BoolValue(false)
1805 }),
1806 DecodedInstruction::Condition(DecodedCondition {
1807 is_equal: true,
1808 lhs: Symbol::Key("grackle".to_string(), ValueType::Str),
1809 rhs: Symbol::NumberValue(1)
1810 })
1811 ]
1812 }],
1813 optional_parents: vec![],
1814 debug_info: None,
1815 }),
1816 DecodedRules::new(bytecode).unwrap()
1817 );
1818 }
1819
1820 #[test]
1821 fn test_composite_optional_with_compiler() {
1822 use crate::compiler::{
1823 CompiledBindRules, CompositeBindRules, CompositeParent, Symbol, SymbolicInstruction,
1824 SymbolicInstructionInfo,
1825 };
1826 use crate::parser::bind_library::ValueType;
1827
1828 let primary_node_inst = vec![SymbolicInstructionInfo {
1829 location: None,
1830 instruction: SymbolicInstruction::UnconditionalAbort,
1831 }];
1832
1833 let additional_node_inst = vec![
1834 SymbolicInstructionInfo {
1835 location: None,
1836 instruction: SymbolicInstruction::AbortIfEqual {
1837 lhs: Symbol::Key("bobolink".to_string(), ValueType::Bool),
1838 rhs: Symbol::BoolValue(false),
1839 },
1840 },
1841 SymbolicInstructionInfo {
1842 location: None,
1843 instruction: SymbolicInstruction::AbortIfNotEqual {
1844 lhs: Symbol::Key("grackle".to_string(), ValueType::Number),
1845 rhs: Symbol::NumberValue(1),
1846 },
1847 },
1848 ];
1849
1850 let optional_node_inst = vec![SymbolicInstructionInfo {
1851 location: None,
1852 instruction: SymbolicInstruction::AbortIfEqual {
1853 lhs: Symbol::Key("mockingbird".to_string(), ValueType::Bool),
1854 rhs: Symbol::BoolValue(false),
1855 },
1856 }];
1857
1858 let bytecode = CompiledBindRules::CompositeBind(CompositeBindRules {
1859 device_name: "blackbird".to_string(),
1860 symbol_table: HashMap::new(),
1861 primary_parent: CompositeParent {
1862 name: "meadowlark".to_string(),
1863 instructions: primary_node_inst,
1864 },
1865 additional_parents: vec![CompositeParent {
1866 name: "cowbird".to_string(),
1867 instructions: additional_node_inst,
1868 }],
1869 optional_parents: vec![CompositeParent {
1870 name: "cowbird_optional".to_string(),
1871 instructions: optional_node_inst,
1872 }],
1873 enable_debug: false,
1874 })
1875 .encode_to_bytecode()
1876 .unwrap();
1877
1878 let mut expected_symbol_table: HashMap<u32, String> = HashMap::new();
1879 expected_symbol_table.insert(1, "blackbird".to_string());
1880 expected_symbol_table.insert(2, "meadowlark".to_string());
1881 expected_symbol_table.insert(3, "cowbird".to_string());
1882 expected_symbol_table.insert(4, "bobolink".to_string());
1883 expected_symbol_table.insert(5, "grackle".to_string());
1884 expected_symbol_table.insert(6, "cowbird_optional".to_string());
1885 expected_symbol_table.insert(7, "mockingbird".to_string());
1886
1887 let primary_node_inst = [0x30];
1888 let additional_node_inst = [
1889 0x02, 0x0, 0x04, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x05, 0x0, 0x0, 0x0, 0x01, 0x1, 0x0, 0x0, 0x0, ];
1892
1893 let optional_node_inst = [
1894 0x02, 0x0, 0x07, 0x0, 0x0, 0x0, 0x03, 0x0, 0x0, 0x0, 0x0, ];
1896
1897 assert_eq!(
1898 DecodedRules::Composite(DecodedCompositeBindRules {
1899 symbol_table: expected_symbol_table,
1900 device_name_id: 1,
1901 primary_parent: Parent {
1902 name_id: 2,
1903 instructions: primary_node_inst.to_vec(),
1904 decoded_instructions: vec![DecodedInstruction::UnconditionalAbort],
1905 },
1906 additional_parents: vec![Parent {
1907 name_id: 3,
1908 instructions: additional_node_inst.to_vec(),
1909 decoded_instructions: vec![
1910 DecodedInstruction::Condition(DecodedCondition {
1911 is_equal: false,
1912 lhs: Symbol::Key("bobolink".to_string(), ValueType::Str),
1913 rhs: Symbol::BoolValue(false)
1914 }),
1915 DecodedInstruction::Condition(DecodedCondition {
1916 is_equal: true,
1917 lhs: Symbol::Key("grackle".to_string(), ValueType::Str),
1918 rhs: Symbol::NumberValue(1)
1919 })
1920 ]
1921 }],
1922 optional_parents: vec![Parent {
1923 name_id: 6,
1924 instructions: optional_node_inst.to_vec(),
1925 decoded_instructions: vec![DecodedInstruction::Condition(DecodedCondition {
1926 is_equal: false,
1927 lhs: Symbol::Key("mockingbird".to_string(), ValueType::Str),
1928 rhs: Symbol::BoolValue(false)
1929 })],
1930 }],
1931 debug_info: None,
1932 }),
1933 DecodedRules::new(bytecode).unwrap()
1934 );
1935 }
1936}