Repository: nginx/njs (c)

Issue:
heap-use-after-free src/njs_value.h:992:27
Testcase 

```js
let c = [];
async function Float32Array(){
new Promise(Float32Array);
Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.isFrozen(Object.seal(Array),c[null]), c[null]), await c[null]),null),null),null),null),c),null),{}),{}),Proxy),Map),{}),null);

}

new Promise(Float32Array);



```
ASAN: 

```

=================================================================
==119780==ERROR: AddressSanitizer: heap-use-after-free on address 0x625000043d80 at pc 0x00000086b535 bp 0x7ffd530bab70 sp 0x7ffd530bab68
WRITE of size 8 at 0x625000043d80 thread T0
    #0 0x86b534 in njs_set_promise /home/xxx/njs/src/njs_value.h:992:27
    #1 0x86b534 in njs_promise_constructor /home/xxx/njs/src/njs_promise.c:179
    #2 0x7f0e8c in njs_function_native_call /home/xxx/njs/src/njs_function.c:647:11
    #3 0x7f0e8c in njs_function_frame_invoke /home/xxx/njs/src/njs_function.c:683
    #4 0x57f5df in njs_vmcode_interpreter /home/xxx/njs/src/njs_vmcode.c:1451:15
    #5 0x7f3433 in njs_function_lambda_call /home/xxx/njs/src/njs_function.c:610:11
    #6 0x88c7ae in njs_async_function_frame_invoke /home/xxx/njs/src/njs_async.c:28:11
    #7 0x7f1011 in njs_function_frame_invoke /home/xxx/njs/src/njs_function.c:679:16
    #8 0x7f0a73 in njs_function_call2 /home/xxx/njs/src/njs_function.c:515:12
    #9 0x86a5d2 in njs_function_call /home/xxx/njs/src/njs_function.h:164:12
    #10 0x86a5d2 in njs_promise_constructor_call /home/xxx/njs/src/njs_promise.c:224
    #11 0x86a5d2 in njs_promise_constructor /home/xxx/njs/src/njs_promise.c:174
    #12 0x7f0e8c in njs_function_native_call /home/xxx/njs/src/njs_function.c:647:11
    #13 0x7f0e8c in njs_function_frame_invoke /home/xxx/njs/src/njs_function.c:683
    #14 0x57f5df in njs_vmcode_interpreter /home/xxx/njs/src/njs_vmcode.c:1451:15
    #15 0x7f3433 in njs_function_lambda_call /home/xxx/njs/src/njs_function.c:610:11
    #16 0x88c7ae in njs_async_function_frame_invoke /home/xxx/njs/src/njs_async.c:28:11
    #17 0x7f1011 in njs_function_frame_invoke /home/xxx/njs/src/njs_function.c:679:16
    #18 0x7f0a73 in njs_function_call2 /home/xxx/njs/src/njs_function.c:515:12
    #19 0x86a5d2 in njs_function_call /home/xxx/njs/src/njs_function.h:164:12
    #20 0x86a5d2 in njs_promise_constructor_call /home/xxx/njs/src/njs_promise.c:224
    #21 0x86a5d2 in njs_promise_constructor /home/xxx/njs/src/njs_promise.c:174



```


Discussion:

Patch:
diff --git a/src/njs_parser.c b/src/njs_parser.c
--- a/src/njs_parser.c
+++ b/src/njs_parser.c
@@ -2827,7 +2827,7 @@ njs_parser_arguments(njs_parser_t *parser, njs_lexer_token_t *token,
         return njs_parser_stack_pop(parser);
     }
 
-    parser->scope->in_args = 1;
+    parser->scope->in_args++;
 
     njs_parser_next(parser, njs_parser_argument_list);
 
@@ -2840,7 +2840,7 @@ static njs_int_t
 njs_parser_parenthesis_or_comma(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
-    parser->scope->in_args = 0;
+    parser->scope->in_args--;
 
     if (token->type == NJS_TOKEN_CLOSE_PARENTHESIS) {
         njs_lexer_consume_token(parser->lexer, 1);
@@ -3575,7 +3575,7 @@ njs_parser_await(njs_parser_t *parser, njs_lexer_token_t *token,
         return NJS_ERROR;
     }
 
-    if (parser->scope->in_args) {
+    if (parser->scope->in_args > 0) {
         njs_parser_syntax_error(parser, "await in arguments not supported");
         return NJS_ERROR;
     }
diff --git a/src/njs_parser.h b/src/njs_parser.h
--- a/src/njs_parser.h
+++ b/src/njs_parser.h
@@ -26,7 +26,7 @@ struct njs_parser_scope_s {
     uint8_t                         arrow_function;
     uint8_t                         dest_disable;
     uint8_t                         async;
-    uint8_t                         in_args;
+    uint32_t                        in_args;
 };
 
 


Test patch:
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -19938,19 +19938,19 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("(async function() {console.log('Number: ' + await 111)})"),
       njs_str("SyntaxError: await in arguments not supported in 1") },
 
-    { njs_str("function f(a) {}"
-              "(async function() {f(await 111)})"),
+    { njs_str("(async function() {f(await 111)})"),
+      njs_str("SyntaxError: await in arguments not supported in 1") },
+
+    { njs_str("(async function() {f(f(1), await 111)})"),
       njs_str("SyntaxError: await in arguments not supported in 1") },
 
     { njs_str("async () => [await x(1)(),]; async () => [await x(1)()]"),
       njs_str("[object AsyncFunction]") },
 
-    { njs_str("function f(a, b, c) {}"
-              "(async function() {f(1, 'a', await 111)})"),
+    { njs_str("(async function() {f(1, 'a', await 111)})"),
       njs_str("SyntaxError: await in arguments not supported in 1") },
 
-    { njs_str("function f(a) {}"
-              "(async function() {f('Number: ' + await 111)})"),
+    { njs_str("(async function() {f('Number: ' + await 111)})"),
       njs_str("SyntaxError: await in arguments not supported in 1") },
 
     { njs_str("async function f1() {try {f(await f1)} catch(e) {}}"),