Skip to content

Commit 820a006

Browse files
Copilotpolybassa
authored andcommitted
Add adapted tests from PR secdev#4875 for CBOR encoding edge cases
Co-authored-by: polybassa <1676055+polybassa@users.noreply.github.com>
1 parent d54ae8e commit 820a006

File tree

1 file changed

+224
-0
lines changed

1 file changed

+224
-0
lines changed

test/scapy/layers/cbor.uts

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,227 @@ zero_float = cbor2.dumps(0.0)
555555
obj1, _ = CBOR_Codecs.CBOR.dec(zero_int)
556556
obj2, _ = CBOR_Codecs.CBOR.dec(zero_float)
557557
obj1.val == 0 and obj2.val == 0.0
558+
559+
########### Additional Tests Adapted from PR #4875 ###################
560+
# These tests verify specific encoding sizes and edge cases
561+
562+
+ CBOR Encoding Sizes - Unsigned Integers
563+
564+
= uint encoding size 0 (argument in initial byte)
565+
obj = CBOR_UNSIGNED_INTEGER(0x12)
566+
data = bytes(obj)
567+
data == bytes.fromhex('12')
568+
569+
= uint encoding size 1 (1-byte argument follows)
570+
obj = CBOR_UNSIGNED_INTEGER(0x34)
571+
data = bytes(obj)
572+
data == bytes.fromhex('1834')
573+
574+
= uint encoding size 2 (2-byte argument follows)
575+
obj = CBOR_UNSIGNED_INTEGER(0x1234)
576+
data = bytes(obj)
577+
data == bytes.fromhex('191234')
578+
579+
= uint encoding size 4 (4-byte argument follows)
580+
obj = CBOR_UNSIGNED_INTEGER(0x12345678)
581+
data = bytes(obj)
582+
data == bytes.fromhex('1a12345678')
583+
584+
= uint encoding size 8 (8-byte argument follows)
585+
obj = CBOR_UNSIGNED_INTEGER(0x1234567812345678)
586+
data = bytes(obj)
587+
data == bytes.fromhex('1b1234567812345678')
588+
589+
= uint decoding size 0
590+
data = bytes.fromhex('12')
591+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
592+
obj.val == 18 and remainder == b''
593+
594+
= uint decoding size 1
595+
data = bytes.fromhex('1834')
596+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
597+
obj.val == 0x34 and remainder == b''
598+
599+
= uint decoding size 2
600+
data = bytes.fromhex('191234')
601+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
602+
obj.val == 0x1234 and remainder == b''
603+
604+
= uint decoding size 4
605+
data = bytes.fromhex('1a12345678')
606+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
607+
obj.val == 0x12345678 and remainder == b''
608+
609+
= uint decoding size 8
610+
data = bytes.fromhex('1b1234567812345678')
611+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
612+
obj.val == 0x1234567812345678 and remainder == b''
613+
614+
+ CBOR Encoding Sizes - Negative Integers
615+
616+
= nint encoding size 0
617+
obj = CBOR_NEGATIVE_INTEGER(-0x13)
618+
data = bytes(obj)
619+
data == bytes.fromhex('32')
620+
621+
= nint decoding size 0
622+
data = bytes.fromhex('32')
623+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
624+
obj.val == -0x13 and isinstance(obj, CBOR_NEGATIVE_INTEGER) and remainder == b''
625+
626+
= nint decoding size 2
627+
data = bytes.fromhex('391234')
628+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
629+
obj.val == (-0x1234 - 1) and isinstance(obj, CBOR_NEGATIVE_INTEGER) and remainder == b''
630+
631+
+ CBOR Byte String Edge Cases
632+
633+
= bstr encoding with specific content
634+
obj = CBOR_BYTE_STRING(b'hi')
635+
data = bytes(obj)
636+
data == bytes.fromhex('426869')
637+
638+
= bstr decoding with specific content
639+
data = bytes.fromhex('426869')
640+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
641+
obj.val == b'hi' and isinstance(obj, CBOR_BYTE_STRING) and remainder == b''
642+
643+
= bstr longer content (24 bytes)
644+
content = b'longlonglonglonglonglong'
645+
obj = CBOR_BYTE_STRING(content)
646+
data = bytes(obj)
647+
# Should use 1-byte length encoding (0x58 = major type 2, additional info 24)
648+
data[:2] == bytes.fromhex('5818') and data[2:] == content
649+
650+
= bstr decoding longer content
651+
data = bytes.fromhex('58186c6f6e676c6f6e676c6f6e676c6f6e676c6f6e676c6f6e67')
652+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
653+
obj.val == b'longlonglonglonglonglong' and remainder == b''
654+
655+
+ CBOR Text String Edge Cases
656+
657+
= tstr encoding with specific content
658+
obj = CBOR_TEXT_STRING('hi')
659+
data = bytes(obj)
660+
data == bytes.fromhex('626869')
661+
662+
= tstr decoding with specific content
663+
data = bytes.fromhex('626869')
664+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
665+
obj.val == 'hi' and isinstance(obj, CBOR_TEXT_STRING) and remainder == b''
666+
667+
= tstr longer content (24 chars)
668+
content = 'longlonglonglonglonglong'
669+
obj = CBOR_TEXT_STRING(content)
670+
data = bytes(obj)
671+
# Should use 1-byte length encoding (0x78 = major type 3, additional info 24)
672+
data[:2] == bytes.fromhex('7818') and data[2:] == content.encode('utf8')
673+
674+
= tstr decoding longer content
675+
data = bytes.fromhex('78186c6f6e676c6f6e676c6f6e676c6f6e676c6f6e676c6f6e67')
676+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
677+
obj.val == 'longlonglonglonglonglong' and remainder == b''
678+
679+
+ CBOR Array Specific Encodings
680+
681+
= array encoding with mixed integer types
682+
from scapy.cbor.cborcodec import CBORcodec_ARRAY
683+
# Array with positive 10 and negative 20
684+
encoded = CBORcodec_ARRAY.enc([10, -20])
685+
decoded, _ = CBOR_Codecs.CBOR.dec(encoded)
686+
isinstance(decoded, CBOR_ARRAY) and len(decoded.val) == 2
687+
688+
= array decoding specific encoding
689+
data = bytes.fromhex('820A33') # array(2): [10, -20]
690+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
691+
isinstance(obj, CBOR_ARRAY) and len(obj.val) == 2 and remainder == b''
692+
693+
+ CBOR Map Specific Encodings
694+
695+
= map encoding with integer keys
696+
from scapy.cbor.cborcodec import CBORcodec_MAP
697+
encoded = CBORcodec_MAP.enc({10: -20})
698+
decoded, _ = CBOR_Codecs.CBOR.dec(encoded)
699+
isinstance(decoded, CBOR_MAP) and len(decoded.val) == 1
700+
701+
= map decoding specific encoding
702+
data = bytes.fromhex('A10A33') # map(1): {10: -20}
703+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
704+
isinstance(obj, CBOR_MAP) and len(obj.val) == 1 and remainder == b''
705+
706+
+ CBOR Float Specific Encodings
707+
708+
= float64 encoding specific value
709+
obj = CBOR_FLOAT(1.5e20)
710+
data = bytes(obj)
711+
data == bytes.fromhex('FB442043561A882930')
712+
713+
= float64 decoding specific value
714+
data = bytes.fromhex('FB442043561A882930')
715+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
716+
isinstance(obj, CBOR_FLOAT) and obj.val == 1.5e20 and remainder == b''
717+
718+
+ CBOR Multiple Item Decoding
719+
720+
= decode multiple items in sequence
721+
data = bytes.fromhex('010203') # Three unsigned integers: 1, 2, 3
722+
obj1, remainder1 = CBOR_Codecs.CBOR.dec(data)
723+
obj2, remainder2 = CBOR_Codecs.CBOR.dec(remainder1)
724+
obj3, remainder3 = CBOR_Codecs.CBOR.dec(remainder2)
725+
obj1.val == 1 and obj2.val == 2 and obj3.val == 3 and remainder3 == b''
726+
727+
= decode nested array with specific encoding
728+
data = bytes.fromhex('8201820203') # array(2): [1, array(2): [2, 3]]
729+
obj, remainder = CBOR_Codecs.CBOR.dec(data)
730+
isinstance(obj, CBOR_ARRAY) and len(obj.val) == 2 and remainder == b'' and isinstance(obj.val[1], CBOR_ARRAY)
731+
732+
+ CBOR Boundary Value Tests
733+
734+
= encode maximum value that fits in each size
735+
# Maximum for size 0 (0-23)
736+
obj = CBOR_UNSIGNED_INTEGER(23)
737+
bytes(obj) == bytes.fromhex('17')
738+
739+
= encode minimum value needing size 1
740+
obj = CBOR_UNSIGNED_INTEGER(24)
741+
bytes(obj) == bytes.fromhex('1818')
742+
743+
= encode maximum value for size 1
744+
obj = CBOR_UNSIGNED_INTEGER(255)
745+
bytes(obj) == bytes.fromhex('18ff')
746+
747+
= encode minimum value needing size 2
748+
obj = CBOR_UNSIGNED_INTEGER(256)
749+
bytes(obj) == bytes.fromhex('190100')
750+
751+
= negative integer boundary at -24
752+
obj = CBOR_NEGATIVE_INTEGER(-24)
753+
bytes(obj) == bytes.fromhex('37')
754+
755+
= negative integer boundary at -25
756+
obj = CBOR_NEGATIVE_INTEGER(-25)
757+
bytes(obj) == bytes.fromhex('3818')
758+
759+
+ CBOR Empty Container Tests
760+
761+
= encode empty array
762+
from scapy.cbor.cborcodec import CBORcodec_ARRAY
763+
encoded = CBORcodec_ARRAY.enc([])
764+
decoded, _ = CBOR_Codecs.CBOR.dec(encoded)
765+
isinstance(decoded, CBOR_ARRAY) and len(decoded.val) == 0
766+
767+
= encode empty map
768+
from scapy.cbor.cborcodec import CBORcodec_MAP
769+
encoded = CBORcodec_MAP.enc({})
770+
decoded, _ = CBOR_Codecs.CBOR.dec(encoded)
771+
isinstance(decoded, CBOR_MAP) and len(decoded.val) == 0
772+
773+
= encode empty byte string
774+
obj = CBOR_BYTE_STRING(b'')
775+
data = bytes(obj)
776+
data == bytes.fromhex('40')
777+
778+
= encode empty text string
779+
obj = CBOR_TEXT_STRING('')
780+
data = bytes(obj)
781+
data == bytes.fromhex('60')

0 commit comments

Comments
 (0)