Skip to content

Commit 03146eb

Browse files
committed
Validate reserved field must be set to 0
1 parent c0b4ae8 commit 03146eb

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

core/common/src/error/iggy_error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ pub enum IggyError {
407407
ProducerClosed = 4057,
408408
#[error("Invalid offset: {0}")]
409409
InvalidOffset(u64) = 4100,
410+
#[error("Invalid reserved field value: {0}, expected: 0")]
411+
InvalidReservedField(u64) = 4101,
410412
#[error("Consumer group with ID: {0} for topic with ID: {1} was not found.")]
411413
ConsumerGroupIdNotFound(Identifier, Identifier) = 5000,
412414
#[error("Invalid consumer group ID")]

core/common/src/types/message/message_header.rs

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)