Skip to content

Commit

Permalink
py/emitbc: Add check for bytecode jump offset overflow.
Browse files Browse the repository at this point in the history
Signed-off-by: Damien George <[email protected]>
  • Loading branch information
dpgeorge committed Mar 28, 2022
1 parent 538c3c0 commit acd2c5c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
9 changes: 9 additions & 0 deletions py/emitbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct _emit_t {
size_t bytecode_offset;
size_t bytecode_size;
byte *code_base; // stores both byte code and code info
bool overflow;

size_t n_info;
size_t n_cell;
Expand Down Expand Up @@ -260,6 +261,9 @@ STATIC void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1,
if (is_signed) {
bytecode_offset += 0x4000;
}
if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) {
emit->overflow = true;
}
c[1] = 0x80 | (bytecode_offset & 0x7f);
c[2] = bytecode_offset >> 7;
}
Expand All @@ -274,6 +278,7 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
emit->last_source_line = 1;
emit->bytecode_offset = 0;
emit->code_info_offset = 0;
emit->overflow = false;

// Write local state size, exception stack size, scope flags and number of arguments
{
Expand Down Expand Up @@ -373,6 +378,10 @@ bool mp_emit_bc_end_pass(emit_t *emit) {
return false;
}

if (emit->overflow) {
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("bytecode overflow"));
}

// Bytecode is finalised, assign it to the raw code object.
mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
#if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS
Expand Down
7 changes: 7 additions & 0 deletions tests/stress/bytecode_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@
print(x)
"""
)

# Test overflow of jump offset.
for n in (430, 431, 432, 433):
try:
exec("cond = 0\nif cond:\n" + body * n + "else:\n print('cond false')\n")
except RuntimeError:
print("RuntimeError")
4 changes: 4 additions & 0 deletions tests/stress/bytecode_limit.py.exp
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
[123]
cond false
cond false
RuntimeError
RuntimeError

0 comments on commit acd2c5c

Please sign in to comment.