Skip to content

Integer overflow in function IDs #223

Open
@joeltg

Description

@joeltg

After running a program in QuickJS for a long time, eventually it crashes with this error: QuickJSContext had no callback with id -32768.

Image

-32768 is the minimum int16 value. Looking at this line in context.ts, we see that this error is thrown when this.getFunction(fn_id) returns undefined. Function ids are set by incrementing protected fnNextId: number, starting at -32768.

It seems that after 2^16 function callbacks have been set, the next function ID is 2^16 = 32768, which overflows the int16 used to represent them in C, and gets returned back to JavaScript as -32768. The correct behavior is for context.ts to wrap around to -32768 when allocating the next function id in this line.

  newFunction(name: string, fn: VmFunctionImplementation<QuickJSHandle>): QuickJSHandle {
    if (this.fnNextId >= (1 << 15)) {
       this.fnNextId = -(1 << 15)
    }
    const fnId = this.fnNextId++ // (is 0 a valid fnId?)
    this.setFunction(fnId, fn)
    return this.memory.heapValueHandle(this.ffi.QTS_NewFunction(this.ctx.value, fnId, name))
  }

Note that I wasn't creating 2^16 functions simultaneously - just cumulative over history. In fact I wasn't actually creating new functions at all, just awaiting promises, which use newFunction internally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions