#include <njs_main.h>
+#define NJS_FUNCTION_MAX_DEPTH 128
+
+
typedef struct njs_generator_patch_s njs_generator_patch_t;
typedef enum {
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_function_scope(njs_vm_t *vm,
njs_function_lambda_t *lambda, njs_parser_node_t *node,
- const njs_str_t *name);
+ const njs_str_t *name, njs_uint_t depth);
static njs_int_t njs_generate_scope_end(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
static int64_t njs_generate_lambda_variables(njs_vm_t *vm,
return NJS_ERROR;
}
- ret = njs_generate_function_scope(vm, lambda, node, &lex_entry->name);
+ ret = njs_generate_function_scope(vm, lambda, node, &lex_entry->name,
+ generator->depth);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
name = module ? &njs_entry_module : &njs_entry_anonymous;
- ret = njs_generate_function_scope(vm, lambda, node, name);
+ ret = njs_generate_function_scope(vm, lambda, node, name, generator->depth);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
return NJS_ERROR;
}
- ret = njs_generate_function_scope(vm, lambda, node, &lex_entry->name);
+ ret = njs_generate_function_scope(vm, lambda, node, &lex_entry->name,
+ generator->depth);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
static njs_int_t
njs_generate_function_scope(njs_vm_t *vm, njs_function_lambda_t *lambda,
- njs_parser_node_t *node, const njs_str_t *name)
+ njs_parser_node_t *node, const njs_str_t *name, njs_uint_t depth)
{
njs_arr_t *arr;
njs_bool_t module;
njs_memzero(&generator, sizeof(njs_generator_t));
+ if (++depth >= NJS_FUNCTION_MAX_DEPTH) {
+ njs_range_error(vm, "Maximum function nesting depth exceeded");
+ return NJS_ERROR;
+ }
+
+ generator.depth = depth;
+
node = node->right;
code = njs_generate_scope(vm, &generator, node->scope, name);
"fn(1); arr"),
njs_str("1,2,3,4,5,6") },
+ /* Function nesting depth. */
+
+ { njs_str("() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => 1"),
+ njs_str("[object Function]") },
+
+ { njs_str("() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => () => () => () => () =>"
+ "() => () => () => () => () => () => () => 1"),
+ njs_str("RangeError: Maximum function nesting depth exceeded") },
+
/* Recursive factorial. */
{ njs_str("function f(a) {"