Skip to content

Commit 8f76eb3

Browse files
committed
fix #379: Skip if statements and loops in repeat until loop correctly
1 parent 18a3824 commit 8f76eb3

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/engine/virtualmachine_p.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,17 @@ do_repeat_loop_index1 : {
321321
pos = loopStart;
322322
} else {
323323
pos = loopStart;
324-
while (*pos != OP_LOOP_END)
324+
unsigned int loopCounter = 1;
325+
while ((*pos != OP_LOOP_END) || (loopCounter > 0)) {
325326
pos += instruction_arg_count[*pos++];
327+
328+
if ((*pos == OP_IF) || (*pos == OP_FOREVER_LOOP) || (*pos == OP_REPEAT_LOOP) || (*pos == OP_UNTIL_LOOP))
329+
loopCounter++;
330+
else if ((*pos == OP_ENDIF) || (*pos == OP_LOOP_END)) {
331+
assert(loopCounter > 0);
332+
loopCounter--;
333+
}
334+
}
326335
}
327336
FREE_REGS(1);
328337
DISPATCH();

test/virtual_machine/virtual_machine_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,3 +1637,14 @@ TEST(VirtualMachineTest, NoCrashInNestedIfStatementsWithLoopAndIfElse)
16371637
vm.run();
16381638
ASSERT_EQ(vm.registerCount(), 0);
16391639
}
1640+
1641+
TEST(VirtualMachineTest, NoCrashInNestedLoopsInRepeatUntilLoop)
1642+
{
1643+
// Regtest for #379
1644+
static unsigned int bytecode[] = { OP_START, OP_UNTIL_LOOP, OP_NULL, OP_NOT, OP_BEGIN_UNTIL_LOOP, OP_NULL, OP_REPEAT_LOOP, OP_LOOP_END, OP_LOOP_END, OP_HALT };
1645+
1646+
VirtualMachine vm(nullptr, nullptr, nullptr);
1647+
vm.setBytecode(bytecode);
1648+
vm.run();
1649+
ASSERT_EQ(vm.registerCount(), 0);
1650+
}

0 commit comments

Comments
 (0)