[njs] Limiting recursion depth while compiling.
Dmitry Volyntsev
xeioex at nginx.com
Fri Aug 23 16:10:22 UTC 2019
details: https://hg.nginx.org/njs/rev/8057f3ad56c1
branches:
changeset: 1141:8057f3ad56c1
user: Dmitry Volyntsev <xeioex at 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;
}
More information about the nginx-devel
mailing list