@@ -239,13 +239,14 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
239239 IFOp ifop = new IFOp ( ) ;
240240 List < IOperation > ifOps = new List < IOperation > ( ) ;
241241 offset ++ ;
242- while ( data [ offset ] != ( byte ) OP . EndIf && data [ offset ] != ( byte ) OP . ELSE && offset < endIndex )
242+ // (offset < endIndex) needs to be first to prevent OutOfRange exception
243+ while ( offset < endIndex && data [ offset ] != ( byte ) OP . EndIf && data [ offset ] != ( byte ) OP . ELSE )
243244 {
244245 if ( ! TryRead ( data , ifOps , ref offset , out error ) )
245246 {
246247 return false ;
247248 }
248- if ( offset > endIndex )
249+ if ( offset >= endIndex ) // there must be at least 1 more item remaining that is equal to EndIf
249250 {
250251 error = "Bad format." ;
251252 return false ;
@@ -256,18 +257,19 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
256257 return false ;
257258 }
258259 }
259- if ( data [ offset ] == ( byte ) OP . ELSE )
260+ // (offset < endIndex) needs to be checked again to prevent another OutOfRange exception
261+ if ( offset < endIndex && data [ offset ] == ( byte ) OP . ELSE )
260262 {
261263 List < IOperation > elseOps = new List < IOperation > ( ) ;
262264 offset ++ ;
263- while ( data [ offset ] != ( byte ) OP . EndIf && offset < endIndex )
265+ while ( offset < endIndex && data [ offset ] != ( byte ) OP . EndIf )
264266 {
265267 if ( ! TryRead ( data , elseOps , ref offset , out error ) )
266268 {
267269 return false ;
268270 }
269271 }
270- if ( offset > endIndex )
272+ if ( offset >= endIndex )
271273 {
272274 error = "Bad format." ;
273275 return false ;
@@ -279,8 +281,8 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
279281 }
280282 ifop . elseOps = elseOps . ToArray ( ) ;
281283 }
282-
283- if ( data [ offset ] != ( byte ) OP . EndIf )
284+ // (offset < endIndex) needs to be checked again to prevent another OutOfRange exception
285+ if ( offset >= endIndex || data [ offset ] != ( byte ) OP . EndIf )
284286 {
285287 error = "No OP_ENDIF was found." ; //this may never happen!
286288 return false ;
@@ -295,35 +297,37 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
295297 NotIfOp notifOp = new NotIfOp ( ) ;
296298 List < IOperation > ifOps2 = new List < IOperation > ( ) ;
297299 offset ++ ;
298- while ( data [ offset ] != ( byte ) OP . EndIf && data [ offset ] != ( byte ) OP . ELSE && offset < endIndex )
300+ // (offset < endIndex) needs to be first to prevent OutOfRange exception
301+ while ( offset < endIndex && data [ offset ] != ( byte ) OP . EndIf && data [ offset ] != ( byte ) OP . ELSE )
299302 {
300303 if ( ! TryRead ( data , ifOps2 , ref offset , out error ) )
301304 {
302305 return false ;
303306 }
304- if ( offset > endIndex )
307+ if ( offset >= endIndex ) // there must be at least 1 more item remaining that is equal to EndIf
305308 {
306309 error = "Bad format." ;
307310 return false ;
308311 }
309312 if ( ifOps2 . Count == 0 )
310313 {
311- error = "Empty OP_IF " ;
314+ error = "Empty OP_NotIf " ;
312315 return false ;
313316 }
314317 }
318+ // (offset < endIndex) needs to be first to prevent OutOfRange exception
315319 if ( data [ offset ] == ( byte ) OP . ELSE )
316320 {
317321 List < IOperation > elseOps2 = new List < IOperation > ( ) ;
318322 offset ++ ;
319- while ( data [ offset ] != ( byte ) OP . EndIf && offset < endIndex )
323+ while ( offset < endIndex && data [ offset ] != ( byte ) OP . EndIf )
320324 {
321325 if ( ! TryRead ( data , elseOps2 , ref offset , out error ) )
322326 {
323327 return false ;
324328 }
325329 }
326- if ( offset > endIndex )
330+ if ( offset >= endIndex )
327331 {
328332 error = "Bad format." ;
329333 return false ;
@@ -335,8 +339,8 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
335339 }
336340 notifOp . elseOps = elseOps2 . ToArray ( ) ;
337341 }
338-
339- if ( data [ offset ] != ( byte ) OP . EndIf )
342+ // (offset < endIndex) needs to be checked again to prevent another OutOfRange exception
343+ if ( offset >= endIndex || data [ offset ] != ( byte ) OP . EndIf )
340344 {
341345 error = "No OP_ENDIF was found." ; //this may never happen!
342346 return false ;
@@ -346,6 +350,7 @@ private bool TryRead(byte[] data, List<IOperation> opList, ref int offset, out s
346350
347351 opList . Add ( notifOp ) ;
348352 break ;
353+
349354 case OP . ELSE :
350355 error = "OP_ELSE found without prior OP_IF or OP_NOTIF." ;
351356 return false ;
0 commit comments