@@ -148,6 +148,8 @@ ebml_master_elements! {
148
148
}
149
149
150
150
struct ElementReaderContext {
151
+ /// Previous master element
152
+ previous_master : Option < MasterElement > ,
151
153
/// Current master element
152
154
current_master : Option < MasterElement > ,
153
155
/// Remaining length of the master element
@@ -156,17 +158,24 @@ struct ElementReaderContext {
156
158
max_id_length : u8 ,
157
159
/// Maximum size in octets of all element data sizes
158
160
max_size_length : u8 ,
161
+ /// Whether the reader is locked to the current master element
162
+ ///
163
+ /// This is set with [`ElementReader::lock`], and is used to prevent
164
+ /// the reader from reading past the end of the current master element.
165
+ locked : bool ,
159
166
}
160
167
161
168
impl Default for ElementReaderContext {
162
169
fn default ( ) -> Self {
163
170
Self {
171
+ previous_master : None ,
164
172
current_master : None ,
165
173
master_length : 0 ,
166
174
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxidlength-element
167
175
max_id_length : 4 ,
168
176
// https://www.rfc-editor.org/rfc/rfc8794.html#name-ebmlmaxsizelength-element
169
177
max_size_length : 8 ,
178
+ locked : false ,
170
179
}
171
180
}
172
181
}
@@ -213,6 +222,7 @@ where
213
222
return Ok ( ElementReaderYield :: Unknown ( header) ) ;
214
223
} ;
215
224
225
+ self . ctx . previous_master = self . ctx . current_master ;
216
226
self . ctx . current_master = Some ( * master) ;
217
227
self . ctx . master_length = header. size . value ( ) ;
218
228
Ok ( ElementReaderYield :: Master ( (
@@ -221,12 +231,34 @@ where
221
231
) ) )
222
232
}
223
233
234
+ /// Lock the reader to the current master element
235
+ pub ( crate ) fn lock ( & mut self ) {
236
+ self . ctx . locked = true ;
237
+ }
238
+
239
+ pub ( crate ) fn unlock ( & mut self ) {
240
+ self . ctx . locked = false ;
241
+ }
242
+
243
+ pub ( crate ) fn goto_previous_master ( & mut self ) -> Result < ( ) > {
244
+ if let Some ( previous_master) = self . ctx . previous_master {
245
+ self . ctx . current_master = Some ( previous_master) ;
246
+ Ok ( ( ) )
247
+ } else {
248
+ decode_err ! ( @BAIL Ebml , "Expected a parent element to be available" )
249
+ }
250
+ }
251
+
224
252
pub ( crate ) fn next ( & mut self ) -> Result < ElementReaderYield > {
225
253
let Some ( current_master) = self . ctx . current_master else {
226
254
return self . next_master ( ) ;
227
255
} ;
228
256
229
257
if self . ctx . master_length == 0 {
258
+ if self . ctx . locked {
259
+ return Ok ( ElementReaderYield :: Eof ) ;
260
+ }
261
+
230
262
return self . next_master ( ) ;
231
263
}
232
264
@@ -244,6 +276,21 @@ where
244
276
return Ok ( ElementReaderYield :: Unknown ( header) ) ;
245
277
} ;
246
278
279
+ if child. data_type == ElementDataType :: Master {
280
+ self . ctx . current_master = Some (
281
+ * MASTER_ELEMENTS
282
+ . get ( & header. id )
283
+ . expect ( "Nested master elements should be defined at this level." ) ,
284
+ ) ;
285
+ self . ctx . master_length = header. size . value ( ) ;
286
+
287
+ // We encountered a nested master element
288
+ return Ok ( ElementReaderYield :: Master ( (
289
+ child. ident ,
290
+ header. size . value ( ) ,
291
+ ) ) ) ;
292
+ }
293
+
247
294
Ok ( ElementReaderYield :: Child ( ( * child, header. size . value ( ) ) ) )
248
295
}
249
296
0 commit comments