Skip to content

Commit 57540c1

Browse files
committed
overflow check for fragmentation in rtps writer
1 parent 7ae5548 commit 57540c1

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

src/rtps/writer.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -535,12 +535,36 @@ impl Writer {
535535
// --------------------------------------------------------------
536536
// --------------------------------------------------------------
537537
fn num_frags_and_frag_size(&self, payload_size: usize) -> (u32, u16) {
538-
let fragment_size = self.data_max_size_serialized as u32; // TODO: overflow check
539-
let data_size = payload_size as u32; // TODO: overflow check
540-
// Formula from RTPS spec v2.5 Section "8.3.8.3.5 Logical Interpretation"
541-
let num_frags = (data_size / fragment_size) + u32::from(data_size % fragment_size != 0); // rounding up
542-
debug!("Fragmenting {data_size} to {num_frags} x {fragment_size}");
543-
// TODO: Check fragment_size overflow
538+
let calc_frag_size = |max_size| {
539+
u16::try_from(max_size).unwrap_or_else(|_| {
540+
warn!(
541+
"Integer overflow when converting writer {:x?} fragmentation size ({}) to u16, using \
542+
u16::MAX",
543+
self.entity_id(),
544+
self.data_max_size_serialized
545+
);
546+
u16::MAX
547+
}) as usize
548+
};
549+
let mut fragment_size = calc_frag_size(self.data_max_size_serialized);
550+
551+
// RTPS spec v2.5 Section "8.3.8.3.5 Logical Interpretation"
552+
let calc_num_frags = |frag_size| u32::try_from(payload_size.div_ceil(frag_size));
553+
let mut num_frags = calc_num_frags(fragment_size);
554+
555+
while num_frags.is_err() {
556+
let overflow_frag_count = payload_size.div_ceil(fragment_size);
557+
let new_fragment_size = calc_frag_size(fragment_size * 2);
558+
warn!(
559+
"Integer overflow when converting writer {:x?} fragmentation count \
560+
({overflow_frag_count}) to u32, increasing fragmentation count to {new_fragment_size}",
561+
self.entity_id()
562+
);
563+
num_frags = calc_num_frags(new_fragment_size);
564+
fragment_size = new_fragment_size;
565+
}
566+
let num_frags = num_frags.unwrap();
567+
debug!("Fragmenting {payload_size} to {num_frags} x {fragment_size}");
544568
(num_frags, fragment_size as u16)
545569
}
546570

0 commit comments

Comments
 (0)