skx / evalfilter

A bytecode-based virtual machine to implement scripting/filtering support in your golang project.
GNU General Public License v2.0
117 stars 12 forks source link

BUG: Control flow at the end of a script #156

Closed skx closed 4 years ago

skx commented 4 years ago

Two examples expose a bug:

$ cat bug1.in 
    foreach value in { "Name": "Steve", "Location": "Finland" } {
      printf("Value %s \n", value );
    }

And:

$ cat bug2.in 
if ( false ) {
    printf("OK\n");
}

The issue here is obvious when running the code (note you must run the second with the optimizer disabled):

$ ./evalfilter run bug1.in 
Value Finland 
Value Steve 
Failed to run script: instruction pointer is out of bounds
$ ./evalfilter run -no-optimizer bug2.in 
Failed to run script: instruction pointer is out of bounds

The issue here is exactly the same as that resolved and described in :

We generate a JUMP instruction which jumps "after" the block. The problem is nothing comes next. In the past such a thing would have been masked by the (mandatory) return instruction.

Now we have to deal with it - we can generalize the previous solution, changing OpTrue + OpPop into OpPlaceholder which will be like OpNop, but not optimized away.