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