Skip to content

Commit 08ce036

Browse files
[BugFix] reading (NOT)IF ops
1 parent 1ed5f31 commit 08ce036

File tree

1 file changed

+19
-14
lines changed
  • BitcoinTransactionTool/Backend/Blockchain/Scripts

1 file changed

+19
-14
lines changed

BitcoinTransactionTool/Backend/Blockchain/Scripts/Script.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)