@@ -671,6 +671,82 @@ test('Packet.RCODE is preserved through encode/parse round-trip', function() {
671671 }
672672} ) ;
673673
674+ test ( 'Resource encode round-trips unknown type via raw data fallback' , function ( ) {
675+ // C1 (AUDIT-RFC.md): the encoder must write RDLENGTH+RDATA for types it
676+ // doesn't know how to serialize, otherwise the wire format is truncated.
677+ // 0xABCD is intentionally not in Packet.TYPE.
678+ const rdata = Buffer . from ( [ 0xDE , 0xAD , 0xBE , 0xEF , 0x00 , 0x01 ] ) ;
679+ const packet = new Packet ( ) ;
680+ packet . header . qr = 1 ;
681+ packet . answers . push ( {
682+ name : 'unknown.example' ,
683+ type : 0xABCD ,
684+ class : Packet . CLASS . IN ,
685+ ttl : 60 ,
686+ data : rdata ,
687+ } ) ;
688+ const parsed = Packet . parse ( packet . toBuffer ( ) ) ;
689+ assert . equal ( parsed . answers . length , 1 ) ;
690+ assert . equal ( parsed . answers [ 0 ] . type , 0xABCD ) ;
691+ assert . equal ( parsed . answers [ 0 ] . class , Packet . CLASS . IN ) ;
692+ assert . equal ( parsed . answers [ 0 ] . ttl , 60 ) ;
693+ assert . ok ( Buffer . isBuffer ( parsed . answers [ 0 ] . data ) ) ;
694+ assert . deepEqual ( parsed . answers [ 0 ] . data , rdata ) ;
695+ } ) ;
696+
697+ test ( 'Resource encode of unknown type does not corrupt following records' , function ( ) {
698+ // The strongest signal for the C1 fix: without it, the missing RDLENGTH
699+ // would make the parser interpret the next record's bytes as RDATA, and
700+ // the A record below would never appear in `answers`.
701+ const packet = new Packet ( ) ;
702+ packet . header . qr = 1 ;
703+ packet . answers . push ( {
704+ name : 'unknown.example' ,
705+ type : 0xABCD ,
706+ class : Packet . CLASS . IN ,
707+ ttl : 60 ,
708+ data : Buffer . from ( [ 0x01 , 0x02 , 0x03 ] ) ,
709+ } ) ;
710+ packet . answers . push ( {
711+ name : 'after.example' ,
712+ type : Packet . TYPE . A ,
713+ class : Packet . CLASS . IN ,
714+ ttl : 30 ,
715+ address : '203.0.113.9' ,
716+ } ) ;
717+ const parsed = Packet . parse ( packet . toBuffer ( ) ) ;
718+ assert . equal ( parsed . answers . length , 2 ) ;
719+ assert . equal ( parsed . answers [ 0 ] . type , 0xABCD ) ;
720+ assert . equal ( parsed . answers [ 1 ] . type , Packet . TYPE . A ) ;
721+ assert . equal ( parsed . answers [ 1 ] . name , 'after.example' ) ;
722+ assert . equal ( parsed . answers [ 1 ] . address , '203.0.113.9' ) ;
723+ } ) ;
724+
725+ test ( 'Resource encode of unknown type with no data writes empty RDATA' , function ( ) {
726+ // When an unknown-type record has no `data`, encode should still emit a
727+ // valid RDLENGTH=0 block so the packet remains parseable.
728+ const packet = new Packet ( ) ;
729+ packet . header . qr = 1 ;
730+ packet . answers . push ( {
731+ name : 'bare.example' ,
732+ type : 0xABCD ,
733+ class : Packet . CLASS . IN ,
734+ ttl : 0 ,
735+ } ) ;
736+ packet . answers . push ( {
737+ name : 'follow.example' ,
738+ type : Packet . TYPE . A ,
739+ class : Packet . CLASS . IN ,
740+ ttl : 30 ,
741+ address : '198.51.100.1' ,
742+ } ) ;
743+ const parsed = Packet . parse ( packet . toBuffer ( ) ) ;
744+ assert . equal ( parsed . answers . length , 2 ) ;
745+ assert . equal ( parsed . answers [ 0 ] . type , 0xABCD ) ;
746+ assert . equal ( parsed . answers [ 0 ] . data . length , 0 ) ;
747+ assert . equal ( parsed . answers [ 1 ] . address , '198.51.100.1' ) ;
748+ } ) ;
749+
674750test ( 'Packet.parse tolerates multiple questions' , function ( ) {
675751 const request = new Packet ( ) ;
676752 request . header . id = 0x9999 ;
0 commit comments