@@ -94,11 +94,17 @@ impl IggyMessageHeader {
9494 . try_into ( )
9595 . map_err ( |_| IggyError :: InvalidNumberEncoding ) ?,
9696 ) ,
97- reserved : u64:: from_le_bytes (
98- bytes[ IGGY_MESSAGE_RESERVED_OFFSET_RANGE ]
99- . try_into ( )
100- . map_err ( |_| IggyError :: InvalidNumberEncoding ) ?,
101- ) ,
97+ reserved : {
98+ let reserved = u64:: from_le_bytes (
99+ bytes[ IGGY_MESSAGE_RESERVED_OFFSET_RANGE ]
100+ . try_into ( )
101+ . map_err ( |_| IggyError :: InvalidNumberEncoding ) ?,
102+ ) ;
103+ if reserved != 0 {
104+ return Err ( IggyError :: InvalidReservedField ( reserved) ) ;
105+ }
106+ reserved
107+ } ,
102108 } )
103109 }
104110}
@@ -164,12 +170,16 @@ impl BytesSerializable for IggyMessageHeader {
164170 . map_err ( |_| IggyError :: InvalidNumberEncoding ) ?,
165171 ) ;
166172
167- let _reserved = u64:: from_le_bytes (
173+ let reserved = u64:: from_le_bytes (
168174 bytes[ IGGY_MESSAGE_RESERVED_OFFSET_RANGE ]
169175 . try_into ( )
170176 . map_err ( |_| IggyError :: InvalidNumberEncoding ) ?,
171177 ) ;
172178
179+ if reserved != 0 {
180+ return Err ( IggyError :: InvalidReservedField ( reserved) ) ;
181+ }
182+
173183 Ok ( IggyMessageHeader {
174184 checksum,
175185 id,
@@ -178,7 +188,7 @@ impl BytesSerializable for IggyMessageHeader {
178188 origin_timestamp,
179189 user_headers_length : headers_length,
180190 payload_length,
181- reserved : _reserved ,
191+ reserved,
182192 } )
183193 }
184194}
@@ -245,4 +255,54 @@ mod tests {
245255 assert_eq ! ( header. user_headers_length, deserialized. user_headers_length) ;
246256 assert_eq ! ( header. payload_length, deserialized. payload_length) ;
247257 }
258+
259+ #[ test]
260+ fn should_reject_non_zero_reserved_field_from_bytes ( ) {
261+ let header = IggyMessageHeader {
262+ checksum : 123456789 ,
263+ id : 987654321 ,
264+ offset : 100 ,
265+ timestamp : 1000000 ,
266+ origin_timestamp : 999999 ,
267+ user_headers_length : 50 ,
268+ payload_length : 200 ,
269+ reserved : 0 ,
270+ } ;
271+
272+ let mut bytes = header. to_bytes ( ) . to_vec ( ) ;
273+ let non_zero_reserved: u64 = 42 ;
274+ bytes[ IGGY_MESSAGE_RESERVED_OFFSET_RANGE ] . copy_from_slice ( & non_zero_reserved. to_le_bytes ( ) ) ;
275+
276+ let result = IggyMessageHeader :: from_bytes ( Bytes :: from ( bytes) ) ;
277+ assert ! ( result. is_err( ) ) ;
278+ assert_eq ! (
279+ result. unwrap_err( ) ,
280+ IggyError :: InvalidReservedField ( non_zero_reserved)
281+ ) ;
282+ }
283+
284+ #[ test]
285+ fn should_reject_non_zero_reserved_field_from_raw_bytes ( ) {
286+ let header = IggyMessageHeader {
287+ checksum : 111 ,
288+ id : 222 ,
289+ offset : 333 ,
290+ timestamp : 444 ,
291+ origin_timestamp : 555 ,
292+ user_headers_length : 66 ,
293+ payload_length : 77 ,
294+ reserved : 0 ,
295+ } ;
296+
297+ let mut bytes = header. to_bytes ( ) . to_vec ( ) ;
298+ let non_zero_reserved: u64 = 123456789 ;
299+ bytes[ IGGY_MESSAGE_RESERVED_OFFSET_RANGE ] . copy_from_slice ( & non_zero_reserved. to_le_bytes ( ) ) ;
300+
301+ let result = IggyMessageHeader :: from_raw_bytes ( & bytes) ;
302+ assert ! ( result. is_err( ) ) ;
303+ assert_eq ! (
304+ result. unwrap_err( ) ,
305+ IggyError :: InvalidReservedField ( non_zero_reserved)
306+ ) ;
307+ }
248308}
0 commit comments