[njs] The maximum depth of nested functions is set to 128.

Alexander Borisov alexander.borisov at nginx.com
Thu Jul 15 17:34:53 UTC 2021


details:   https://hg.nginx.org/njs/rev/424dd99ada9a
branches:  
changeset: 1682:424dd99ada9a
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Thu Jul 15 20:32:44 2021 +0300
description:
The maximum depth of nested functions is set to 128.

diffstat:

 src/njs_generator.c      |  22 +++++++++++++++++-----
 src/njs_generator.h      |   2 ++
 src/test/njs_unit_test.c |  30 ++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 5 deletions(-)

diffs (126 lines):

diff -r 20dec02c7283 -r 424dd99ada9a src/njs_generator.c
--- a/src/njs_generator.c	Thu Jul 15 20:32:43 2021 +0300
+++ b/src/njs_generator.c	Thu Jul 15 20:32:44 2021 +0300
@@ -10,6 +10,9 @@
 #include <njs_main.h>
 
 
+#define NJS_FUNCTION_MAX_DEPTH  128
+
+
 typedef struct njs_generator_patch_s   njs_generator_patch_t;
 
 typedef enum {
@@ -275,7 +278,7 @@ static njs_int_t njs_generate_function_d
     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,
@@ -3043,7 +3046,8 @@ njs_generate_function_expression(njs_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;
     }
@@ -3078,7 +3082,7 @@ njs_generate_function(njs_vm_t *vm, njs_
 
     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;
     }
@@ -3577,7 +3581,8 @@ njs_generate_function_declaration(njs_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;
     }
@@ -3599,7 +3604,7 @@ njs_generate_function_declaration(njs_vm
 
 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;
@@ -3609,6 +3614,13 @@ njs_generate_function_scope(njs_vm_t *vm
 
     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);
diff -r 20dec02c7283 -r 424dd99ada9a src/njs_generator.h
--- a/src/njs_generator.h	Thu Jul 15 20:32:43 2021 +0300
+++ b/src/njs_generator.h	Thu Jul 15 20:32:44 2021 +0300
@@ -35,6 +35,8 @@ struct njs_generator_s {
 
     /* Parsing Function() or eval(). */
     uint8_t                         runtime;           /* 1 bit */
+
+    njs_uint_t                      depth;
 };
 
 
diff -r 20dec02c7283 -r 424dd99ada9a src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Thu Jul 15 20:32:43 2021 +0300
+++ b/src/test/njs_unit_test.c	Thu Jul 15 20:32:44 2021 +0300
@@ -9590,6 +9590,36 @@ static njs_unit_test_t  njs_test[] =
               "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) {"


More information about the nginx-devel mailing list