Jelajahi Sumber

Fix packet buffer panic caused by large payload (#332)

When packet buffer's payload buffer does not have enough contiguous
window left, the ring buffer roll over uses an incorrect size
causing the ring buffer pointer not resetting to the head.

When the payload enqueued is larger than 1/2 of the payload ring
buffer, this bug will cause the slice returned by
`PacketBuffer::enqueue` to not match the requested size, and
trigger `debug_assert` in debug profile or size mismatch panic in
`copy_from_slice` when compiled in release profile.
Gary Guo 5 tahun lalu
induk
melakukan
0d82444556
1 mengubah file dengan 10 tambahan dan 2 penghapusan
  1. 10 2
      src/storage/packet_buffer.rs

+ 10 - 2
src/storage/packet_buffer.rs

@@ -96,8 +96,8 @@ impl<'a, 'b, H> PacketBuffer<'a, 'b, H> {
             } else {
             } else {
                 // Add padding to the end of the ring buffer so that the
                 // Add padding to the end of the ring buffer so that the
                 // contiguous window is at the beginning of the ring buffer.
                 // contiguous window is at the beginning of the ring buffer.
-                *self.metadata_ring.enqueue_one()? = PacketMetadata::padding(size);
-                self.payload_ring.enqueue_many(size);
+                *self.metadata_ring.enqueue_one()? = PacketMetadata::padding(contig_window);
+                self.payload_ring.enqueue_many(contig_window);
             }
             }
         }
         }
 
 
@@ -224,6 +224,14 @@ mod test {
         assert_eq!(buffer.metadata_ring.len(), 0);
         assert_eq!(buffer.metadata_ring.len(), 0);
     }
     }
 
 
+    #[test]
+    fn test_padding_with_large_payload() {
+        let mut buffer = buffer();
+        assert!(buffer.enqueue(12, ()).is_ok());
+        assert!(buffer.dequeue().is_ok());
+        buffer.enqueue(12, ()).unwrap().copy_from_slice(b"abcdefghijkl");
+    }
+
     #[test]
     #[test]
     fn test_dequeue_with() {
     fn test_dequeue_with() {
         let mut buffer = buffer();
         let mut buffer = buffer();