@@ -49,14 +49,8 @@ impl AttributeWrite for ErrorCode {
49
49
50
50
fn write_into_unchecked ( & self , dest : & mut [ u8 ] ) {
51
51
let len = self . padded_len ( ) ;
52
- let offset = self . write_header_unchecked ( dest) ;
53
- dest[ offset] = 0u8 ;
54
- dest[ offset + 1 ] = 0u8 ;
55
- dest[ offset + 2 ] = ( self . code / 100 ) as u8 ;
56
- dest[ offset + 3 ] = ( self . code % 100 ) as u8 ;
57
- let offset = offset + 4 ;
58
- dest[ offset..offset + self . reason . len ( ) ] . copy_from_slice ( self . reason . as_bytes ( ) ) ;
59
- let offset = offset + self . reason . len ( ) ;
52
+ let mut offset = self . write_header_unchecked ( dest) ;
53
+ offset += self . write_into_data ( & mut dest[ offset..] ) ;
60
54
if len - offset > 0 {
61
55
dest[ offset..len] . fill ( 0 ) ;
62
56
}
@@ -247,6 +241,16 @@ impl ErrorCode {
247
241
_ => "Unknown" ,
248
242
}
249
243
}
244
+
245
+ fn write_into_data ( & self , dest : & mut [ u8 ] ) -> usize {
246
+ dest[ 0 ] = 0u8 ;
247
+ dest[ 1 ] = 0u8 ;
248
+ dest[ 2 ] = ( self . code / 100 ) as u8 ;
249
+ dest[ 3 ] = ( self . code % 100 ) as u8 ;
250
+ let bytes = self . reason . as_bytes ( ) ;
251
+ dest[ 4 ..4 + bytes. len ( ) ] . copy_from_slice ( bytes) ;
252
+ 4 + bytes. len ( )
253
+ }
250
254
}
251
255
252
256
impl std:: fmt:: Display for ErrorCode {
@@ -273,23 +277,15 @@ impl Attribute for UnknownAttributes {
273
277
}
274
278
impl AttributeWrite for UnknownAttributes {
275
279
fn to_raw ( & self ) -> RawAttribute {
276
- let mut data = Vec :: with_capacity ( self . length ( ) as usize ) ;
277
- for attr in & self . attributes {
278
- let mut encoded = [ 0 ; 2 ] ;
279
- BigEndian :: write_u16 ( & mut encoded, ( * attr) . into ( ) ) ;
280
- data. extend ( encoded) ;
281
- }
280
+ let mut data = vec ! [ 0 ; self . length( ) as usize ] ;
281
+ self . write_into_data ( & mut data) ;
282
282
RawAttribute :: new_owned ( UnknownAttributes :: TYPE , data. into_boxed_slice ( ) )
283
283
}
284
284
285
285
fn write_into_unchecked ( & self , dest : & mut [ u8 ] ) {
286
286
let len = self . padded_len ( ) ;
287
287
let mut offset = self . write_header_unchecked ( dest) ;
288
- for attr in & self . attributes {
289
- let mut encoded = [ 0 ; 2 ] ;
290
- BigEndian :: write_u16 ( & mut encoded, ( * attr) . into ( ) ) ;
291
- offset += 2 ;
292
- }
288
+ offset += self . write_into_data ( & mut dest[ offset..] ) ;
293
289
if len - offset > 0 {
294
290
dest[ offset..len] . fill ( 0 ) ;
295
291
}
@@ -360,6 +356,15 @@ impl UnknownAttributes {
360
356
pub fn has_attribute ( & self , attr : AttributeType ) -> bool {
361
357
self . attributes . iter ( ) . any ( |& a| a == attr)
362
358
}
359
+
360
+ fn write_into_data ( & self , dest : & mut [ u8 ] ) -> usize {
361
+ let mut offset = 0 ;
362
+ for attr in & self . attributes {
363
+ BigEndian :: write_u16 ( & mut dest[ offset..offset + 2 ] , ( * attr) . into ( ) ) ;
364
+ offset += 2 ;
365
+ }
366
+ offset
367
+ }
363
368
}
364
369
365
370
impl std:: fmt:: Display for UnknownAttributes {
@@ -392,6 +397,13 @@ mod tests {
392
397
let err2 = ErrorCode :: try_from ( & raw ) . unwrap ( ) ;
393
398
assert_eq ! ( err2. code( ) , code) ;
394
399
assert_eq ! ( err2. reason( ) , reason) ;
400
+
401
+ let mut dest = vec ! [ 0 ; raw. padded_len( ) ] ;
402
+ err. write_into ( & mut dest) . unwrap ( ) ;
403
+ let raw = RawAttribute :: from_bytes ( & dest) . unwrap ( ) ;
404
+ let err2 = ErrorCode :: try_from ( & raw ) . unwrap ( ) ;
405
+ assert_eq ! ( err2. code( ) , code) ;
406
+ assert_eq ! ( err2. reason( ) , reason) ;
395
407
}
396
408
}
397
409
@@ -527,11 +539,19 @@ mod tests {
527
539
} )
528
540
) ) ;
529
541
// provide incorrectly typed data
530
- let mut data: Vec < _ > = raw. into ( ) ;
542
+ let mut data: Vec < _ > = raw. clone ( ) . into ( ) ;
531
543
BigEndian :: write_u16 ( & mut data[ 0 ..2 ] , 0 ) ;
532
544
assert ! ( matches!(
533
545
UnknownAttributes :: try_from( & RawAttribute :: from_bytes( data. as_ref( ) ) . unwrap( ) ) ,
534
546
Err ( StunParseError :: WrongAttributeImplementation )
535
547
) ) ;
548
+
549
+ let mut dest = vec ! [ 0 ; raw. padded_len( ) ] ;
550
+ unknown. write_into ( & mut dest) . unwrap ( ) ;
551
+ tracing:: error!( "{dest:?}" ) ;
552
+ let raw = RawAttribute :: from_bytes ( & dest) . unwrap ( ) ;
553
+ let unknown2 = UnknownAttributes :: try_from ( & raw ) . unwrap ( ) ;
554
+ assert ! ( unknown2. has_attribute( Realm :: TYPE ) ) ;
555
+ assert ! ( unknown2. has_attribute( AlternateServer :: TYPE ) ) ;
536
556
}
537
557
}
0 commit comments