1use crate::parser::ast::{Endianness, TypeKind, Value};
10use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian};
11use thiserror::Error;
12
13#[derive(Debug, Error, PartialEq, Eq)]
15pub enum TypeReadError {
16 #[error(
18 "Buffer overrun: attempted to read at offset {offset} but buffer length is {buffer_len}"
19 )]
20 BufferOverrun {
21 offset: usize,
23 buffer_len: usize,
25 },
26 #[error("Unsupported type: {type_name}")]
28 UnsupportedType {
29 type_name: String,
31 },
32}
33
34pub fn read_byte(buffer: &[u8], offset: usize) -> Result<Value, TypeReadError> {
78 buffer
79 .get(offset)
80 .map(|&byte| Value::Uint(u64::from(byte)))
81 .ok_or(TypeReadError::BufferOverrun {
82 offset,
83 buffer_len: buffer.len(),
84 })
85}
86
87pub fn read_short(
123 buffer: &[u8],
124 offset: usize,
125 endian: Endianness,
126 signed: bool,
127) -> Result<Value, TypeReadError> {
128 let bytes = buffer
129 .get(offset..offset + 2)
130 .ok_or(TypeReadError::BufferOverrun {
131 offset,
132 buffer_len: buffer.len(),
133 })?;
134
135 let value = match endian {
136 Endianness::Little => LittleEndian::read_u16(bytes),
137 Endianness::Big => BigEndian::read_u16(bytes),
138 Endianness::Native => NativeEndian::read_u16(bytes),
139 };
140
141 if signed {
142 #[allow(clippy::cast_possible_wrap)]
143 Ok(Value::Int(i64::from(value as i16)))
144 } else {
145 Ok(Value::Uint(u64::from(value)))
146 }
147}
148
149pub fn read_long(
185 buffer: &[u8],
186 offset: usize,
187 endian: Endianness,
188 signed: bool,
189) -> Result<Value, TypeReadError> {
190 let bytes = buffer
191 .get(offset..offset + 4)
192 .ok_or(TypeReadError::BufferOverrun {
193 offset,
194 buffer_len: buffer.len(),
195 })?;
196
197 let value = match endian {
198 Endianness::Little => LittleEndian::read_u32(bytes),
199 Endianness::Big => BigEndian::read_u32(bytes),
200 Endianness::Native => NativeEndian::read_u32(bytes),
201 };
202
203 if signed {
204 #[allow(clippy::cast_possible_wrap)]
205 Ok(Value::Int(i64::from(value as i32)))
206 } else {
207 Ok(Value::Uint(u64::from(value)))
208 }
209}
210
211pub fn read_string(
276 buffer: &[u8],
277 offset: usize,
278 max_length: Option<usize>,
279) -> Result<Value, TypeReadError> {
280 if offset >= buffer.len() {
282 return Err(TypeReadError::BufferOverrun {
283 offset,
284 buffer_len: buffer.len(),
285 });
286 }
287
288 let remaining_buffer = &buffer[offset..];
290
291 let read_length = if let Some(max_len) = max_length {
293 let search_len = std::cmp::min(max_len, remaining_buffer.len());
295 memchr::memchr(0, &remaining_buffer[..search_len]).unwrap_or(search_len)
296 } else {
297 memchr::memchr(0, remaining_buffer).unwrap_or(remaining_buffer.len())
299 };
300
301 let string_bytes = &remaining_buffer[..read_length];
303
304 let string_value = String::from_utf8_lossy(string_bytes).into_owned();
306
307 Ok(Value::String(string_value))
308}
309
310pub fn read_typed_value(
351 buffer: &[u8],
352 offset: usize,
353 type_kind: &TypeKind,
354) -> Result<Value, TypeReadError> {
355 match type_kind {
356 TypeKind::Byte => read_byte(buffer, offset),
357 TypeKind::Short { endian, signed } => read_short(buffer, offset, *endian, *signed),
358 TypeKind::Long { endian, signed } => read_long(buffer, offset, *endian, *signed),
359 TypeKind::String { max_length } => read_string(buffer, offset, *max_length),
360 }
361}
362
363#[cfg(test)]
364mod tests {
365 use super::*;
366
367 #[test]
368 fn test_read_byte_success() {
369 let buffer = &[0x7f, 0x45, 0x4c, 0x46];
370
371 assert_eq!(read_byte(buffer, 0).unwrap(), Value::Uint(0x7f));
373 assert_eq!(read_byte(buffer, 1).unwrap(), Value::Uint(0x45));
374 assert_eq!(read_byte(buffer, 2).unwrap(), Value::Uint(0x4c));
375 assert_eq!(read_byte(buffer, 3).unwrap(), Value::Uint(0x46));
376 }
377
378 #[test]
379 fn test_read_byte_zero_value() {
380 let buffer = &[0x00, 0xff];
381
382 assert_eq!(read_byte(buffer, 0).unwrap(), Value::Uint(0));
384 assert_eq!(read_byte(buffer, 1).unwrap(), Value::Uint(255));
386 }
387
388 #[test]
389 fn test_read_byte_single_byte_buffer() {
390 let buffer = &[0x42];
391
392 assert_eq!(read_byte(buffer, 0).unwrap(), Value::Uint(0x42));
394
395 let result = read_byte(buffer, 1);
397 assert!(result.is_err());
398 assert_eq!(
399 result.unwrap_err(),
400 TypeReadError::BufferOverrun {
401 offset: 1,
402 buffer_len: 1
403 }
404 );
405 }
406
407 #[test]
408 fn test_read_byte_empty_buffer() {
409 let buffer = &[];
410
411 let result = read_byte(buffer, 0);
413 assert!(result.is_err());
414 assert_eq!(
415 result.unwrap_err(),
416 TypeReadError::BufferOverrun {
417 offset: 0,
418 buffer_len: 0
419 }
420 );
421 }
422
423 #[test]
424 fn test_read_byte_out_of_bounds() {
425 let buffer = &[0x01, 0x02, 0x03];
426
427 let test_cases = [3, 4, 10, 100, usize::MAX];
429
430 for offset in test_cases {
431 let result = read_byte(buffer, offset);
432 assert!(result.is_err());
433 assert_eq!(
434 result.unwrap_err(),
435 TypeReadError::BufferOverrun {
436 offset,
437 buffer_len: 3
438 }
439 );
440 }
441 }
442
443 #[test]
444 fn test_read_byte_large_buffer() {
445 let buffer: Vec<u8> = (0..=255).collect();
447
448 assert_eq!(read_byte(&buffer, 0).unwrap(), Value::Uint(0));
450 assert_eq!(read_byte(&buffer, 127).unwrap(), Value::Uint(127));
451 assert_eq!(read_byte(&buffer, 255).unwrap(), Value::Uint(255));
452
453 let result = read_byte(&buffer, 256);
455 assert!(result.is_err());
456 assert_eq!(
457 result.unwrap_err(),
458 TypeReadError::BufferOverrun {
459 offset: 256,
460 buffer_len: 256
461 }
462 );
463 }
464
465 #[test]
466 fn test_read_byte_all_byte_values() {
467 let buffer: Vec<u8> = (0..=255).collect();
469
470 for (i, &expected_byte) in buffer.iter().enumerate() {
471 let result = read_byte(&buffer, i).unwrap();
472 assert_eq!(result, Value::Uint(u64::from(expected_byte)));
473 }
474 }
475
476 #[test]
477 fn test_type_read_error_display() {
478 let error = TypeReadError::BufferOverrun {
479 offset: 10,
480 buffer_len: 5,
481 };
482
483 let error_string = format!("{error}");
484 assert!(error_string.contains("Buffer overrun"));
485 assert!(error_string.contains("offset 10"));
486 assert!(error_string.contains("buffer length is 5"));
487 }
488
489 #[test]
490 fn test_type_read_error_debug() {
491 let error = TypeReadError::BufferOverrun {
492 offset: 42,
493 buffer_len: 20,
494 };
495
496 let debug_string = format!("{error:?}");
497 assert!(debug_string.contains("BufferOverrun"));
498 assert!(debug_string.contains("offset: 42"));
499 assert!(debug_string.contains("buffer_len: 20"));
500 }
501
502 #[test]
503 fn test_type_read_error_equality() {
504 let error1 = TypeReadError::BufferOverrun {
505 offset: 5,
506 buffer_len: 3,
507 };
508 let error2 = TypeReadError::BufferOverrun {
509 offset: 5,
510 buffer_len: 3,
511 };
512 let error3 = TypeReadError::BufferOverrun {
513 offset: 6,
514 buffer_len: 3,
515 };
516
517 assert_eq!(error1, error2);
518 assert_ne!(error1, error3);
519 }
520
521 #[test]
522 fn test_read_byte_boundary_conditions() {
523 let buffer = &[0xaa, 0xbb, 0xcc];
524
525 assert_eq!(read_byte(buffer, 2).unwrap(), Value::Uint(0xcc));
527
528 let result = read_byte(buffer, 3);
530 assert!(result.is_err());
531 }
532
533 #[test]
534 fn test_read_byte_return_type() {
535 let buffer = &[0x80]; let result = read_byte(buffer, 0).unwrap();
538
539 match result {
541 Value::Uint(val) => assert_eq!(val, 0x80),
542 _ => panic!("Expected Value::Uint variant"),
543 }
544 }
545
546 #[test]
548 fn test_read_short_little_endian_unsigned() {
549 let buffer = &[0x34, 0x12, 0x78, 0x56]; let result = read_short(buffer, 0, Endianness::Little, false).unwrap();
553 assert_eq!(result, Value::Uint(0x1234));
554
555 let result = read_short(buffer, 2, Endianness::Little, false).unwrap();
557 assert_eq!(result, Value::Uint(0x5678));
558 }
559
560 #[test]
561 fn test_read_short_big_endian_unsigned() {
562 let buffer = &[0x12, 0x34, 0x56, 0x78]; let result = read_short(buffer, 0, Endianness::Big, false).unwrap();
566 assert_eq!(result, Value::Uint(0x1234));
567
568 let result = read_short(buffer, 2, Endianness::Big, false).unwrap();
570 assert_eq!(result, Value::Uint(0x5678));
571 }
572
573 #[test]
574 fn test_read_short_native_endian_unsigned() {
575 let buffer = &[0x34, 0x12, 0x78, 0x56];
576
577 let result = read_short(buffer, 0, Endianness::Native, false).unwrap();
579
580 match result {
582 Value::Uint(val) => {
583 assert!(val == 0x1234 || val == 0x3412);
585 }
586 _ => panic!("Expected Value::Uint variant"),
587 }
588 }
589
590 #[test]
591 fn test_read_short_signed_positive() {
592 let buffer = &[0xff, 0x7f]; let result = read_short(buffer, 0, Endianness::Little, true).unwrap();
595 assert_eq!(result, Value::Int(32767));
596 }
597
598 #[test]
599 fn test_read_short_signed_negative() {
600 let buffer = &[0x00, 0x80]; let result = read_short(buffer, 0, Endianness::Little, true).unwrap();
603 assert_eq!(result, Value::Int(-32768));
604 }
605
606 #[test]
607 fn test_read_short_signed_vs_unsigned() {
608 let buffer = &[0xff, 0xff]; let unsigned_result = read_short(buffer, 0, Endianness::Little, false).unwrap();
612 assert_eq!(unsigned_result, Value::Uint(65535));
613
614 let signed_result = read_short(buffer, 0, Endianness::Little, true).unwrap();
616 assert_eq!(signed_result, Value::Int(-1));
617 }
618
619 #[test]
620 fn test_read_short_buffer_overrun() {
621 let buffer = &[0x12]; let result = read_short(buffer, 0, Endianness::Little, false);
625 assert!(result.is_err());
626 assert_eq!(
627 result.unwrap_err(),
628 TypeReadError::BufferOverrun {
629 offset: 0,
630 buffer_len: 1
631 }
632 );
633 }
634
635 #[test]
636 fn test_read_short_offset_out_of_bounds() {
637 let buffer = &[0x12, 0x34, 0x56];
638
639 let result = read_short(buffer, 2, Endianness::Little, false);
641 assert!(result.is_err());
642 assert_eq!(
643 result.unwrap_err(),
644 TypeReadError::BufferOverrun {
645 offset: 2,
646 buffer_len: 3
647 }
648 );
649 }
650
651 #[test]
652 fn test_read_short_empty_buffer() {
653 let buffer = &[];
654
655 let result = read_short(buffer, 0, Endianness::Little, false);
656 assert!(result.is_err());
657 assert_eq!(
658 result.unwrap_err(),
659 TypeReadError::BufferOverrun {
660 offset: 0,
661 buffer_len: 0
662 }
663 );
664 }
665
666 #[test]
667 fn test_read_short_all_endianness_variants() {
668 let buffer = &[0x12, 0x34];
669
670 let little = read_short(buffer, 0, Endianness::Little, false).unwrap();
672 let big = read_short(buffer, 0, Endianness::Big, false).unwrap();
673 let native = read_short(buffer, 0, Endianness::Native, false).unwrap();
674
675 assert_eq!(little, Value::Uint(0x3412));
677 assert_eq!(big, Value::Uint(0x1234));
678
679 match native {
681 Value::Uint(val) => assert!(val == 0x1234 || val == 0x3412),
682 _ => panic!("Expected Value::Uint variant"),
683 }
684 }
685
686 #[test]
688 fn test_read_long_little_endian_unsigned() {
689 let buffer = &[0x78, 0x56, 0x34, 0x12, 0xbc, 0x9a, 0x78, 0x56]; let result = read_long(buffer, 0, Endianness::Little, false).unwrap();
693 assert_eq!(result, Value::Uint(0x1234_5678));
694
695 let result = read_long(buffer, 4, Endianness::Little, false).unwrap();
697 assert_eq!(result, Value::Uint(0x5678_9abc));
698 }
699
700 #[test]
701 fn test_read_long_big_endian_unsigned() {
702 let buffer = &[0x12, 0x34, 0x56, 0x78, 0x56, 0x78, 0x9a, 0xbc]; let result = read_long(buffer, 0, Endianness::Big, false).unwrap();
706 assert_eq!(result, Value::Uint(0x1234_5678));
707
708 let result = read_long(buffer, 4, Endianness::Big, false).unwrap();
710 assert_eq!(result, Value::Uint(0x5678_9abc));
711 }
712
713 #[test]
714 fn test_read_long_native_endian_unsigned() {
715 let buffer = &[0x78, 0x56, 0x34, 0x12];
716
717 let result = read_long(buffer, 0, Endianness::Native, false).unwrap();
719
720 match result {
722 Value::Uint(val) => {
723 assert!(val == 0x1234_5678 || val == 0x7856_3412);
725 }
726 _ => panic!("Expected Value::Uint variant"),
727 }
728 }
729
730 #[test]
731 fn test_read_long_signed_positive() {
732 let buffer = &[0xff, 0xff, 0xff, 0x7f]; let result = read_long(buffer, 0, Endianness::Little, true).unwrap();
735 assert_eq!(result, Value::Int(2_147_483_647));
736 }
737
738 #[test]
739 fn test_read_long_signed_negative() {
740 let buffer = &[0x00, 0x00, 0x00, 0x80]; let result = read_long(buffer, 0, Endianness::Little, true).unwrap();
743 assert_eq!(result, Value::Int(-2_147_483_648));
744 }
745
746 #[test]
747 fn test_read_long_signed_vs_unsigned() {
748 let buffer = &[0xff, 0xff, 0xff, 0xff]; let unsigned_result = read_long(buffer, 0, Endianness::Little, false).unwrap();
752 assert_eq!(unsigned_result, Value::Uint(4_294_967_295));
753
754 let signed_result = read_long(buffer, 0, Endianness::Little, true).unwrap();
756 assert_eq!(signed_result, Value::Int(-1));
757 }
758
759 #[test]
760 fn test_read_long_buffer_overrun() {
761 let buffer = &[0x12, 0x34, 0x56]; let result = read_long(buffer, 0, Endianness::Little, false);
765 assert!(result.is_err());
766 assert_eq!(
767 result.unwrap_err(),
768 TypeReadError::BufferOverrun {
769 offset: 0,
770 buffer_len: 3
771 }
772 );
773 }
774
775 #[test]
776 fn test_read_long_offset_out_of_bounds() {
777 let buffer = &[0x12, 0x34, 0x56, 0x78, 0x9a];
778
779 let result = read_long(buffer, 2, Endianness::Little, false);
781 assert!(result.is_err());
782 assert_eq!(
783 result.unwrap_err(),
784 TypeReadError::BufferOverrun {
785 offset: 2,
786 buffer_len: 5
787 }
788 );
789 }
790
791 #[test]
792 fn test_read_long_empty_buffer() {
793 let buffer = &[];
794
795 let result = read_long(buffer, 0, Endianness::Little, false);
796 assert!(result.is_err());
797 assert_eq!(
798 result.unwrap_err(),
799 TypeReadError::BufferOverrun {
800 offset: 0,
801 buffer_len: 0
802 }
803 );
804 }
805
806 #[test]
807 fn test_read_long_all_endianness_variants() {
808 let buffer = &[0x12, 0x34, 0x56, 0x78];
809
810 let little = read_long(buffer, 0, Endianness::Little, false).unwrap();
812 let big = read_long(buffer, 0, Endianness::Big, false).unwrap();
813 let native = read_long(buffer, 0, Endianness::Native, false).unwrap();
814
815 assert_eq!(little, Value::Uint(0x7856_3412));
817 assert_eq!(big, Value::Uint(0x1234_5678));
818
819 match native {
821 Value::Uint(val) => assert!(val == 0x1234_5678 || val == 0x7856_3412),
822 _ => panic!("Expected Value::Uint variant"),
823 }
824 }
825
826 #[test]
827 fn test_read_long_extreme_values() {
828 let max_buffer = &[0xff, 0xff, 0xff, 0xff];
830 let max_result = read_long(max_buffer, 0, Endianness::Little, false).unwrap();
831 assert_eq!(max_result, Value::Uint(u64::from(u32::MAX)));
832
833 let zero_buffer = &[0x00, 0x00, 0x00, 0x00];
835 let zero_result = read_long(zero_buffer, 0, Endianness::Little, false).unwrap();
836 assert_eq!(zero_result, Value::Uint(0));
837 }
838
839 #[test]
840 fn test_read_short_extreme_values() {
841 let max_buffer = &[0xff, 0xff];
843 let max_result = read_short(max_buffer, 0, Endianness::Little, false).unwrap();
844 assert_eq!(max_result, Value::Uint(u64::from(u16::MAX)));
845
846 let zero_buffer = &[0x00, 0x00];
848 let zero_result = read_short(zero_buffer, 0, Endianness::Little, false).unwrap();
849 assert_eq!(zero_result, Value::Uint(0));
850 }
851
852 #[test]
853 fn test_multi_byte_reading_consistency() {
854 let buffer = &[0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xde, 0xf0];
856
857 let byte0 = read_byte(buffer, 0).unwrap();
859 let byte1 = read_byte(buffer, 1).unwrap();
860
861 let short = read_short(buffer, 0, Endianness::Little, false).unwrap();
863
864 match (byte0, byte1, short) {
866 (Value::Uint(b0), Value::Uint(b1), Value::Uint(s)) => {
867 assert_eq!(s, b0 + (b1 << 8)); }
869 _ => panic!("Expected all Uint values"),
870 }
871 }
872
873 #[test]
875 fn test_unsupported_type_error() {
876 let error = TypeReadError::UnsupportedType {
877 type_name: "CustomType".to_string(),
878 };
879
880 let error_string = format!("{error}");
881 assert!(error_string.contains("Unsupported type"));
882 assert!(error_string.contains("CustomType"));
883 }
884
885 #[test]
886 fn test_unsupported_type_error_debug() {
887 let error = TypeReadError::UnsupportedType {
888 type_name: "TestType".to_string(),
889 };
890
891 let debug_string = format!("{error:?}");
892 assert!(debug_string.contains("UnsupportedType"));
893 assert!(debug_string.contains("TestType"));
894 }
895
896 #[test]
897 fn test_unsupported_type_error_equality() {
898 let error1 = TypeReadError::UnsupportedType {
899 type_name: "Type1".to_string(),
900 };
901 let error2 = TypeReadError::UnsupportedType {
902 type_name: "Type1".to_string(),
903 };
904 let error3 = TypeReadError::UnsupportedType {
905 type_name: "Type2".to_string(),
906 };
907
908 assert_eq!(error1, error2);
909 assert_ne!(error1, error3);
910 }
911
912 #[test]
914 fn test_read_typed_value_byte() {
915 let buffer = &[0x7f, 0x45, 0x4c, 0x46];
916 let type_kind = TypeKind::Byte;
917
918 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
919 assert_eq!(result, Value::Uint(0x7f));
920
921 let result = read_typed_value(buffer, 3, &type_kind).unwrap();
922 assert_eq!(result, Value::Uint(0x46));
923 }
924
925 #[test]
926 fn test_read_typed_value_short_unsigned_little_endian() {
927 let buffer = &[0x34, 0x12, 0x78, 0x56];
928 let type_kind = TypeKind::Short {
929 endian: Endianness::Little,
930 signed: false,
931 };
932
933 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
934 assert_eq!(result, Value::Uint(0x1234));
935
936 let result = read_typed_value(buffer, 2, &type_kind).unwrap();
937 assert_eq!(result, Value::Uint(0x5678));
938 }
939
940 #[test]
941 fn test_read_typed_value_short_signed_big_endian() {
942 let buffer = &[0x80, 0x00, 0x7f, 0xff];
943 let type_kind = TypeKind::Short {
944 endian: Endianness::Big,
945 signed: true,
946 };
947
948 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
950 assert_eq!(result, Value::Int(-32768));
951
952 let result = read_typed_value(buffer, 2, &type_kind).unwrap();
954 assert_eq!(result, Value::Int(32767));
955 }
956
957 #[test]
958 fn test_read_typed_value_long_unsigned_little_endian() {
959 let buffer = &[0x78, 0x56, 0x34, 0x12, 0xbc, 0x9a, 0x78, 0x56];
960 let type_kind = TypeKind::Long {
961 endian: Endianness::Little,
962 signed: false,
963 };
964
965 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
966 assert_eq!(result, Value::Uint(0x1234_5678));
967
968 let result = read_typed_value(buffer, 4, &type_kind).unwrap();
969 assert_eq!(result, Value::Uint(0x5678_9abc));
970 }
971
972 #[test]
973 fn test_read_typed_value_long_signed_big_endian() {
974 let buffer = &[0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff];
975 let type_kind = TypeKind::Long {
976 endian: Endianness::Big,
977 signed: true,
978 };
979
980 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
982 assert_eq!(result, Value::Int(-2_147_483_648));
983
984 let result = read_typed_value(buffer, 4, &type_kind).unwrap();
986 assert_eq!(result, Value::Int(2_147_483_647));
987 }
988
989 #[test]
990 fn test_read_typed_value_native_endian() {
991 let buffer = &[0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xde, 0xf0];
992
993 let short_type = TypeKind::Short {
995 endian: Endianness::Native,
996 signed: false,
997 };
998
999 let result = read_typed_value(buffer, 0, &short_type).unwrap();
1000 match result {
1001 Value::Uint(val) => {
1002 assert!(val == 0x1234 || val == 0x3412);
1004 }
1005 _ => panic!("Expected Value::Uint variant"),
1006 }
1007 }
1008
1009 #[test]
1010 fn test_read_typed_value_string() {
1011 let buffer = b"Hello\x00World\x00";
1012 let type_kind = TypeKind::String { max_length: None };
1013
1014 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
1015 assert_eq!(result, Value::String("Hello".to_string()));
1016
1017 let result = read_typed_value(buffer, 6, &type_kind).unwrap();
1018 assert_eq!(result, Value::String("World".to_string()));
1019 }
1020
1021 #[test]
1022 fn test_read_typed_value_string_with_max_length() {
1023 let buffer = b"VeryLongString\x00";
1024 let type_kind = TypeKind::String {
1025 max_length: Some(4),
1026 };
1027
1028 let result = read_typed_value(buffer, 0, &type_kind).unwrap();
1029 assert_eq!(result, Value::String("Very".to_string()));
1030 }
1031
1032 #[test]
1033 fn test_read_typed_value_buffer_overrun() {
1034 let buffer = &[0x12];
1035 let type_kind = TypeKind::Short {
1036 endian: Endianness::Little,
1037 signed: false,
1038 };
1039
1040 let result = read_typed_value(buffer, 0, &type_kind);
1041 assert!(result.is_err());
1042 assert_eq!(
1043 result.unwrap_err(),
1044 TypeReadError::BufferOverrun {
1045 offset: 0,
1046 buffer_len: 1
1047 }
1048 );
1049 }
1050
1051 #[test]
1053 fn test_read_string_null_terminated() {
1054 let buffer = b"Hello\x00World";
1055
1056 let result = read_string(buffer, 0, None).unwrap();
1057 assert_eq!(result, Value::String("Hello".to_string()));
1058 }
1059
1060 #[test]
1061 fn test_read_string_null_terminated_at_offset() {
1062 let buffer = b"Prefix\x00Hello\x00Suffix";
1063
1064 let result = read_string(buffer, 7, None).unwrap();
1065 assert_eq!(result, Value::String("Hello".to_string()));
1066 }
1067
1068 #[test]
1069 fn test_read_string_with_max_length_shorter_than_null() {
1070 let buffer = b"VeryLongString\x00";
1071
1072 let result = read_string(buffer, 0, Some(4)).unwrap();
1074 assert_eq!(result, Value::String("Very".to_string()));
1075 }
1076
1077 #[test]
1078 fn test_read_string_with_max_length_longer_than_null() {
1079 let buffer = b"Short\x00LongerSuffix";
1080
1081 let result = read_string(buffer, 0, Some(10)).unwrap();
1083 assert_eq!(result, Value::String("Short".to_string()));
1084 }
1085
1086 #[test]
1087 fn test_read_string_no_null_terminator_with_max_length() {
1088 let buffer = b"NoNullTerminator";
1089
1090 let result = read_string(buffer, 0, Some(6)).unwrap();
1092 assert_eq!(result, Value::String("NoNull".to_string()));
1093 }
1094
1095 #[test]
1096 fn test_read_string_no_null_terminator_no_max_length() {
1097 let buffer = b"NoNullTerminator";
1098
1099 let result = read_string(buffer, 0, None).unwrap();
1101 assert_eq!(result, Value::String("NoNullTerminator".to_string()));
1102 }
1103
1104 #[test]
1105 fn test_read_string_empty_string() {
1106 let buffer = b"\x00Hello";
1107
1108 let result = read_string(buffer, 0, None).unwrap();
1110 assert_eq!(result, Value::String(String::new()));
1111 }
1112
1113 #[test]
1114 fn test_read_string_empty_buffer() {
1115 let buffer = b"";
1116
1117 let result = read_string(buffer, 0, None);
1119 assert!(result.is_err());
1120 assert_eq!(
1121 result.unwrap_err(),
1122 TypeReadError::BufferOverrun {
1123 offset: 0,
1124 buffer_len: 0
1125 }
1126 );
1127 }
1128
1129 #[test]
1130 fn test_read_string_offset_out_of_bounds() {
1131 let buffer = b"Hello";
1132
1133 let result = read_string(buffer, 10, None);
1135 assert!(result.is_err());
1136 assert_eq!(
1137 result.unwrap_err(),
1138 TypeReadError::BufferOverrun {
1139 offset: 10,
1140 buffer_len: 5
1141 }
1142 );
1143 }
1144
1145 #[test]
1146 fn test_read_string_offset_at_buffer_end() {
1147 let buffer = b"Hello";
1148
1149 let result = read_string(buffer, 5, None);
1151 assert!(result.is_err());
1152 assert_eq!(
1153 result.unwrap_err(),
1154 TypeReadError::BufferOverrun {
1155 offset: 5,
1156 buffer_len: 5
1157 }
1158 );
1159 }
1160
1161 #[test]
1162 fn test_read_string_max_length_zero() {
1163 let buffer = b"Hello\x00World";
1164
1165 let result = read_string(buffer, 0, Some(0)).unwrap();
1167 assert_eq!(result, Value::String(String::new()));
1168 }
1169
1170 #[test]
1171 fn test_read_string_max_length_larger_than_buffer() {
1172 let buffer = b"Short";
1173
1174 let result = read_string(buffer, 0, Some(100)).unwrap();
1176 assert_eq!(result, Value::String("Short".to_string()));
1177 }
1178
1179 #[test]
1180 fn test_read_string_utf8_valid() {
1181 let buffer = b"Caf\xc3\xa9\x00"; let result = read_string(buffer, 0, None).unwrap();
1184 assert_eq!(result, Value::String("Café".to_string()));
1185 }
1186
1187 #[test]
1188 fn test_read_string_utf8_invalid() {
1189 let buffer = b"Invalid\xff\xfe\x00"; let result = read_string(buffer, 0, None).unwrap();
1192 assert!(matches!(result, Value::String(_)));
1194 if let Value::String(s) = result {
1195 assert!(s.starts_with("Invalid"));
1196 assert!(s.contains('\u{FFFD}')); }
1198 }
1199
1200 #[test]
1201 fn test_read_string_binary_data() {
1202 let buffer = &[0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x80, 0x90]; let result = read_string(buffer, 0, None).unwrap();
1205 assert_eq!(result, Value::String("Hello".to_string()));
1206 }
1207
1208 #[test]
1209 fn test_read_string_multiple_nulls() {
1210 let buffer = b"First\x00\x00Second\x00";
1211
1212 let result = read_string(buffer, 0, None).unwrap();
1214 assert_eq!(result, Value::String("First".to_string()));
1215
1216 let result = read_string(buffer, 6, None).unwrap();
1218 assert_eq!(result, Value::String(String::new()));
1219 }
1220
1221 #[test]
1222 fn test_read_string_ascii_control_characters() {
1223 let buffer = b"Hello\x09World\x00"; let result = read_string(buffer, 0, None).unwrap();
1226 assert_eq!(result, Value::String("Hello\tWorld".to_string()));
1227 }
1228
1229 #[test]
1230 fn test_read_string_single_character() {
1231 let buffer = b"A\x00";
1232
1233 let result = read_string(buffer, 0, None).unwrap();
1234 assert_eq!(result, Value::String("A".to_string()));
1235 }
1236
1237 #[test]
1238 fn test_read_string_max_length_exact_match() {
1239 let buffer = b"Exact\x00";
1240
1241 let result = read_string(buffer, 0, Some(5)).unwrap();
1243 assert_eq!(result, Value::String("Exact".to_string()));
1244 }
1245
1246 #[test]
1247 fn test_read_string_at_buffer_boundary() {
1248 let buffer = b"Hello";
1249
1250 let result = read_string(buffer, 4, Some(1)).unwrap();
1252 assert_eq!(result, Value::String("o".to_string()));
1253 }
1254
1255 #[test]
1256 fn test_read_string_whitespace_handling() {
1257 let buffer = b" Spaces \x00";
1258
1259 let result = read_string(buffer, 0, None).unwrap();
1261 assert_eq!(result, Value::String(" Spaces ".to_string()));
1262 }
1263
1264 #[test]
1265 fn test_read_string_newline_characters() {
1266 let buffer = b"Line1\nLine2\r\n\x00";
1267
1268 let result = read_string(buffer, 0, None).unwrap();
1269 assert_eq!(result, Value::String("Line1\nLine2\r\n".to_string()));
1270 }
1271
1272 #[test]
1273 fn test_read_string_consistency_with_typed_value() {
1274 let buffer = b"Test\x00String";
1275
1276 let direct_result = read_string(buffer, 0, None).unwrap();
1278
1279 let type_kind = TypeKind::String { max_length: None };
1280 let typed_result = read_typed_value(buffer, 0, &type_kind).unwrap();
1281
1282 assert_eq!(direct_result, typed_result);
1283 assert_eq!(typed_result, Value::String("Test".to_string()));
1284 }
1285
1286 #[test]
1287 fn test_read_string_consistency_with_max_length() {
1288 let buffer = b"LongString\x00";
1289
1290 let direct_result = read_string(buffer, 0, Some(4)).unwrap();
1292
1293 let type_kind = TypeKind::String {
1294 max_length: Some(4),
1295 };
1296 let typed_result = read_typed_value(buffer, 0, &type_kind).unwrap();
1297
1298 assert_eq!(direct_result, typed_result);
1299 assert_eq!(typed_result, Value::String("Long".to_string()));
1300 }
1301
1302 #[test]
1303 fn test_read_string_edge_case_combinations() {
1304 let test_cases = [
1306 (b"" as &[u8], 0, None, true), (b"\x00", 0, None, false), (b"A", 0, Some(0), false), (b"AB", 1, Some(1), false), ];
1311
1312 for (buffer, offset, max_length, should_fail) in test_cases {
1313 let result = read_string(buffer, offset, max_length);
1314
1315 if should_fail {
1316 assert!(
1317 result.is_err(),
1318 "Expected failure for buffer {buffer:?}, offset {offset}, max_length {max_length:?}"
1319 );
1320 } else {
1321 assert!(
1322 result.is_ok(),
1323 "Expected success for buffer {buffer:?}, offset {offset}, max_length {max_length:?}"
1324 );
1325 }
1326 }
1327 }
1328}
1329
1330#[test]
1331fn test_read_typed_value_buffer_overrun() {
1332 let buffer = &[0x12, 0x34];
1333
1334 let long_type = TypeKind::Long {
1336 endian: Endianness::Little,
1337 signed: false,
1338 };
1339 let result = read_typed_value(buffer, 0, &long_type);
1340 assert!(result.is_err());
1341 assert_eq!(
1342 result.unwrap_err(),
1343 TypeReadError::BufferOverrun {
1344 offset: 0,
1345 buffer_len: 2
1346 }
1347 );
1348
1349 let short_type = TypeKind::Short {
1351 endian: Endianness::Little,
1352 signed: false,
1353 };
1354 let result = read_typed_value(buffer, 1, &short_type);
1355 assert!(result.is_err());
1356 assert_eq!(
1357 result.unwrap_err(),
1358 TypeReadError::BufferOverrun {
1359 offset: 1,
1360 buffer_len: 2
1361 }
1362 );
1363}
1364
1365#[test]
1366fn test_read_typed_value_all_supported_types() {
1367 let buffer = &[0x7f, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xbc, 0x9a];
1368
1369 let test_cases = vec![
1371 (TypeKind::Byte, 0, Value::Uint(0x7f)),
1372 (
1373 TypeKind::Short {
1374 endian: Endianness::Little,
1375 signed: false,
1376 },
1377 1,
1378 Value::Uint(0x1234), ),
1380 (
1381 TypeKind::Short {
1382 endian: Endianness::Big,
1383 signed: false,
1384 },
1385 1,
1386 Value::Uint(0x3412), ),
1388 (
1389 TypeKind::Long {
1390 endian: Endianness::Little,
1391 signed: false,
1392 },
1393 1,
1394 Value::Uint(0x5678_1234), ),
1396 (
1397 TypeKind::Long {
1398 endian: Endianness::Big,
1399 signed: false,
1400 },
1401 1,
1402 Value::Uint(0x3412_7856), ),
1404 ];
1405
1406 for (type_kind, offset, expected) in test_cases {
1407 let result = read_typed_value(buffer, offset, &type_kind).unwrap();
1408 assert_eq!(result, expected, "Failed for type: {type_kind:?}");
1409 }
1410}
1411
1412#[test]
1413fn test_read_typed_value_signed_vs_unsigned() {
1414 let buffer = &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
1415
1416 let unsigned_short = TypeKind::Short {
1418 endian: Endianness::Little,
1419 signed: false,
1420 };
1421 let signed_short = TypeKind::Short {
1422 endian: Endianness::Little,
1423 signed: true,
1424 };
1425
1426 let unsigned_result = read_typed_value(buffer, 0, &unsigned_short).unwrap();
1427 let signed_result = read_typed_value(buffer, 0, &signed_short).unwrap();
1428
1429 assert_eq!(unsigned_result, Value::Uint(65535));
1430 assert_eq!(signed_result, Value::Int(-1));
1431
1432 let unsigned_long = TypeKind::Long {
1434 endian: Endianness::Little,
1435 signed: false,
1436 };
1437 let signed_long = TypeKind::Long {
1438 endian: Endianness::Little,
1439 signed: true,
1440 };
1441
1442 let unsigned_result = read_typed_value(buffer, 0, &unsigned_long).unwrap();
1443 let signed_result = read_typed_value(buffer, 0, &signed_long).unwrap();
1444
1445 assert_eq!(unsigned_result, Value::Uint(4_294_967_295));
1446 assert_eq!(signed_result, Value::Int(-1));
1447}
1448
1449#[test]
1450fn test_read_typed_value_consistency_with_direct_calls() {
1451 let buffer = &[0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xde, 0xf0];
1452
1453 let byte_type = TypeKind::Byte;
1455 let direct_byte = read_byte(buffer, 0).unwrap();
1456 let typed_byte = read_typed_value(buffer, 0, &byte_type).unwrap();
1457 assert_eq!(direct_byte, typed_byte);
1458
1459 let short_type = TypeKind::Short {
1460 endian: Endianness::Little,
1461 signed: false,
1462 };
1463 let direct_short = read_short(buffer, 0, Endianness::Little, false).unwrap();
1464 let typed_short = read_typed_value(buffer, 0, &short_type).unwrap();
1465 assert_eq!(direct_short, typed_short);
1466
1467 let long_type = TypeKind::Long {
1468 endian: Endianness::Big,
1469 signed: true,
1470 };
1471 let direct_long = read_long(buffer, 0, Endianness::Big, true).unwrap();
1472 let typed_long = read_typed_value(buffer, 0, &long_type).unwrap();
1473 assert_eq!(direct_long, typed_long);
1474}
1475
1476#[test]
1477fn test_read_typed_value_empty_buffer() {
1478 let buffer = &[];
1479
1480 let types = vec![
1482 TypeKind::Byte,
1483 TypeKind::Short {
1484 endian: Endianness::Little,
1485 signed: false,
1486 },
1487 TypeKind::Long {
1488 endian: Endianness::Little,
1489 signed: false,
1490 },
1491 ];
1492
1493 for type_kind in types {
1494 let result = read_typed_value(buffer, 0, &type_kind);
1495 assert!(result.is_err());
1496 match result.unwrap_err() {
1497 TypeReadError::BufferOverrun { offset, buffer_len } => {
1498 assert_eq!(offset, 0);
1499 assert_eq!(buffer_len, 0);
1500 }
1501 TypeReadError::UnsupportedType { .. } => panic!("Expected BufferOverrun error"),
1502 }
1503 }
1504}