details: https://hg.nginx.org/njs/rev/8057f3ad56c1 branches: changeset: 1141:8057f3ad56c1 user: Dmitry Volyntsev <xei...@nginx.com> date: Fri Aug 23 15:13:45 2019 +0300 description: Limiting recursion depth while compiling.
This closes #146 issue on Github. diffstat: src/njs_generator.c | 20 +++++++++++++++++++- src/njs_generator.h | 2 ++ src/njs_parser.c | 10 ++++++++++ src/njs_parser.h | 13 +++++++++++++ src/njs_parser_expression.c | 14 ++++++++++++++ 5 files changed, 58 insertions(+), 1 deletions(-) diffs (148 lines): diff -r 6923d5ac84bc -r 8057f3ad56c1 src/njs_generator.c --- a/src/njs_generator.c Thu Aug 22 18:27:34 2019 +0300 +++ b/src/njs_generator.c Fri Aug 23 15:13:45 2019 +0300 @@ -257,7 +257,7 @@ static const njs_str_t undef_label = { static njs_int_t -njs_generator(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) +njs_generate(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { if (node == NULL) { return NJS_OK; @@ -508,6 +508,24 @@ njs_generator(njs_vm_t *vm, njs_generato } +njs_inline njs_int_t +njs_generator(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) +{ + njs_int_t ret; + + if (njs_slow_path(generator->count++ > 1024)) { + njs_range_error(vm, "Maximum call stack size exceeded"); + return NJS_ERROR; + } + + ret = njs_generate(vm, generator, node); + + generator->count--; + + return ret; +} + + static u_char * njs_generate_reserve(njs_vm_t *vm, njs_generator_t *generator, size_t size) { diff -r 6923d5ac84bc -r 8057f3ad56c1 src/njs_generator.h --- a/src/njs_generator.h Thu Aug 22 18:27:34 2019 +0300 +++ b/src/njs_generator.h Fri Aug 23 15:13:45 2019 +0300 @@ -24,6 +24,8 @@ struct njs_generator_s { /* Parsing Function() or eval(). */ uint8_t runtime; /* 1 bit */ + + njs_uint_t count; }; diff -r 6923d5ac84bc -r 8057f3ad56c1 src/njs_parser.c --- a/src/njs_parser.c Thu Aug 22 18:27:34 2019 +0300 +++ b/src/njs_parser.c Fri Aug 23 15:13:45 2019 +0300 @@ -127,6 +127,11 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p node->token = NJS_TOKEN_END; + if (njs_slow_path(parser->count != 0)) { + njs_internal_error(vm, "parser->count != 0"); + return NJS_ERROR; + } + return NJS_OK; } @@ -249,7 +254,12 @@ njs_parser_statement_chain(njs_vm_t *vm, last = *child; + njs_parser_enter(vm, parser); + token = njs_parser_statement(vm, parser, token); + + njs_parser_leave(parser); + if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return njs_parser_unexpected_token(vm, parser, token); } diff -r 6923d5ac84bc -r 8057f3ad56c1 src/njs_parser.h --- a/src/njs_parser.h Thu Aug 22 18:27:34 2019 +0300 +++ b/src/njs_parser.h Fri Aug 23 15:13:45 2019 +0300 @@ -73,6 +73,7 @@ struct njs_parser_s { njs_lexer_t *lexer; njs_parser_node_t *node; njs_parser_scope_t *scope; + njs_uint_t count; }; @@ -113,6 +114,18 @@ void njs_parser_node_error(njs_vm_t *vm, njs_value_type_t type, const char *fmt, ...); +#define njs_parser_enter(vm, parser) \ + do { \ + if (njs_slow_path((parser)->count++ > 1024)) { \ + njs_range_error(vm, "Maximum call stack size exceeded"); \ + return NJS_TOKEN_ERROR; \ + } \ + } while (0) + + +#define njs_parser_leave(parser) ((parser)->count--) + + #define njs_parser_is_lvalue(node) \ ((node)->token == NJS_TOKEN_NAME || (node)->token == NJS_TOKEN_PROPERTY) diff -r 6923d5ac84bc -r 8057f3ad56c1 src/njs_parser_expression.c --- a/src/njs_parser_expression.c Thu Aug 22 18:27:34 2019 +0300 +++ b/src/njs_parser_expression.c Fri Aug 23 15:13:45 2019 +0300 @@ -744,7 +744,11 @@ njs_parser_call_expression(njs_vm_t *vm, token = njs_parser_new_expression(vm, parser, token); } else { + njs_parser_enter(vm, parser); + token = njs_parser_terminal(vm, parser, token); + + njs_parser_leave(parser); } if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { @@ -761,7 +765,12 @@ njs_parser_call_expression(njs_vm_t *vm, return token; } + njs_parser_enter(vm, parser); + token = njs_parser_call(vm, parser, token, 0); + + njs_parser_leave(parser); + if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -863,7 +872,12 @@ njs_parser_new_expression(njs_vm_t *vm, token = njs_parser_new_expression(vm, parser, token); } else { + njs_parser_enter(vm, parser); + token = njs_parser_terminal(vm, parser, token); + + njs_parser_leave(parser); + if (njs_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel