Skip to content

Commit 94ef7d3

Browse files
committed
[[ LCB Machine ]] Fix bug in validation code for 'return' which caused incorrect register count to be calculated.
1 parent 15d1e5a commit 94ef7d3

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

libscript/src/script-module.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,48 +262,85 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
262262
switch(t_operation)
263263
{
264264
case kMCScriptBytecodeOpJump:
265-
// check arity == 1
265+
// jump <offset>
266+
if (t_arity != 1)
267+
return false;
268+
266269
// check resolved address is within handler
267270
break;
268271
case kMCScriptBytecodeOpJumpIfFalse:
269272
case kMCScriptBytecodeOpJumpIfTrue:
270-
// check arity == 2
273+
// jumpiftrue <register>, <offset>
274+
// jumpiffalse <register>, <offset>
275+
if (t_arity != 2)
276+
return false;
277+
271278
// check resolved address is within handler
272279
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
273280
break;
274281
case kMCScriptBytecodeOpAssignConstant:
275-
// check arity == 2
282+
// assignconst <dst>, <index>
283+
if (t_arity != 2)
284+
return false;
285+
276286
// check index argument is within value pool range
277287
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
278288
break;
279289
case kMCScriptBytecodeOpAssign:
280-
// check arity == 2
290+
// assign <dst>, <src>
291+
if (t_arity != 2)
292+
return false;
293+
281294
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
282295
t_temporary_count = MCMax(t_temporary_count, t_operands[1] + 1);
283296
break;
284297
case kMCScriptBytecodeOpReturn:
285-
// check arity == 1
286-
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
298+
// return
299+
// return <value>
300+
if (t_arity != 0 && t_arity != 1)
301+
return false;
302+
303+
if (t_arity == 1)
304+
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
287305
break;
288306
case kMCScriptBytecodeOpInvoke:
307+
// invoke <index>, <result>, [ <arg_1>, ..., <arg_n> ]
308+
if (t_arity < 2)
309+
return false;
310+
289311
// check index operand is within definition range
290312
// check definition[index] is handler or definition group
291313
// check signature of defintion[index] conforms with invoke arity
292314
for(uindex_t i = 1; i < t_arity; i++)
293315
t_temporary_count = MCMax(t_temporary_count, t_operands[i] + 1);
294316
break;
295-
case kMCScriptBytecodeOpAssignList:
296317
case kMCScriptBytecodeOpInvokeIndirect:
318+
// invoke *<src>, <result>, [ <arg_1>, ..., <arg_n> ]
319+
if (t_arity < 2)
320+
return false;
321+
297322
for(uindex_t i = 0; i < t_arity; i++)
298323
t_temporary_count = MCMax(t_temporary_count, t_operands[i] + 1);
299324
break;
300325
case kMCScriptBytecodeOpFetch:
301326
case kMCScriptBytecodeOpStore:
302-
// check arity is 2
327+
// fetch <dst>, <index>
328+
// store <src>, <index>
329+
if (t_arity != 2)
330+
return false;
331+
303332
// check definition[index] is variable or handler
304333
// check level is appropriate.
305334
t_temporary_count = MCMax(t_temporary_count, t_operands[0] + 1);
306335
break;
336+
case kMCScriptBytecodeOpAssignList:
337+
// assignlist <dst>, [ <elem_1>, ..., <elem_n> ]
338+
if (t_arity < 1)
339+
return false;
340+
341+
for(uindex_t i = 0; i < t_arity; i++)
342+
t_temporary_count = MCMax(t_temporary_count, t_operands[i] + 1);
343+
break;
307344
}
308345
}
309346

0 commit comments

Comments
 (0)