quickjs-emscripten icon indicating copy to clipboard operation
quickjs-emscripten copied to clipboard

Integer overflow in function IDs

Open joeltg opened this issue 8 months ago • 2 comments
trafficstars

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.

joeltg avatar Mar 20 '25 17:03 joeltg