Welcome! Log In Create A New Profile

Advanced

[njs] Fixed Function.prototype.apply() with slow arrays.

Dmitry Volyntsev
January 19, 2022 12:20PM
details: https://hg.nginx.org/njs/rev/620418b1a641
branches:
changeset: 1813:620418b1a641
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Wed Jan 19 14:03:49 2022 +0000
description:
Fixed Function.prototype.apply() with slow arrays.

Previously, the function had two issues:
* array->start was referenced without checking for fast array flag
* the created arguments list was not sanity-checked for its length,
which can be very large.

The fix is to remove micro-optimization for arrays and introduce limit
size for arguments list.

This closes #449 issue in Github.

diffstat:

src/njs_function.c | 17 +++++++----------
src/test/njs_unit_test.c | 4 ++++
2 files changed, 11 insertions(+), 10 deletions(-)

diffs (50 lines):

diff -r c419a4e34998 -r 620418b1a641 src/njs_function.c
--- a/src/njs_function.c Wed Jan 19 13:12:09 2022 +0000
+++ b/src/njs_function.c Wed Jan 19 14:03:49 2022 +0000
@@ -1385,18 +1385,10 @@ njs_function_prototype_apply(njs_vm_t *v

if (njs_is_null_or_undefined(arr_like)) {
length = 0;
-
goto activate;
-
- } else if (njs_is_array(arr_like)) {
- arr = arr_like->data.u.array;
+ }

- args = arr->start;
- length = arr->length;
-
- goto activate;
-
- } else if (njs_slow_path(!njs_is_object(arr_like))) {
+ if (njs_slow_path(!njs_is_object(arr_like))) {
njs_type_error(vm, "second argument is not an array-like object");
return NJS_ERROR;
}
@@ -1406,6 +1398,11 @@ njs_function_prototype_apply(njs_vm_t *v
return ret;
}

+ if (njs_slow_path(length > 1024)) {
+ njs_internal_error(vm, "argument list is too long");
+ return NJS_ERROR;
+ }
+
arr = njs_array_alloc(vm, 1, length, NJS_ARRAY_SPARE);
if (njs_slow_path(arr == NULL)) {
return NJS_ERROR;
diff -r c419a4e34998 -r 620418b1a641 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed Jan 19 13:12:09 2022 +0000
+++ b/src/test/njs_unit_test.c Wed Jan 19 14:03:49 2022 +0000
@@ -10063,6 +10063,10 @@ static njs_unit_test_t njs_test[] =
"f.apply(123, {})"),
njs_str("123") },

+ { njs_str("(function(index, ...rest){ return rest[index];})"
+ ".apply({}, [1022].concat(Array(1023).fill(1).map((v,i)=>i.toString(16))))"),
+ njs_str("3fe") },
+
{ njs_str("String.prototype.concat.apply('a', "
"{length:2, 0:{toString:function() {return 'b'}}, 1:'c'})"),
njs_str("abc") },
_______________________________________________
nginx-devel mailing list -- nginx-devel@nginx.org
To unsubscribe send an email to nginx-devel-leave@nginx.org
Subject Author Views Posted

[njs] Fixed Function.prototype.apply() with slow arrays.

Dmitry Volyntsev 286 January 19, 2022 12:20PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 297
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready