Closed 0xbigshaq closed 6 months ago
Hi @0xbigshaq,
Thank you for the report and a good catch.
The root-cause here is in the step 2. We set a retval value too early. Unfortunately in NJS, the retval value will be visible outside the native JS function even if the exception was thrown.
I found similar places in
Array.prototype.toSpliced()
Array.prototype.toReversed()
Array.prototype.toSorted()
The incorrect pattern to look for is when the retval is set before the code that can throw an exception. The correct pattern is when retval is set right before the return from the function.
74854b6edaa8a76fdc96395cdc7fbdfcd01425b6
0.8.5
To reproduce, run:
output:
Analysis
In
Array.prototype.toSpliced
/njs_array_prototype_to_spliced
, the code performs the following:retval
by callingnjs_set_array()
NJS_ERROR
https://github.com/nginx/njs/blob/74854b6edaa8a76fdc96395cdc7fbdfcd01425b6/src/njs_array.c#L1451-L1468
It looks like the problem is in the implementation of step 3+4(?) We assign to
retval
a heap chunk with un-initialized data, then, thethrow new Error()
exception(triggered by our getter) makes the function to bail out in the middle of thetoSpliced
operation, before the memory pointed byretval
is fully initialized.