Skip to content

Commit 958895d

Browse files
WorkingRobotSerial-ATA
authored andcommitted
ogg_pager: Fix panic on nil packet
Signed-off-by: Asriel Camora <asriel@camora.dev>
1 parent 2727c5c commit 958895d

File tree

1 file changed

+19
-23
lines changed

1 file changed

+19
-23
lines changed

ogg_pager/src/paginate.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ impl PaginateContext {
3030
first_page: true,
3131
fresh_packet: true,
3232
packet_finished_on_page: false,
33-
need_nil_page: false,
3433
},
3534
pos: 0,
3635
idx: 0,
@@ -81,12 +80,6 @@ impl PaginateContext {
8180

8281
// Moving on to a new packet
8382
debug_assert!(self.pos <= self.current_packet_len as u64);
84-
let at_packet_end = self.pos == self.current_packet_len as u64;
85-
if at_packet_end && full_segments_occupied == MAX_WRITTEN_SEGMENT_COUNT {
86-
// See comment on `PaginateContextFlags.need_nil_page`
87-
self.flags.need_nil_page = true;
88-
self.flags.packet_finished_on_page = false;
89-
}
9083

9184
if self.flags.packet_finished_on_page {
9285
header.abgp = self.abgp;
@@ -123,15 +116,6 @@ struct PaginateContextFlags {
123116
first_page: bool,
124117
fresh_packet: bool,
125118
packet_finished_on_page: bool,
126-
// A 'nil' page just means it is zero-length. This is used when our packet is perfectly
127-
// divisible by `255 * MAX_SEGMENT_COUNT`. We need a zero-sized segment to mark the end of our
128-
// packet across page boundaries.
129-
//
130-
// Very rare circumstance, but still possible.
131-
//
132-
// From <https://xiph.org/ogg/doc/framing.html>:
133-
// "Note also that a 'nil' (zero length) packet is not an error; it consists of nothing more than a lacing value of zero in the header."
134-
need_nil_page: bool,
135119
}
136120

137121
/// Create pages from a list of packets
@@ -175,13 +159,6 @@ fn paginate_packet(ctx: &mut PaginateContext, packet: &[u8]) -> Result<()> {
175159
let mut page_content = Vec::with_capacity(MAX_WRITTEN_CONTENT_SIZE);
176160
let mut packet = packet;
177161
loop {
178-
// See comment on `PaginateContextFlags.need_nil_page`
179-
if ctx.flags.need_nil_page {
180-
assert!(packet.is_empty());
181-
ctx.flags.packet_finished_on_page = true;
182-
ctx.flush_page(&mut page_content);
183-
}
184-
185162
if packet.is_empty() {
186163
break;
187164
}
@@ -210,5 +187,24 @@ fn paginate_packet(ctx: &mut PaginateContext, packet: &[u8]) -> Result<()> {
210187
ctx.flush_page(&mut page_content);
211188
}
212189

190+
// After all packet bytes are consumed, check for nil page condition
191+
// If the packet length is a multiple of 255 * MAX_WRITTEN_SEGMENT_COUNT, we need a nil page
192+
193+
// A 'nil' page just means it is zero-length. This is used when our packet is perfectly
194+
// divisible by `255 * MAX_SEGMENT_COUNT`. We need a zero-sized segment to mark the end of our
195+
// packet across page boundaries.
196+
//
197+
// Very rare circumstance, but still possible.
198+
//
199+
// From <https://xiph.org/ogg/doc/framing.html>:
200+
// "Note also that a 'nil' (zero length) packet is not an error; it consists of nothing more than a lacing value of zero in the header."
201+
if ctx.current_packet_len != 0
202+
&& ctx.current_packet_len % (255 * MAX_WRITTEN_SEGMENT_COUNT) == 0
203+
{
204+
ctx.flags.packet_finished_on_page = true;
205+
let mut nil_content = Vec::new();
206+
ctx.flush_page(&mut nil_content);
207+
}
208+
213209
Ok(())
214210
}

0 commit comments

Comments
 (0)