NJS_FRAME_SIZE did not take into account the variable length of
closures array. This can result in overlapping addresses for
native_frame->arguments and frame->closures[n],
closures = lambda->nesting + lambda->block_closures;
- size = NJS_FRAME_SIZE
+ size = njs_frame_size(closures)
+ (function->args_offset + max_args) * sizeof(njs_value_t)
- + lambda->local_size
- + closures * sizeof(njs_closure_t *);
+ + lambda->local_size;
native_frame = njs_function_frame_alloc(vm, size);
if (nxt_slow_path(native_frame == NULL)) {
/* Function arguments. */
- value = (njs_value_t *) ((u_char *) native_frame + NJS_FRAME_SIZE);
+ value = (njs_value_t *) ((u_char *) native_frame +
+ njs_frame_size(closures));
native_frame->arguments = value;
bound = function->bound;
nxt_align_size(sizeof(njs_native_frame_t), sizeof(njs_value_t))
/* The frame size must be aligned to njs_value_t. */
-#define NJS_FRAME_SIZE \
- nxt_align_size(sizeof(njs_frame_t), sizeof(njs_value_t))
+#define njs_frame_size(closures) \
+ nxt_align_size(sizeof(njs_frame_t) + closures * sizeof(njs_closure_t *), \
+ sizeof(njs_value_t))
/* The retval field is not used in the global frame. */
#define NJS_GLOBAL_FRAME_SIZE \