njs-0.8.5

2024-06-25 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.5   25 Jun 2024

    nginx modules:

    *) Change: r.variables.var, r.requestText, r.responseText,
   s.variables.var, and the "data" argument of the s.on() callback
   with "upload" or "download" event types will now convert bytes
   invalid in UTF-8 encoding into the replacement character. When
   working with binary data, use r.rawVariables.var, r.requestBuffer,
   r.responseBuffer, s.rawVariables.var, and the "upstream" or
   "downstream" event type for s.on() instead.

    *) Feature: added timeout argument for shared dictionary methods
   add(), set() and incr().

    *) Bugfix: fixed checking for duplicate js_set variables.

    *) Bugfix: fixed request Host header when the port is non-standard.

    *) Bugfix: fixed handling of a zero-length request body in ngx.fetch()
   and r.subrequest().

    *) Bugfix: fixed heap-buffer-overflow in Headers.get().

    *) Bugfix: fixed r.subrequest() error handling.

    Core:

    *) Feature: added zlib module for QuickJS engine.

    *) Bugfix: fixed zlib.inflate().

    *) Bugfix: fixed String.prototype.replaceAll() with zero-length
   argument.

    *) Bugfix: fixed retval handling after an exception in
   Array.prototype.toSpliced(), Array.prototype.toReversed(),
   Array.prototype.toSorted().

    *) Bugfix: fixed RegExp.prototype[@@replace]() with replacements
   containing "$'", "$\`" and strings with Unicode characters.

    *) Bugfix: fixed a one-byte overread in decodeURI() and
   decodeURIComponent().

    *) Bugfix: fixed tracking of argument scope.

    *) Bugfix: fixed integer overflow in Date.parse().
___
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx


[nginx-announce] njs-0.8.5

2024-06-25 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.5   25 Jun 2024

    nginx modules:

    *) Change: r.variables.var, r.requestText, r.responseText,
   s.variables.var, and the "data" argument of the s.on() callback
   with "upload" or "download" event types will now convert bytes
   invalid in UTF-8 encoding into the replacement character. When
   working with binary data, use r.rawVariables.var, r.requestBuffer,
   r.responseBuffer, s.rawVariables.var, and the "upstream" or
   "downstream" event type for s.on() instead.

    *) Feature: added timeout argument for shared dictionary methods
   add(), set() and incr().

    *) Bugfix: fixed checking for duplicate js_set variables.

    *) Bugfix: fixed request Host header when the port is non-standard.

    *) Bugfix: fixed handling of a zero-length request body in ngx.fetch()
   and r.subrequest().

    *) Bugfix: fixed heap-buffer-overflow in Headers.get().

    *) Bugfix: fixed r.subrequest() error handling.

    Core:

    *) Feature: added zlib module for QuickJS engine.

    *) Bugfix: fixed zlib.inflate().

    *) Bugfix: fixed String.prototype.replaceAll() with zero-length
   argument.

    *) Bugfix: fixed retval handling after an exception in
   Array.prototype.toSpliced(), Array.prototype.toReversed(),
   Array.prototype.toSorted().

    *) Bugfix: fixed RegExp.prototype[@@replace]() with replacements
   containing "$'", "$\`" and strings with Unicode characters.

    *) Bugfix: fixed a one-byte overread in decodeURI() and
   decodeURIComponent().

    *) Bugfix: fixed tracking of argument scope.

    *) Bugfix: fixed integer overflow in Date.parse().
___
nginx-announce mailing list
nginx-announce@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-announce


NGINX JavaScript (njs) has migrated to Github

2024-06-05 Thread Dmitry Volyntsev

Hello,

This week we took the next step in our commitment to the Open Source
community by moving the official njs code repository to GitHub
(https://github.com/nginx/njs).

As part of the move, we have revamped our testing infrastructure and added
clearer guidelines around installation, building, and contributing source
code. We believe these changes will serve two purposes:

1. Modernize njs by creating a single place for the community to
contribute, ask questions, and provide feedback.

2. Underscore our commitment to openness, consistency, transparency,
and fairness in our acceptance of contributions.

Importantly, these changes do not impact core njs source code,
functionality, or license in any way. They simply do a better job at
codifying existing guidelines, while providing a modern approach for
managing the project and community.

Please refer to the following files for more details:

README.md

https://github.com/nginx/njs/blob/master/README.md

Provides basic information on what NJS is, how it is used (including links
to sample code & projects), installing, debugging, building from source,
etc...

CONTRIBUTING.md

https://github.com/nginx/njs/blob/master/CONTRIBUTING.md

Provides clear guidelines for asking questions, suggesting improvements,
and contributing code. You will also find our code and git style guides
here.

CODE_OF_CONDUCT.md

https://github.com/nginx/njs/blob/master/CODE_OF_CONDUCT.md

Our pledge, policies, and guidelines for community etiquette, along with
enforcement procedures.

SECURITY.md

https://github.com/nginx/njs/blob/master/SECURITY.md

Our security policy, including what constitutes a security concern and
procedures for reporting vulnerabilities.

SUPPORT.md

https://github.com/nginx/njs/blob/master/SUPPORT.md

A list of all support resources available to the community.


For additional information on F5 NGINX’s commitment to our Open Source
projects and communities, please see:

https://www.f5.com/company/blog/nginx/meetup-recap-nginxs-commitments-to-the-open-source-community

We look forward to your feedback, questions, and contributions as we work
together to make njs even faster, more powerful, and feature-rich!
___
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx


[njs] Fetch: fixed heap-buffer-overflow in Headers.get().

2024-05-24 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f75f670905f0
branches:  
changeset: 2339:f75f670905f0
user:  Dmitry Volyntsev 
date:  Thu May 23 22:50:34 2024 -0700
description:
Fetch: fixed heap-buffer-overflow in Headers.get().

Previously, when more than one header with the same name added to a
Headers object and Headers.get() was used to get the the duplicate
header heap-buffer-overflow occured. The overflow occurred due to an
incorrect calculation of the combined header value's length.

The issue was introduced in c43261bad627 (0.7.10).

diffstat:

 nginx/ngx_js_fetch.c |  31 ++-
 1 files changed, 10 insertions(+), 21 deletions(-)

diffs (60 lines):

diff -r 437fc09db765 -r f75f670905f0 nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c  Thu May 23 22:50:19 2024 -0700
+++ b/nginx/ngx_js_fetch.c  Thu May 23 22:50:34 2024 -0700
@@ -3181,9 +3181,8 @@ static njs_int_t
 ngx_headers_js_get(njs_vm_t *vm, njs_value_t *value, njs_str_t *name,
 njs_value_t *retval, njs_bool_t as_array)
 {
-u_char*data, *p;
-size_t len;
 njs_int_t  rc;
+njs_chb_t  chain;
 ngx_uint_t i;
 ngx_js_tb_elt_t   *h, *ph;
 ngx_list_part_t   *part;
@@ -3254,36 +3253,26 @@ ngx_headers_js_get(njs_vm_t *vm, njs_val
 return NJS_DECLINED;
 }
 
-len = 0;
+NJS_CHB_MP_INIT(, vm);
+
 h = ph;
 
-while (ph != NULL) {
-len = ph->value.len + njs_length(", ");
-ph = ph->next;
-}
-
-len -= njs_length(", ");
-
-data = njs_mp_alloc(njs_vm_memory_pool(vm), len);
-if (data == NULL) {
-njs_vm_memory_error(vm);
-return NJS_ERROR;
-}
-
-p = data;
-
 for ( ;; ) {
-p = ngx_cpymem(p, h->value.data, h->value.len);
+njs_chb_append(, h->value.data, h->value.len);
 
 if (h->next == NULL) {
 break;
 }
 
-*p++ = ','; *p++ = ' ';
+njs_chb_append_literal(, ", ");
 h = h->next;
 }
 
-return njs_vm_value_string_create(vm, retval, data, p - data);
+rc = njs_vm_value_string_create_chb(vm, retval, );
+
+njs_chb_destroy();
+
+return rc;
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Added fast path in njs_chb_utf8_length() for ASCII input.

2024-05-24 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/437fc09db765
branches:  
changeset: 2338:437fc09db765
user:  Dmitry Volyntsev 
date:  Thu May 23 22:50:19 2024 -0700
description:
Added fast path in njs_chb_utf8_length() for ASCII input.

diffstat:

 src/njs_chb.h|  19 +++
 src/test/njs_benchmark.c |  33 +
 2 files changed, 52 insertions(+), 0 deletions(-)

diffs (93 lines):

diff -r 585756e8cafe -r 437fc09db765 src/njs_chb.h
--- a/src/njs_chb.h Wed May 22 23:08:15 2024 -0700
+++ b/src/njs_chb.h Thu May 23 22:50:19 2024 -0700
@@ -96,6 +96,8 @@ njs_chb_size(njs_chb_t *chain)
 njs_inline int64_t
 njs_chb_utf8_length(njs_chb_t *chain)
 {
+u_char  *p, *p_end;
+size_t  size;
 int64_t len, length;
 njs_chb_node_t  *n;
 
@@ -108,6 +110,23 @@ njs_chb_utf8_length(njs_chb_t *chain)
 length = 0;
 
 while (n != NULL) {
+p = n->start;
+size = njs_chb_node_size(n);
+p_end = p + size;
+
+while (p < p_end && *p < 0x80) {
+  p++;
+}
+
+if (p != p_end) {
+break;
+}
+
+length += size;
+n = n->next;
+}
+
+while (n != NULL) {
 len = njs_utf8_length(n->start, njs_chb_node_size(n));
 if (njs_slow_path(len < 0)) {
 return -1;
diff -r 585756e8cafe -r 437fc09db765 src/test/njs_benchmark.c
--- a/src/test/njs_benchmark.c  Wed May 22 23:08:15 2024 -0700
+++ b/src/test/njs_benchmark.c  Thu May 23 22:50:19 2024 -0700
@@ -305,6 +305,21 @@ static njs_benchmark_test_t  njs_test[] 
   njs_str("undefined"),
   1 },
 
+{ "string create chb 'x'.repeat(256)",
+  njs_str("benchmark.string('chb', 'x'.repeat(256), 1)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create chb 'Д'.repeat(128)",
+  njs_str("benchmark.string('chb', 'Д'.repeat(128), 1)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create chb 'x'.repeat(128) + 'Д'.repeat(64)",
+  njs_str("benchmark.string('chb', 'x'.repeat(128) + 'Д'.repeat(64), 
1)"),
+  njs_str("undefined"),
+  1 },
+
 { "JSON.parse",
   njs_str("JSON.parse('{\"a\":123, \"XXX\":[3,4,null]}').a"),
   njs_str("123"),
@@ -696,6 +711,7 @@ njs_benchmark_string(njs_vm_t *vm, njs_v
 njs_index_t unused, njs_value_t *retval)
 {
 int64_t  i, n;
+njs_chb_tchain;
 njs_str_ts, mode;
 njs_value_t  value;
 
@@ -718,6 +734,23 @@ njs_benchmark_string(njs_vm_t *vm, njs_v
 njs_string_create(vm, , s.start, s.length);
 }
 
+} else if (memcmp(mode.start, "chb", 3) == 0) {
+
+NJS_CHB_MP_INIT(, vm);
+
+njs_chb_append_literal(, "abc");
+njs_chb_append(, s.start, s.length);
+njs_chb_append_literal(, "abc");
+njs_chb_append(, s.start, s.length);
+njs_chb_append_literal(, "abc");
+njs_chb_append(, s.start, s.length);
+
+for (i = 0; i < n; i++) {
+njs_string_create_chb(vm, , );
+}
+
+njs_chb_destroy();
+
 } else {
 njs_type_error(vm, "unknown mode \"%V\"", );
 return NJS_ERROR;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed retval handling after an exception.

2024-05-23 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/585756e8cafe
branches:  
changeset: 2337:585756e8cafe
user:  Dmitry Volyntsev 
date:  Wed May 22 23:08:15 2024 -0700
description:
Fixed retval handling after an exception.

Previously, some functions set a retval too early.  If this happened
before an exception a partially created object in inconsistent state
may be visible outside the affected functions.

The following functions were fixed:
Object.prototype.valueOf()
Array.prototype.toSpliced()
Array.prototype.toReversed()
Array.prototype.toSorted()

This fixes #713 issue on Github.

diffstat:

 src/njs_array.c  |  39 ++-
 src/njs_object.c |  14 ++
 src/test/njs_unit_test.c |  12 
 3 files changed, 44 insertions(+), 21 deletions(-)

diffs (203 lines):

diff -r 077a5b2f30d8 -r 585756e8cafe src/njs_array.c
--- a/src/njs_array.c   Wed May 22 17:26:16 2024 -0700
+++ b/src/njs_array.c   Wed May 22 23:08:15 2024 -0700
@@ -591,14 +591,14 @@ njs_array_of(njs_vm_t *vm, njs_value_t *
 return NJS_ERROR;
 }
 
-njs_set_array(retval, array);
-
 if (array->object.fast_array) {
 for (i = 0; i < length; i++) {
 array->start[i] = args[i + 1];
 }
 }
 
+njs_set_array(retval, array);
+
 return NJS_OK;
 }
 
@@ -1388,7 +1388,7 @@ njs_array_prototype_to_spliced(njs_vm_t 
 {
 int64_t  i, n, r, start, length, to_insert, to_skip, new_length;
 njs_int_tret;
-njs_value_t  *this, value;
+njs_value_t  *this, a, value;
 njs_array_t  *array;
 
 this = njs_argument(args, 0);
@@ -1439,7 +1439,7 @@ njs_array_prototype_to_spliced(njs_vm_t 
 return NJS_ERROR;
 }
 
-njs_set_array(retval, array);
+njs_set_array(, array);
 
 for (i = 0; i < start; i++) {
 ret = njs_value_property_i64(vm, this, i, );
@@ -1447,14 +1447,14 @@ njs_array_prototype_to_spliced(njs_vm_t 
 return NJS_ERROR;
 }
 
-ret = njs_value_create_data_prop_i64(vm, retval, i, , 0);
+ret = njs_value_create_data_prop_i64(vm, , i, , 0);
 if (njs_slow_path(ret != NJS_OK)) {
 return ret;
 }
 }
 
 for (n = 3; to_insert-- > 0; i++, n++) {
-ret = njs_value_create_data_prop_i64(vm, retval, i, [n], 0);
+ret = njs_value_create_data_prop_i64(vm, , i, [n], 0);
 if (njs_slow_path(ret != NJS_OK)) {
 return ret;
 }
@@ -1468,7 +1468,7 @@ njs_array_prototype_to_spliced(njs_vm_t 
 return NJS_ERROR;
 }
 
-ret = njs_value_create_data_prop_i64(vm, retval, i, , 0);
+ret = njs_value_create_data_prop_i64(vm, , i, , 0);
 if (njs_slow_path(ret != NJS_OK)) {
 return ret;
 }
@@ -1477,6 +1477,8 @@ njs_array_prototype_to_spliced(njs_vm_t 
 i++;
 }
 
+njs_set_array(retval, array);
+
 return NJS_OK;
 }
 
@@ -1562,7 +1564,7 @@ njs_array_prototype_to_reversed(njs_vm_t
 int64_t  length, i;
 njs_int_tret;
 njs_array_t  *array;
-njs_value_t  *this, value;
+njs_value_t  *this, a, value;
 
 this = njs_argument(args, 0);
 
@@ -1581,7 +1583,7 @@ njs_array_prototype_to_reversed(njs_vm_t
 return NJS_ERROR;
 }
 
-njs_set_array(retval, array);
+njs_set_array(, array);
 
 for (i = 0; i < length; i++) {
 ret = njs_value_property_i64(vm, this, length - i - 1, );
@@ -1589,12 +1591,14 @@ njs_array_prototype_to_reversed(njs_vm_t
 return NJS_ERROR;
 }
 
-ret = njs_value_create_data_prop_i64(vm, retval, i, , 0);
+ret = njs_value_create_data_prop_i64(vm, , i, , 0);
 if (njs_slow_path(ret != NJS_OK)) {
 return ret;
 }
 }
 
+njs_set_array(retval, array);
+
 return NJS_OK;
 }
 
@@ -3018,7 +3022,7 @@ njs_array_prototype_to_sorted(njs_vm_t *
 int64_ti, nslots, nunds, length;
 njs_int_t  ret;
 njs_array_t*array;
-njs_value_t*this, *comparefn;
+njs_value_t*this, *comparefn, a;
 njs_function_t *compare;
 njs_array_sort_slot_t  *slots;
 
@@ -3070,24 +3074,25 @@ njs_array_prototype_to_sorted(njs_vm_t *
 
 njs_assert(length == (nslots + nunds));
 
-njs_set_array(retval, array);
+njs_set_array(, array);
 
 for (i = 0; i < nslots; i++) {
-ret = njs_value_property_i64_set(vm, retval, i, [i].value);
-if (njs_slow_path(ret == NJS_ERROR)) {
+ret = njs_value_create_data_prop_i64(vm, , i, [i].value, 0);
+if (njs_slow_path(ret != NJS_OK)) {
 goto exception;
 }
 }
 
 for (; i < length; i++) {
-ret = njs_value_property_i64_set(vm, retval, i,
-  njs_value_arg(_value_undefined));
-if (njs_slow_path(ret == NJS_ERROR)) {
+ret = njs_value_crea

[njs] Improved String.prototype.replaceAll() for readability.

2024-05-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/077a5b2f30d8
branches:  
changeset: 2336:077a5b2f30d8
user:  Dmitry Volyntsev 
date:  Wed May 22 17:26:16 2024 -0700
description:
Improved String.prototype.replaceAll() for readability.

diffstat:

 src/njs_string.c |  44 ++--
 1 files changed, 26 insertions(+), 18 deletions(-)

diffs (100 lines):

diff -r e496851c0fe7 -r 077a5b2f30d8 src/njs_string.c
--- a/src/njs_string.c  Wed May 22 17:26:08 2024 -0700
+++ b/src/njs_string.c  Wed May 22 17:26:16 2024 -0700
@@ -3228,7 +3228,7 @@ njs_string_prototype_replace(njs_vm_t *v
 njs_index_t replaceAll, njs_value_t *retval)
 {
 u_char *r;
-size_t length, size, increment, end_of_last_match;
+size_t length, size, end_of_last_match;
 int64_tpos;
 njs_int_t  ret;
 njs_str_t  str;
@@ -3236,7 +3236,7 @@ njs_string_prototype_replace(njs_vm_t *v
 njs_value_t*this, *search, *replace;
 njs_value_tsearch_lvalue, replace_lvalue, replacer, value,
arguments[3];
-const u_char   *p, *p_start;
+const u_char   *start, *end;
 njs_function_t *func_replace;
 njs_string_prop_t  string, s, ret_string;
 
@@ -3331,7 +3331,6 @@ njs_string_prototype_replace(njs_vm_t *v
 }
 
 if (!replaceAll) {
-
 if (func_replace == NULL) {
 ret = njs_string_get_substitution(vm, search, this, pos, NULL, 0,
   NULL, replace, );
@@ -3356,7 +3355,7 @@ njs_string_prototype_replace(njs_vm_t *v
 }
 }
 
-p = njs_string_offset(, pos);
+end = njs_string_offset(, pos);
 
 (void) njs_string_prop(_string, );
 
@@ -3368,17 +3367,16 @@ njs_string_prototype_replace(njs_vm_t *v
 return NJS_ERROR;
 }
 
-r = njs_cpymem(r, string.start, p - string.start);
+r = njs_cpymem(r, string.start, end - string.start);
 r = njs_cpymem(r, ret_string.start, ret_string.size);
-memcpy(r, p + s.size, string.size - s.size - (p - string.start));
+memcpy(r, end + s.size, string.size - s.size - (end - string.start));
 
 return NJS_OK;
 }
 
 NJS_CHB_MP_INIT(, vm);
 
-p_start = string.start;
-increment = s.length != 0 ? s.length : 1;
+start = string.start;
 
 do {
 if (func_replace == NULL) {
@@ -3405,20 +3403,30 @@ njs_string_prototype_replace(njs_vm_t *v
 }
 }
 
-p = njs_string_offset(, pos);
+end = njs_string_offset(, pos);
 (void) njs_string_prop(_string, );
 
-njs_chb_append(, p_start, p - p_start);
+njs_chb_append(, start, end - start);
 njs_chb_append(, ret_string.start, ret_string.size);
 
-p_start = p + s.size;
-end_of_last_match = pos + increment;
-
-pos = njs_string_index_of(, , end_of_last_match);
-
-} while (pos >= 0 && end_of_last_match <= string.length);
-
-njs_chb_append(, p_start, string.start + string.size - p_start);
+start = end + s.size;
+end_of_last_match = pos + s.length;
+
+if (njs_slow_path(s.length == 0)) {
+if (end_of_last_match >= string.length) {
+pos = -1;
+
+} else {
+pos = end_of_last_match + 1;
+}
+
+} else {
+pos = njs_string_index_of(, , end_of_last_match);
+}
+
+} while (pos >= 0);
+
+njs_chb_append(, start, string.start + string.size - start);
 
 ret = njs_string_create_chb(vm, retval, );
 if (njs_slow_path(ret != NJS_OK)) {
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed String.prototype.replaceAll() with zero length argument.

2024-05-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/e496851c0fe7
branches:  
changeset: 2335:e496851c0fe7
user:  Dmitry Volyntsev 
date:  Wed May 22 17:26:08 2024 -0700
description:
Fixed String.prototype.replaceAll() with zero length argument.

This fixes #712 issue on Github.

diffstat:

 src/njs_string.c |  15 ---
 src/njs_string.h |   4 
 src/test/njs_unit_test.c |   6 ++
 3 files changed, 14 insertions(+), 11 deletions(-)

diffs (76 lines):

diff -r bc09b884022d -r e496851c0fe7 src/njs_string.c
--- a/src/njs_string.c  Tue May 21 23:41:10 2024 -0700
+++ b/src/njs_string.c  Wed May 22 17:26:08 2024 -0700
@@ -1736,7 +1736,9 @@ njs_string_index_of(njs_string_prop_t *s
 } else {
 /* UTF-8 string. */
 
-p = njs_string_utf8_offset(string->start, end, index);
+p = (index < string->length)
+? njs_string_utf8_offset(string->start, end, index)
+: end;
 end -= search->size - 1;
 
 while (p < end) {
@@ -3231,7 +3233,6 @@ njs_string_prototype_replace(njs_vm_t *v
 njs_int_t  ret;
 njs_str_t  str;
 njs_chb_t  chain;
-njs_bool_t is_ascii_string;
 njs_value_t*this, *search, *replace;
 njs_value_tsearch_lvalue, replace_lvalue, replacer, value,
arguments[3];
@@ -3378,7 +3379,6 @@ njs_string_prototype_replace(njs_vm_t *v
 
 p_start = string.start;
 increment = s.length != 0 ? s.length : 1;
-is_ascii_string = njs_is_ascii_string();
 
 do {
 if (func_replace == NULL) {
@@ -3405,14 +3405,7 @@ njs_string_prototype_replace(njs_vm_t *v
 }
 }
 
-if (is_ascii_string) {
-p = string.start + pos;
-
-} else {
-p = njs_string_utf8_offset(string.start, string.start + 
string.size,
-   pos);
-}
-
+p = njs_string_offset(, pos);
 (void) njs_string_prop(_string, );
 
 njs_chb_append(, p_start, p - p_start);
diff -r bc09b884022d -r e496851c0fe7 src/njs_string.h
--- a/src/njs_string.h  Tue May 21 23:41:10 2024 -0700
+++ b/src/njs_string.h  Wed May 22 17:26:08 2024 -0700
@@ -245,6 +245,10 @@ njs_string_offset(njs_string_prop_t *str
 
 /* UTF-8 string. */
 
+if (index == (int64_t) string->length) {
+return string->start + string->size;
+}
+
 return njs_string_utf8_offset(string->start, string->start + string->size,
   index);
 }
diff -r bc09b884022d -r e496851c0fe7 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Tue May 21 23:41:10 2024 -0700
+++ b/src/test/njs_unit_test.c  Wed May 22 17:26:08 2024 -0700
@@ -,6 +,12 @@ static njs_unit_test_t  njs_test[] =
 { njs_str("var r = 'αβγ'.replaceAll('', 'X'); [r, r.length]"),
   njs_str("XαXβXγX,7") },
 
+{ njs_str("var r = ''.replaceAll('', 'z'); [r, r.length]"),
+  njs_str("z,1") },
+
+{ njs_str("var r = 'α'.padStart(32).replaceAll('', 'z'); [r, r.length]"),
+  njs_str("z z z z z z z z z z z z z z z z z z z z z z z z z z z z z z z 
zαz,65") },
+
 { njs_str("'abc'.replace('b', (m, o, s) => `|${s}|${o}|${m}|`)"),
   njs_str("a|abc|1|b|c") },
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Aligned StringIndexOf() implementation with the spec.

2024-05-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/bc09b884022d
branches:  
changeset: 2334:bc09b884022d
user:  Dmitry Volyntsev 
date:  Tue May 21 23:41:10 2024 -0700
description:
Aligned StringIndexOf() implementation with the spec.

When searchValue is empty the function should return early
when fromIndex <= len is also true.

diffstat:

 src/njs_string.c |  4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diffs (14 lines):

diff -r 2d098d2a1c85 -r bc09b884022d src/njs_string.c
--- a/src/njs_string.c  Tue May 21 23:41:10 2024 -0700
+++ b/src/njs_string.c  Tue May 21 23:41:10 2024 -0700
@@ -1710,8 +1710,8 @@ njs_string_index_of(njs_string_prop_t *s
 
 length = string->length;
 
-if (njs_slow_path(search->length == 0)) {
-return (from < length) ? from : length;
+if (search->length == 0 && from <= length) {
+return from;
 }
 
 index = from;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Removed code for byte strings in built-in functions.

2024-05-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/2d098d2a1c85
branches:  
changeset: 2333:2d098d2a1c85
user:  Dmitry Volyntsev 
date:  Tue May 21 23:41:10 2024 -0700
description:
Removed code for byte strings in built-in functions.

diffstat:

 src/njs_array.c  |  52 --
 src/njs_iterator.c   |   2 +-
 src/njs_json.c   |   9 +-
 src/njs_object.c |   4 +-
 src/njs_regexp.c |  16 +++
 src/njs_string.c |  65 +--
 src/njs_string.h |  20 ++---
 src/njs_vmcode.c |   9 --
 src/test/njs_unit_test.c |  30 +-
 9 files changed, 49 insertions(+), 158 deletions(-)

diffs (596 lines):

diff -r 27da19960b72 -r 2d098d2a1c85 src/njs_array.c
--- a/src/njs_array.c   Tue May 21 23:38:19 2024 -0700
+++ b/src/njs_array.c   Tue May 21 23:41:10 2024 -0700
@@ -826,29 +826,15 @@ njs_array_prototype_slice_copy(njs_vm_t 
 src = string.start;
 end = src + string.size;
 
-if (string.length == 0) {
-/* Byte string. */
-do {
-value = >start[n++];
-dst = njs_string_short_start(value);
-*dst = *src++;
-njs_string_short_set(value, 1, 0);
-
-length--;
-} while (length != 0);
-
-} else {
-/* UTF-8 or ASCII string. */
-do {
-value = >start[n++];
-dst = njs_string_short_start(value);
-dst = njs_utf8_copy(dst, , end);
-size = dst - njs_string_short_start(value);
-njs_string_short_set(value, size, 1);
-
-length--;
-} while (length != 0);
-}
+do {
+value = >start[n++];
+dst = njs_string_short_start(value);
+dst = njs_utf8_copy(dst, , end);
+size = dst - njs_string_short_start(value);
+njs_string_short_set(value, size, 1);
+
+length--;
+} while (length != 0);
 
 } else if (njs_is_object(this)) {
 
@@ -1647,11 +1633,10 @@ static njs_int_t
 njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 njs_index_t unused, njs_value_t *retval)
 {
-u_char *p, *last;
+u_char *p;
 int64_ti, size, len, length;
 njs_int_t  ret;
 njs_chb_t  chain;
-njs_utf8_t utf8;
 njs_value_t*value, *this, entry;
 njs_string_prop_t  separator, string;
 
@@ -1684,7 +1669,6 @@ njs_array_prototype_join(njs_vm_t *vm, n
 }
 
 length = 0;
-utf8 = njs_is_byte_string() ? NJS_STRING_BYTE : NJS_STRING_UTF8;
 
 ret = njs_object_length(vm, this, );
 if (njs_slow_path(ret == NJS_ERROR)) {
@@ -1708,29 +1692,15 @@ njs_array_prototype_join(njs_vm_t *vm, n
 
 if (!njs_is_null_or_undefined(value)) {
 if (!njs_is_string(value)) {
-last = njs_chb_current();
-
 ret = njs_value_to_chain(vm, , value);
 if (njs_slow_path(ret < NJS_OK)) {
 return ret;
 }
 
-if (last != njs_chb_current() && ret == 0) {
-/*
- * Appended values was a byte string.
- */
-utf8 = NJS_STRING_BYTE;
-}
-
 length += ret;
 
 } else {
 (void) njs_string_prop(, value);
-
-if (njs_is_byte_string()) {
-utf8 = NJS_STRING_BYTE;
-}
-
 length += string.length;
 njs_chb_append(, string.start, string.size);
 }
@@ -1755,7 +1725,7 @@ njs_array_prototype_join(njs_vm_t *vm, n
 
 length -= separator.length;
 
-p = njs_string_alloc(vm, retval, size, utf8 ? length : 0);
+p = njs_string_alloc(vm, retval, size, length);
 if (njs_slow_path(p == NULL)) {
 return NJS_ERROR;
 }
diff -r 27da19960b72 -r 2d098d2a1c85 src/njs_iterator.c
--- a/src/njs_iterator.cTue May 21 23:38:19 2024 -0700
+++ b/src/njs_iterator.cTue May 21 23:41:10 2024 -0700
@@ -355,7 +355,7 @@ njs_object_iterate(njs_vm_t *vm, njs_ite
 end = p + string_prop.size;
 
 if ((size_t) length == string_prop.size) {
-/* Byte or ASCII string. */
+/* ASCII string. */
 
 for (i = from; i < to; i++) {
 /* This cannot fail. */
diff -r 27da19960b72 -r 2d098d2a1c85 src/njs_json.c
--- a/src/njs_json.cTue May 21 23:38:19 2024 -0700
+++ b/src/njs_json.cTue May 21 23:41:10 2024 -0700
@@ -226,13 +226,6 @@ njs_json_stringify(njs_vm_t *vm, njs_val
 switch (space->type) {
 case N

[njs] Avoid creating byte strings explicitly.

2024-05-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/27da19960b72
branches:  
changeset: 2332:27da19960b72
user:  Dmitry Volyntsev 
date:  Tue May 21 23:38:19 2024 -0700
description:
Avoid creating byte strings explicitly.

Previously, calls like njs_string_new(,,,0) produced byte strings by
explicitly providing zero length argument.

diffstat:

 src/njs_builtin.c |  4 ++--
 src/njs_json.c|  8 +---
 src/njs_vm.c  |  2 +-
 3 files changed, 4 insertions(+), 10 deletions(-)

diffs (58 lines):

diff -r 286dbef3c0b2 -r 27da19960b72 src/njs_builtin.c
--- a/src/njs_builtin.c Mon May 20 16:44:10 2024 -0700
+++ b/src/njs_builtin.c Tue May 21 23:38:19 2024 -0700
@@ -388,7 +388,7 @@ njs_builtin_traverse(njs_vm_t *vm, njs_t
 return NJS_ERROR;
 }
 
-ret = njs_string_new(vm, >name, buf, p - buf, 0);
+ret = njs_string_create(vm, >name, buf, p - buf);
 if (njs_slow_path(ret != NJS_OK)) {
 return ret;
 }
@@ -590,7 +590,7 @@ njs_ext_dump(njs_vm_t *vm, njs_value_t *
 return NJS_ERROR;
 }
 
-return njs_string_new(vm, retval, str.start, str.length, 0);
+return njs_string_create(vm, retval, str.start, str.length);
 }
 
 
diff -r 286dbef3c0b2 -r 27da19960b72 src/njs_json.c
--- a/src/njs_json.cMon May 20 16:44:10 2024 -0700
+++ b/src/njs_json.cTue May 21 23:38:19 2024 -0700
@@ -548,7 +548,6 @@ njs_json_parse_string(njs_json_parse_ctx
 {
 u_charch, *s, *dst;
 size_tsize, surplus;
-ssize_t   length;
 uint32_t  utf, utf_low;
 njs_int_t ret;
 const u_char  *start, *last;
@@ -742,12 +741,7 @@ njs_json_parse_string(njs_json_parse_ctx
 start = dst;
 }
 
-length = njs_utf8_length(start, size);
-if (njs_slow_path(length < 0)) {
-length = 0;
-}
-
-ret = njs_string_new(ctx->vm, value, (u_char *) start, size, length);
+ret = njs_string_create(ctx->vm, value, (u_char *) start, size);
 if (njs_slow_path(ret != NJS_OK)) {
 return NULL;
 }
diff -r 286dbef3c0b2 -r 27da19960b72 src/njs_vm.c
--- a/src/njs_vm.c  Mon May 20 16:44:10 2024 -0700
+++ b/src/njs_vm.c  Tue May 21 23:38:19 2024 -0700
@@ -874,7 +874,7 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str
 njs_lvlhsh_t*hash;
 njs_lvlhsh_query_t  lhq;
 
-ret = njs_string_new(vm, >name, var_name->start, var_name->length, 
0);
+ret = njs_string_create(vm, >name, var_name->start, 
var_name->length);
 if (njs_slow_path(ret != NJS_OK)) {
 return NJS_ERROR;
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] HTTP: fixed handling of 0 length request body.

2024-05-20 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/286dbef3c0b2
branches:  
changeset: 2331:286dbef3c0b2
user:  Dmitry Volyntsev 
date:  Mon May 20 16:44:10 2024 -0700
description:
HTTP: fixed handling of 0 length request body.

Previously, when r.requestBuffer was passed as a body argument to
ngx.fetch() or r.subrequest() then exception was thrown "Error: invalid
Request body" when the request body had 0 length.

diffstat:

 src/njs_vm.c |  6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diffs (16 lines):

diff -r 8851a78723dc -r 286dbef3c0b2 src/njs_vm.c
--- a/src/njs_vm.c  Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_vm.c  Mon May 20 16:44:10 2024 -0700
@@ -1602,6 +1602,12 @@ njs_vm_value_to_bytes(njs_vm_t *vm, njs_
 }
 
 if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+if (length == 0) {
+dst->length = 0;
+dst->start = NULL;
+return NJS_OK;
+}
+
 njs_type_error(vm, "detached buffer");
 return NJS_ERROR;
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Removing njs_string_set() from builtin functions.

2024-05-17 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/8851a78723dc
branches:  
changeset: 2330:8851a78723dc
user:  Dmitry Volyntsev 
date:  Fri May 17 21:54:50 2024 -0700
description:
Removing njs_string_set() from builtin functions.

This is the last function that produced byte strings.

diffstat:

 src/njs_builtin.c|  9 -
 src/njs_error.c  |  2 +-
 src/njs_extern.c |  5 +++--
 src/njs_parser.c |  2 +-
 src/njs_regexp.c |  4 ++--
 src/njs_string.c |  4 ++--
 src/njs_string.h |  3 ++-
 src/njs_vm.c |  4 ++--
 src/test/njs_benchmark.c |  2 +-
 9 files changed, 18 insertions(+), 17 deletions(-)

diffs (159 lines):

diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_builtin.c
--- a/src/njs_builtin.c Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_builtin.c Fri May 17 21:54:50 2024 -0700
@@ -1201,8 +1201,8 @@ njs_process_object_argv(njs_vm_t *vm, nj
 i = 0;
 
 for (arg = vm->options.argv; i < vm->options.argc; arg++) {
-njs_string_set(vm, >start[i++], (u_char *) *arg,
-   njs_strlen(*arg));
+njs_string_create(vm, >start[i++], (u_char *) *arg,
+  njs_strlen(*arg));
 }
 
 prop = njs_object_prop_alloc(vm, _string, _value_undefined, 1);
@@ -1265,7 +1265,7 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlh
 continue;
 }
 
-ret = njs_string_create(vm, >name, (char *) entry, val - entry);
+ret = njs_string_create(vm, >name, entry, val - entry);
 if (njs_slow_path(ret != NJS_OK)) {
 return NJS_ERROR;
 }
@@ -1285,8 +1285,7 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlh
 
 val++;
 
-ret = njs_string_create(vm, njs_prop_value(prop), (char *) val,
-njs_strlen(val));
+ret = njs_string_create(vm, njs_prop_value(prop), val, 
njs_strlen(val));
 if (njs_slow_path(ret != NJS_OK)) {
 return NJS_ERROR;
 }
diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_error.c
--- a/src/njs_error.c   Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_error.c   Fri May 17 21:54:50 2024 -0700
@@ -147,7 +147,7 @@ njs_error_stack_new(njs_vm_t *vm, njs_ob
 return ret;
 }
 
-return njs_string_set(vm, retval, string.start, string.length);
+return njs_string_create(vm, retval, string.start, string.length);
 }
 
 
diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_extern.c
--- a/src/njs_extern.c  Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_extern.c  Fri May 17 21:54:50 2024 -0700
@@ -74,8 +74,9 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
 lhq.key_hash = external->name.symbol;
 
 } else {
-ret = njs_string_set(vm, >name, external->name.string.start,
- external->name.string.length);
+ret = njs_string_create(vm, >name,
+external->name.string.start,
+external->name.string.length);
 if (njs_slow_path(ret != NJS_OK)) {
 return NJS_ERROR;
 }
diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_parser.c
--- a/src/njs_parser.c  Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_parser.c  Fri May 17 21:54:50 2024 -0700
@@ -9242,7 +9242,7 @@ njs_parser_error(njs_vm_t *vm, njs_objec
 njs_value_property_set(vm, , njs_value_arg(_number), );
 
 if (file->length != 0) {
-ret = njs_string_set(vm, , file->start, file->length);
+ret = njs_string_create(vm, , file->start, file->length);
 if (ret == NJS_OK) {
 njs_value_property_set(vm, , njs_value_arg(_name),
);
diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_regexp.c
--- a/src/njs_regexp.c  Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_regexp.c  Fri May 17 21:54:50 2024 -0700
@@ -1144,8 +1144,8 @@ njs_regexp_exec_result(njs_vm_t *vm, njs
 do {
 group = >groups[i];
 
-ret = njs_string_set(vm, , group->name.start,
- group->name.length);
+ret = njs_string_create(vm, , group->name.start,
+group->name.length);
 if (njs_slow_path(ret != NJS_OK)) {
 goto fail;
 }
diff -r 4e0553f7ea68 -r 8851a78723dc src/njs_string.c
--- a/src/njs_string.c  Fri May 17 21:54:50 2024 -0700
+++ b/src/njs_string.c  Fri May 17 21:54:50 2024 -0700
@@ -127,7 +127,7 @@ njs_string_set(njs_vm_t *vm, njs_value_t
 
 
 njs_int_t
-njs_string_create(njs_vm_t *vm, njs_value_t *value, const char *src,
+njs_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *src,
 size_t size)
 {
 u_char *p, *p_end;
@@ -3152,7 +3152,7 @@ njs_string_get_substitution(njs_vm_t *vm
 
 p += 2;
 
-ret = njs_string_create(vm, , (const char *) p, r - p);
+ret = njs_str

[njs] Change: removed byte strings API.

2024-05-17 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/4e0553f7ea68
branches:  
changeset: 2329:4e0553f7ea68
user:  Dmitry Volyntsev 
date:  Fri May 17 21:54:50 2024 -0700
description:
Change: removed byte strings API.

These functions are unsafe because they produce byte strings.
Byte strings may not work as expected with the existing JS methods.

The following functions were removed:
- njs_vm_value_string_set() use njs_vm_value_string_create() as a
drop-in replacement.
- njs_vm_value_string_alloc() use njs_chb_t and
njs_vm_value_string_create_chb() instead.

This fixes #710 on Github.

diffstat:

 external/njs_query_string_module.c |2 +-
 external/njs_shell.c   |4 +-
 external/njs_webcrypto_module.c|   54 ++--
 external/njs_xml_module.c  |   20 ++--
 nginx/ngx_http_js_module.c |  150 ++--
 nginx/ngx_js.c |   34 
 nginx/ngx_js.h |2 +-
 nginx/ngx_js_fetch.c   |   32 +++---
 nginx/ngx_js_shared_dict.c |   25 +++--
 nginx/ngx_stream_js_module.c   |4 +-
 src/njs.h  |8 -
 src/njs_string.c   |2 +-
 src/njs_vm.c   |   19 +
 src/test/njs_benchmark.c   |   12 +-
 src/test/njs_externals_test.c  |   38 
 src/test/njs_unit_test.c   |   32 +++---
 16 files changed, 193 insertions(+), 245 deletions(-)

diffs (truncated from 1114 to 1000 lines):

diff -r dec46ad52e9a -r 4e0553f7ea68 external/njs_query_string_module.c
--- a/external/njs_query_string_module.cFri May 17 21:54:49 2024 -0700
+++ b/external/njs_query_string_module.cFri May 17 21:54:50 2024 -0700
@@ -694,7 +694,7 @@ njs_query_string_stringify(njs_vm_t *vm,
 object = njs_arg(args, nargs, 1);
 
 if (njs_slow_path(!njs_value_is_object(object))) {
-njs_vm_value_string_set(vm, retval, (u_char *) "", 0);
+njs_vm_value_string_create(vm, retval, (u_char *) "", 0);
 return NJS_OK;
 }
 
diff -r dec46ad52e9a -r 4e0553f7ea68 external/njs_shell.c
--- a/external/njs_shell.c  Fri May 17 21:54:49 2024 -0700
+++ b/external/njs_shell.c  Fri May 17 21:54:50 2024 -0700
@@ -1579,8 +1579,8 @@ njs_engine_njs_complete(njs_engine_t *en
 
 while (p < end && *p != '.') { p++; }
 
-ret = njs_vm_value_string_set(vm, njs_value_arg(), start,
-  p - start);
+ret = njs_vm_value_string_create(vm, njs_value_arg(), start,
+ p - start);
 if (njs_slow_path(ret != NJS_OK)) {
 return NULL;
 }
diff -r dec46ad52e9a -r 4e0553f7ea68 external/njs_webcrypto_module.c
--- a/external/njs_webcrypto_module.c   Fri May 17 21:54:49 2024 -0700
+++ b/external/njs_webcrypto_module.c   Fri May 17 21:54:50 2024 -0700
@@ -1855,7 +1855,7 @@ njs_export_jwk_rsa(njs_vm_t *vm, njs_web
 return NJS_ERROR;
 }
 
-njs_vm_value_string_set(vm, njs_value_arg(_s), (u_char *) "RSA", 3);
+njs_vm_value_string_create(vm, njs_value_arg(_s), (u_char *) "RSA", 3);
 
 ret = njs_vm_object_prop_set(vm, retval, _kty, _s);
 if (ret != NJS_OK) {
@@ -1909,8 +1909,8 @@ njs_export_jwk_rsa(njs_vm_t *vm, njs_web
 
 nm = _webcrypto_alg_name[key->alg->type][key->hash];
 
-(void) njs_vm_value_string_set(vm, njs_value_arg(), nm->start,
-   nm->length);
+(void) njs_vm_value_string_create(vm, njs_value_arg(), nm->start,
+  nm->length);
 
 return njs_vm_object_prop_set(vm, retval, _alg, );
 }
@@ -1975,8 +1975,8 @@ njs_export_jwk_ec(njs_vm_t *vm, njs_webc
 nid = EC_GROUP_get_curve_name(group);
 
 cname = njs_algorithm_curve_name(nid);
-(void) njs_vm_value_string_set(vm, njs_value_arg(),
-   cname->start, cname->length);
+(void) njs_vm_value_string_create(vm, njs_value_arg(),
+  cname->start, cname->length);
 
 if (cname->length == 0) {
 njs_vm_type_error(vm, "Unsupported JWK EC curve: %s", OBJ_nid2sn(nid));
@@ -1988,7 +1988,7 @@ njs_export_jwk_ec(njs_vm_t *vm, njs_webc
 goto fail;
 }
 
-njs_vm_value_string_set(vm, njs_value_arg(_s), (u_char *) "EC", 2);
+njs_vm_value_string_create(vm, njs_value_arg(_s), (u_char *) "EC", 2);
 
 ret = njs_vm_object_prop_set(vm, retval, _kty, _s);
 if (ret != NJS_OK) {
@@ -2154,8 +2154,8 @@ njs_export_jwk_oct(njs_vm_t *vm, njs_web
 
 if (key->alg->type == NJS_ALGORITHM_HMAC) {
 nm = _webcrypto_alg_name[type][key->hash];
-(void) njs_vm_value_string_set(vm, njs_value_arg(), nm->start,
-   nm->length);
+(void) njs_vm_value_string_create(vm, njs_

[njs] Optimized string creation with ASCII input.

2024-05-17 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/dec46ad52e9a
branches:  
changeset: 2328:dec46ad52e9a
user:  Dmitry Volyntsev 
date:  Fri May 17 21:54:49 2024 -0700
description:
Optimized string creation with ASCII input.

diffstat:

 src/njs_string.c |  12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diffs (24 lines):

diff -r f474755a4dce -r dec46ad52e9a src/njs_string.c
--- a/src/njs_string.c  Fri May 17 18:36:12 2024 -0700
+++ b/src/njs_string.c  Fri May 17 21:54:49 2024 -0700
@@ -130,8 +130,20 @@ njs_int_t
 njs_string_create(njs_vm_t *vm, njs_value_t *value, const char *src,
 size_t size)
 {
+u_char *p, *p_end;
 njs_str_t  str;
 
+p = (u_char *) src;
+p_end = p + size;
+
+while (p < p_end && *p < 0x80) {
+  p++;
+}
+
+if (p == p_end) {
+return njs_string_new(vm, value, (u_char *) src, size, size);
+}
+
 str.start = (u_char *) src;
 str.length = size;
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Added string creation benchmark.

2024-05-17 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f474755a4dce
branches:  
changeset: 2327:f474755a4dce
user:  Dmitry Volyntsev 
date:  Fri May 17 18:36:12 2024 -0700
description:
Added string creation benchmark.

diffstat:

 src/test/njs_benchmark.c |  159 ++-
 1 files changed, 158 insertions(+), 1 deletions(-)

diffs (185 lines):

diff -r 02369792b032 -r f474755a4dce src/test/njs_benchmark.c
--- a/src/test/njs_benchmark.c  Thu May 09 12:58:57 2024 -0700
+++ b/src/test/njs_benchmark.c  Fri May 17 18:36:12 2024 -0700
@@ -29,12 +29,52 @@ typedef struct {
 } njs_opts_t;
 
 
+static njs_int_t njs_benchmark_preinit(njs_vm_t *vm);
+static njs_int_t njs_benchmark_init(njs_vm_t *vm);
+static njs_int_t njs_benchmark_string(njs_vm_t *vm, njs_value_t *args,
+njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
+
+
+static njs_external_t  njs_benchmark_external[] = {
+
+{
+.flags = NJS_EXTERN_PROPERTY | NJS_EXTERN_SYMBOL,
+.name.symbol = NJS_SYMBOL_TO_STRING_TAG,
+.u.property = {
+.value = "Benchmark",
+}
+},
+
+{
+.flags = NJS_EXTERN_METHOD,
+.name.string = njs_str("string"),
+.writable = 1,
+.configurable = 1,
+.enumerable = 1,
+.u.method = {
+.native = njs_benchmark_string,
+}
+},
+};
+
+
+njs_module_t  njs_benchmark_module = {
+.name = njs_str("benchmark"),
+.preinit = njs_benchmark_preinit,
+.init = njs_benchmark_init,
+};
+
+
 njs_module_t *njs_benchmark_addon_external_modules[] = {
 _unit_test_external_module,
-NULL,
+_benchmark_module,
+NULL
 };
 
 
+static njs_int_tnjs_benchmark_proto_id;
+
+
 static uint64_t
 njs_time(void)
 {
@@ -225,6 +265,46 @@ static njs_benchmark_test_t  njs_test[] 
   njs_str("4"),
   10 },
 
+{ "string set 'abcdefABCDEF'",
+  njs_str("benchmark.string('set', 'abcdef', 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string set 'АБВГДЕ'",
+  njs_str("benchmark.string('set', 'АБВГДЕ', 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string set 'x'.repeat(24)",
+  njs_str("benchmark.string('set', 'x'.repeat(32), 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string set 'Д'.repeat(12)",
+  njs_str("benchmark.string('set', 'А'.repeat(16), 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create 'abcdefABCDEF'",
+  njs_str("benchmark.string('create', 'abcdef', 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create 'АБВГДЕ'",
+  njs_str("benchmark.string('create', 'АБВГДЕ', 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create 'x'.repeat(24)",
+  njs_str("benchmark.string('create', 'x'.repeat(32), 100)"),
+  njs_str("undefined"),
+  1 },
+
+{ "string create 'Д'.repeat(12)",
+  njs_str("benchmark.string('create', 'А'.repeat(16), 100)"),
+  njs_str("undefined"),
+  1 },
+
 { "JSON.parse",
   njs_str("JSON.parse('{\"a\":123, \"XXX\":[3,4,null]}').a"),
   njs_str("123"),
@@ -570,3 +650,80 @@ invalid_options:
 
 return EXIT_FAILURE;
 }
+
+
+static njs_int_t
+njs_benchmark_preinit(njs_vm_t *vm)
+{
+njs_benchmark_proto_id = njs_vm_external_prototype(vm,
+   njs_benchmark_external,
+   njs_nitems(njs_benchmark_external));
+if (njs_slow_path(njs_benchmark_proto_id < 0)) {
+njs_printf("njs_vm_external_prototype() failed\n");
+return NJS_ERROR;
+}
+
+return NJS_OK;
+}
+
+
+static njs_int_t
+njs_benchmark_init(njs_vm_t *vm)
+{
+njs_int_t   ret;
+njs_opaque_value_t  value;
+
+static const njs_str_t  benchmark = njs_str("benchmark");
+
+ret = njs_vm_external_create(vm, njs_value_arg(),
+ njs_benchmark_proto_id, NULL, 1);
+if (njs_slow_path(ret != NJS_OK)) {
+return NJS_ERROR;
+}
+
+ret = njs_vm_bind(vm, , njs_value_arg(), 1);
+if (njs_slow_path(ret != NJS_OK)) {
+njs_printf("njs_vm_bind() failed\n");
+return NJS_ERROR;
+}
+
+return NJS_OK;
+}
+
+
+static njs_int_t
+njs_benchmark_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+njs_index_t unused, njs_value_t *retval)
+{
+int64_t  i, n;
+njs_str_ts, mode;
+njs_value_t  value;
+
+njs_value_string_get(njs_arg(args, nargs, 1), );
+
+njs_value_string_get(njs_arg(args, nargs, 2), );
+
+if (njs_value_to_integer(vm, njs_arg(args, nar

[njs] Configure: fixed QuickJS detection with --with-quickjs flag.

2024-05-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/02369792b032
branches:  
changeset: 2326:02369792b032
user:  Dmitry Volyntsev 
date:  Thu May 09 12:58:57 2024 -0700
description:
Configure: fixed QuickJS detection with --with-quickjs flag.

diffstat:

 auto/quickjs |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r f146b5dc21cc -r 02369792b032 auto/quickjs
--- a/auto/quickjs  Wed May 01 17:31:01 2024 -0700
+++ b/auto/quickjs  Thu May 09 12:58:57 2024 -0700
@@ -81,7 +81,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
 NJS_LIB_AUX_LIBS="$NJS_LIB_AUX_LIBS $njs_feature_libs"
 fi
 
-if [ $NJS_QUICKJS = YES -a $njs_found = no ]; then
+if [ $NJS_QUICKJS = YES -a $NJS_HAVE_QUICKJS = NO ]; then
 echo
 echo $0: error: no QuickJS library found.
 echo
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] QuickJS: added zlib module.

2024-05-01 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f146b5dc21cc
branches:  
changeset: 2325:f146b5dc21cc
user:  Dmitry Volyntsev 
date:  Wed May 01 17:31:01 2024 -0700
description:
QuickJS: added zlib module.

diffstat:

 auto/init  | 1 +
 auto/make  |42 +-
 auto/qjs_module| 6 +
 auto/qjs_modules   |20 +
 auto/quickjs   |21 +
 auto/sources   | 4 +
 configure  | 3 +-
 external/njs_shell.c   |15 +-
 external/qjs_zlib_module.c |   512 +++
 src/qjs.c  |   109 
 src/qjs.h  |79 ++
 src/qjs_buffer.c   |  1174 
 src/test/njs_unit_test.c   |   301 ---
 test/buffer.t.js   |   236 
 test/harness/runTsuite.js  |10 +-
 test/setup | 2 +-
 test/zlib.t.mjs|   109 
 17 files changed, 2322 insertions(+), 322 deletions(-)

diffs (truncated from 2828 to 1000 lines):

diff -r 18fc657411ca -r f146b5dc21cc auto/init
--- a/auto/init Fri Apr 26 16:48:19 2024 -0700
+++ b/auto/init Wed May 01 17:31:01 2024 -0700
@@ -16,6 +16,7 @@ NJS_CFLAGS=${NJS_CFLAGS=}
 NJS_BUILD_DIR=${NJS_BUILD_DIR:-build}
 
 NJS_LIB_MODULES=
+QJS_LIB_MODULES=
 
 NJS_LIBRT=
 
diff -r 18fc657411ca -r f146b5dc21cc auto/make
--- a/auto/make Fri Apr 26 16:48:19 2024 -0700
+++ b/auto/make Wed May 01 17:31:01 2024 -0700
@@ -15,11 +15,6 @@ njs_modules_c=$NJS_BUILD_DIR/njs_modules
 
 NJS_LIB_SRCS="$NJS_LIB_SRCS $njs_modules_c"
 
-njs_incs=`echo $NJS_LIB_INCS \
-| sed -e "s# *\([^ ]*\)#$njs_regex_cont-I\1#g"`
-njs_objs=`echo $NJS_LIB_SRCS \
-| sed -e "s# *\([^ ]*\.\)c#$NJS_BUILD_DIR/\1o$njs_regex_cont#g"`
-
 cat << END> $njs_modules_c
 
 #include 
@@ -45,6 +40,43 @@ cat << END  
 
 END
 
+if [ $NJS_HAVE_QUICKJS = YES ]; then
+
+qjs_modules_c=$NJS_BUILD_DIR/qjs_modules.c
+
+NJS_LIB_SRCS="$NJS_LIB_SRCS $qjs_modules_c"
+
+cat << END> $qjs_modules_c
+
+#include 
+
+END
+
+for mod in $QJS_LIB_MODULES
+do
+echo "extern qjs_module_t  $mod;" >> $qjs_modules_c
+done
+
+echo  >> $qjs_modules_c
+echo 'qjs_module_t *qjs_modules[] = {'>> $qjs_modules_c
+
+for mod in $QJS_LIB_MODULES
+do
+echo "&$mod," >> $qjs_modules_c
+done
+
+cat << END>> $qjs_modules_c
+NULL
+};
+
+END
+fi
+
+njs_incs=`echo $NJS_LIB_INCS \
+| sed -e "s# *\([^ ]*\)#$njs_regex_cont-I\1#g"`
+njs_objs=`echo $NJS_LIB_SRCS \
+| sed -e "s# *\([^ ]*\.\)c#$NJS_BUILD_DIR/\1o$njs_regex_cont#g"`
+
 cat << END > $NJS_MAKEFILE
 
 # This file is auto-generated by configure
diff -r 18fc657411ca -r f146b5dc21cc auto/qjs_module
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/auto/qjs_module   Wed May 01 17:31:01 2024 -0700
@@ -0,0 +1,6 @@
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) F5, Inc
+
+QJS_LIB_MODULES="$QJS_LIB_MODULES $njs_module_name"
+NJS_LIB_SRCS="$NJS_LIB_SRCS $njs_module_srcs"
+NJS_LIB_INCS="$NJS_LIB_INCS $njs_module_incs"
diff -r 18fc657411ca -r f146b5dc21cc auto/qjs_modules
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/auto/qjs_modules  Wed May 01 17:31:01 2024 -0700
@@ -0,0 +1,20 @@
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) F5, Inc
+
+if [ $NJS_HAVE_QUICKJS = YES ]; then
+
+njs_module_name=qjs_buffer_module
+njs_module_incs=
+njs_module_srcs=src/qjs_buffer.c
+
+. auto/qjs_module
+
+if [ $NJS_ZLIB = YES -a $NJS_HAVE_ZLIB = YES ]; then
+njs_module_name=qjs_zlib_module
+njs_module_incs=
+njs_module_srcs=external/qjs_zlib_module.c
+
+. auto/qjs_module
+fi
+
+fi
diff -r 18fc657411ca -r f146b5dc21cc auto/quickjs
--- a/auto/quickjs  Fri Apr 26 16:48:19 2024 -0700
+++ b/auto/quickjs  Wed May 01 17:31:01 2024 -0700
@@ -25,6 +25,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
   JSRuntime *rt;
 
   rt = JS_NewRuntime();
+  (void) JS_GetClassID;
   JS_FreeRuntime(rt);
   return 0;
  }"
@@ -54,6 +55,26 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
 fi
 
 if [ $njs_found = yes ]; then
+
+njs_feature="QuickJS JS_NewTypedArray()"
+njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored 
\"-Wcast-function-type\"
+  #endif
+
+  #include 
+

[njs] Tests: fixed typo in stream_js_dup_set.t introduced in be271e8d0b3b.

2024-04-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/18fc657411ca
branches:  
changeset: 2324:18fc657411ca
user:  Dmitry Volyntsev 
date:  Fri Apr 26 16:48:19 2024 -0700
description:
Tests: fixed typo in stream_js_dup_set.t introduced in be271e8d0b3b.

Previously, with typo the test was always skipped.

diffstat:

 nginx/t/stream_js_dup_set.t |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r 7456fe29ac0a -r 18fc657411ca nginx/t/stream_js_dup_set.t
--- a/nginx/t/stream_js_dup_set.t   Fri Apr 26 16:48:17 2024 -0700
+++ b/nginx/t/stream_js_dup_set.t   Fri Apr 26 16:48:19 2024 -0700
@@ -46,7 +46,7 @@ stream {
 
 server {
 listen  127.0.0.1:8082;
-js_set $test test.foo1;
+js_set $test test.foo;
 return  8082:$test;
 }
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fetch: fixed request Host header when the port is non-standard.

2024-04-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/7456fe29ac0a
branches:  
changeset: 2323:7456fe29ac0a
user:  Dmitry Volyntsev 
date:  Fri Apr 26 16:48:17 2024 -0700
description:
Fetch: fixed request Host header when the port is non-standard.

This fixes #707 issue on Github.

diffstat:

 nginx/ngx_js_fetch.c|   5 +++
 nginx/t/js_fetch_resolver.t |  69 
 2 files changed, 67 insertions(+), 7 deletions(-)

diffs (122 lines):

diff -r 622387b5b612 -r 7456fe29ac0a nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c  Fri Apr 26 16:27:52 2024 -0700
+++ b/nginx/ngx_js_fetch.c  Fri Apr 26 16:48:17 2024 -0700
@@ -786,6 +786,11 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value
 if (!has_host) {
 njs_chb_append_literal(>chain, "Host: ");
 njs_chb_append(>chain, u.host.data, u.host.len);
+
+if (!u.no_port) {
+njs_chb_sprintf(>chain, 32, ":%d", u.port);
+}
+
 njs_chb_append_literal(>chain, CRLF);
 }
 
diff -r 622387b5b612 -r 7456fe29ac0a nginx/t/js_fetch_resolver.t
--- a/nginx/t/js_fetch_resolver.t   Fri Apr 26 16:27:52 2024 -0700
+++ b/nginx/t/js_fetch_resolver.t   Fri Apr 26 16:48:17 2024 -0700
@@ -65,6 +65,23 @@ http {
 location /loc {
 js_content test.loc;
 }
+
+location /host {
+return 200 8080:$http_host;
+}
+}
+
+server {
+listen   127.0.0.1:8081;
+server_name  aaa;
+
+location /loc {
+js_content test.loc;
+}
+
+location /host {
+return 200 8081:$http_host;
+}
 }
 
 server {
@@ -80,19 +97,29 @@ http {
 EOF
 
 my $p0 = port(8080);
+my $p1 = port(8081);
 
 $t->write_file('test.js', <http://\${r.args.domain}:$p0/loc`;
+const p0 = $p0;
+const p1 = $p1;
+
+async function dns(r) {
+var port = r.args.port == undefined || r.args.port == 'p0' ? p0 : p1;
+var loc = r.args.loc == undefined ? 'loc' : r.args.loc;
+var url = `http://\${r.args.domain}:\${port}/\${loc}`;
 
-ngx.fetch(url)
-.then(reply => reply.text())
-.then(body => r.return(200, body))
-.catch(e => r.return(501, e.message))
+try {
+let reply = await ngx.fetch(url);
+let body = await reply.text();
+r.return(200, body);
+
+} catch (e) {
+r.return(501, e.message);
+}
 }
 
 function str(v) { return v ? v : ''};
@@ -109,7 +136,7 @@ my $p0 = port(8080);
  export default {njs: test_njs, dns, loc};
 EOF
 
-$t->try_run('no njs.fetch')->plan(3);
+$t->try_run('no njs.fetch')->plan(5);
 
 $t->run_daemon(\_daemon, port(8981), $t);
 $t->waitforfile($t->testdir . '/' . port(8981));
@@ -121,6 +148,34 @@ like(http_get('/dns?domain=many'), qr/ma
 like(http_get('/dns?domain=unknown'), qr/"unknown" could not be resolved/s,
'fetch dns unknown');
 
+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.5');
+
+like(http_get('/dns?domain=aaa=p0=host'), qr/8080:aaa:$p0$/s,
+   'fetch aaa:8080');
+like(http_get('/dns?domain=aaa=p1=host'), qr/8081:aaa:$p1$/s,
+   'fetch aaa:8081');
+}
+
+###
+
+sub has_version {
+   my $need = shift;
+
+   http_get('/njs') =~ /^([.0-9]+)$/m;
+
+   my @v = split(/\./, $1);
+   my ($n, $v);
+
+   for $n (split(/\./, $need)) {
+   $v = shift @v || 0;
+   return 0 if $n > $v;
+   return 1 if $v > $n;
+   }
+
+   return 1;
+}
+
 ###
 
 sub reply_handler {
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Allowing to use custom allocator in njs_chb_t.

2024-04-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/622387b5b612
branches:  
changeset: 2322:622387b5b612
user:  Dmitry Volyntsev 
date:  Fri Apr 26 16:27:52 2024 -0700
description:
Allowing to use custom allocator in njs_chb_t.

diffstat:

 external/njs_query_string_module.c |   6 +++---
 external/njs_xml_module.c  |   2 +-
 external/njs_zlib_module.c |   4 ++--
 nginx/ngx_js_fetch.c   |   6 +++---
 src/njs_array.c|   2 +-
 src/njs_chb.c  |  21 +
 src/njs_chb.h  |  27 ---
 src/njs_error.c|   2 +-
 src/njs_function.c |   2 +-
 src/njs_json.c |   4 ++--
 src/njs_regexp.c   |   2 +-
 src/njs_string.c   |   8 
 src/njs_typed_array.c  |   2 +-
 src/njs_vm.c   |   2 +-
 src/test/njs_unit_test.c   |   2 +-
 15 files changed, 55 insertions(+), 37 deletions(-)

diffs (347 lines):

diff -r a97a9f3b3cea -r 622387b5b612 external/njs_query_string_module.c
--- a/external/njs_query_string_module.cMon Apr 22 18:59:03 2024 -0700
+++ b/external/njs_query_string_module.cFri Apr 26 16:27:52 2024 -0700
@@ -152,7 +152,7 @@ njs_query_string_decode(njs_vm_t *vm, nj
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 };
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 njs_utf8_decode_init();
 
 cp = 0;
@@ -749,7 +749,7 @@ njs_query_string_stringify(njs_vm_t *vm,
 encode = njs_value_function(val);
 }
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 
 keys = njs_vm_object_keys(vm, object, njs_value_arg());
 if (njs_slow_path(keys == NULL)) {
@@ -841,7 +841,7 @@ njs_query_string_escape(njs_vm_t *vm, nj
 
 njs_value_string_get(string, );
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 
 ret = njs_query_string_encode(, );
 if (njs_slow_path(ret != NJS_OK)) {
diff -r a97a9f3b3cea -r 622387b5b612 external/njs_xml_module.c
--- a/external/njs_xml_module.c Mon Apr 22 18:59:03 2024 -0700
+++ b/external/njs_xml_module.c Fri Apr 26 16:27:52 2024 -0700
@@ -1788,7 +1788,7 @@ njs_xml_ext_canonicalization(njs_vm_t *v
 }
 }
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 
 buf = xmlOutputBufferCreateIO(njs_xml_buf_write_cb, NULL, , NULL);
 if (njs_slow_path(buf == NULL)) {
diff -r a97a9f3b3cea -r 622387b5b612 external/njs_zlib_module.c
--- a/external/njs_zlib_module.cMon Apr 22 18:59:03 2024 -0700
+++ b/external/njs_zlib_module.cFri Apr 26 16:27:52 2024 -0700
@@ -320,7 +320,7 @@ njs_zlib_ext_deflate(njs_vm_t *vm, njs_v
 }
 }
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 
 do {
 stream.next_out = njs_chb_reserve(, chunk_size);
@@ -461,7 +461,7 @@ njs_zlib_ext_inflate(njs_vm_t *vm, njs_v
 }
 }
 
-njs_chb_init(, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(, vm);
 
 while (rc != Z_STREAM_END) {
 stream.next_out = njs_chb_reserve(, chunk_size);
diff -r a97a9f3b3cea -r 622387b5b612 nginx/ngx_js_fetch.c
--- a/nginx/ngx_js_fetch.c  Mon Apr 22 18:59:03 2024 -0700
+++ b/nginx/ngx_js_fetch.c  Fri Apr 26 16:27:52 2024 -0700
@@ -740,7 +740,7 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value
 
 http->header_only = njs_strstr_eq(, _str_value("HEAD"));
 
-njs_chb_init(>chain, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(>chain, vm);
 
 njs_chb_append(>chain, request.method.start, request.method.length);
 njs_chb_append_literal(>chain, " ");
@@ -1051,7 +1051,7 @@ ngx_js_ext_response_constructor(njs_vm_t
 }
 }
 
-njs_chb_init(>chain, njs_vm_memory_pool(vm));
+NJS_CHB_MP_INIT(>chain, vm);
 
 body = njs_arg(args, nargs, 1);
 
@@ -2468,7 +2468,7 @@ ngx_js_http_process_headers(ngx_js_http_
 
 njs_chb_destroy(>chain);
 
-njs_chb_init(>response.chain, njs_vm_memory_pool(http->vm));
+NJS_CHB_MP_INIT(>response.chain, http->vm);
 
 http->process = ngx_js_http_process_body;
 
diff -r a97a9f3b3cea -r 622387b5b612 src/njs_array.c
--- a/src/njs_array.c   Mon Apr 22 18:59:03 2024 -0700
+++ b/src/njs_array.c   Fri Apr 26 16:27:52 2024 -0700
@@ -1698,7 +1698,7 @@ njs_array_prototype_join(njs_vm_t *vm, n
 
 value = 
 
-njs_chb_init(, vm->mem_pool);
+NJS_CHB_MP_INIT(, vm);
 
 for (i = 0; i < len; i++) {
 ret = njs_value_property_i64(vm, this, i, value);
diff -r a97a9f3b3cea -r 622387b5b612 src/njs_chb.c
--- a/src/njs_chb.c Mon Apr 22 18:59:03 2024 -0700
+++ b/src/njs_chb.c Fri Apr 26 16:27:52 2024 -0700
@@ -12,6 +12,19 @@
 
 
 void
+njs_chb_init(njs_chb_t *chain, void *pool, njs_chb_alloc_t alloc,
+njs_chb_free_t free)
+{
+chain->error = 0;
+ch

[njs] Configure: fixed default path QuickJS discovery typo.

2024-04-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/a97a9f3b3cea
branches:  
changeset: 2321:a97a9f3b3cea
user:  Dmitry Volyntsev 
date:  Mon Apr 22 18:59:03 2024 -0700
description:
Configure: fixed default path QuickJS discovery typo.

The issue was introduced in 1c8b6b9bc06c (0.8.4).

This closes #706 issue on Github.

diffstat:

 auto/quickjs |  4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diffs (21 lines):

diff -r 0cb259f67ade -r a97a9f3b3cea auto/quickjs
--- a/auto/quickjs  Mon Apr 22 17:52:14 2024 -0700
+++ b/auto/quickjs  Mon Apr 22 18:59:03 2024 -0700
@@ -40,7 +40,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
 if [ $njs_found = no ]; then
 njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs.lto"
 njs_feature_incs="/usr/include/quickjs/"
-njs_feature_libs="-L/usr/lib/quickjs/ -lquijs.lto -lm -ldl -lpthread"
+njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs.lto -lm -ldl -lpthread"
 
 . auto/feature
 fi
@@ -48,7 +48,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
 if [ $njs_found = no ]; then
 njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs"
 njs_feature_incs="/usr/include/quickjs/"
-njs_feature_libs="-L/usr/lib/quickjs/ -lquijs -lm -ldl -lpthread"
+njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs -lm -ldl -lpthread"
 
 . auto/feature
 fi
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Zlib: improved tests with zlib-ng.

2024-04-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/0cb259f67ade
branches:  
changeset: 2320:0cb259f67ade
user:  Dmitry Volyntsev 
date:  Mon Apr 22 17:52:14 2024 -0700
description:
Zlib: improved tests with zlib-ng.

This fixes #704 issue on Github.

diffstat:

 src/test/njs_unit_test.c |  13 +++--
 1 files changed, 7 insertions(+), 6 deletions(-)

diffs (25 lines):

diff -r d640adf691a7 -r 0cb259f67ade src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Mon Apr 22 17:52:06 2024 -0700
+++ b/src/test/njs_unit_test.c  Mon Apr 22 17:52:14 2024 -0700
@@ -22319,14 +22319,15 @@ static njs_unit_test_t  njs_zlib_test[] 
   njs_str("WAKA,αβγ") },
 
 { njs_str("const zlib = require('zlib');"
-  "['WAKA', 'αβγ']"
-  ".map(v => zlib.deflateRawSync(v).toString('base64'))"),
-  njs_str("C3f0dgQA,O7fx3KZzmwE=") },
+  "const enc = ['WAKA', 'αβγ'].map(v => 
zlib.deflateRawSync(v).toString('base64'));"
+  "enc.map(v => zlib.inflateRawSync(Buffer.from(v, 
'base64')).toString())"),
+  njs_str("WAKA,αβγ") },
 
 { njs_str("const zlib = require('zlib');"
-  "['WAKA', 'αβγ']"
-  ".map(v => zlib.deflateRawSync(v, {dictionary: 
Buffer.from('WAKA')}).toString('base64'))"),
-  njs_str("CwdiAA==,O7fx3KZzmwE=") },
+  "const enc = ['WAKA', 'αβγ']"
+  ".map(v => zlib.deflateRawSync(v, {dictionary: 
Buffer.from('WAKA')}).toString('base64'));"
+  "enc.map(v => zlib.inflateRawSync(Buffer.from(v, 'base64'), 
{dictionary: Buffer.from('WAKA')}))"),
+  njs_str("WAKA,αβγ") },
 
 { njs_str("const zlib = require('zlib');"
   "['WAKA', 'αβγ']"
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Zlib: fixed inflate().

2024-04-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/d640adf691a7
branches:  
changeset: 2319:d640adf691a7
user:  Dmitry Volyntsev 
date:  Mon Apr 22 17:52:06 2024 -0700
description:
Zlib: fixed inflate().

Previously, the function might fail to return the last part of the
compressed content. This problem is more visible when output size > 1024
or when chunkSize < the content size.

diffstat:

 external/njs_zlib_module.c |  2 +-
 src/test/njs_unit_test.c   |  7 +++
 2 files changed, 8 insertions(+), 1 deletions(-)

diffs (29 lines):

diff -r be271e8d0b3b -r d640adf691a7 external/njs_zlib_module.c
--- a/external/njs_zlib_module.cMon Apr 22 17:51:45 2024 -0700
+++ b/external/njs_zlib_module.cMon Apr 22 17:52:06 2024 -0700
@@ -463,7 +463,7 @@ njs_zlib_ext_inflate(njs_vm_t *vm, njs_v
 
 njs_chb_init(, njs_vm_memory_pool(vm));
 
-while (stream.avail_in > 0) {
+while (rc != Z_STREAM_END) {
 stream.next_out = njs_chb_reserve(, chunk_size);
 if (njs_slow_path(stream.next_out == NULL)) {
 njs_vm_memory_error(vm);
diff -r be271e8d0b3b -r d640adf691a7 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Mon Apr 22 17:51:45 2024 -0700
+++ b/src/test/njs_unit_test.c  Mon Apr 22 17:52:06 2024 -0700
@@ -22352,6 +22352,13 @@ static njs_unit_test_t  njs_zlib_test[] 
   njs_str("eJwLd/R2BAAC+gEl,eJw7t/HcpnObAQ/sBIE=") },
 
 { njs_str("const zlib = require('zlib');"
+  "const buf = 'αβγ'.repeat(56);"
+  "const enc = zlib.deflateRawSync(buf, 
{chunkSize:64}).toString('base64');"
+  "const dec = zlib.inflateRawSync(Buffer.from(enc, 
'base64')).toString();"
+  "buf == dec"),
+  njs_str("true") },
+
+{ njs_str("const zlib = require('zlib');"
   "['WAKA'.repeat(1024), 'αβγ'.repeat(1024)]"
   ".map(v => [v, zlib.deflateRawSync(v).toString('base64')])"
   ".every(pair => pair[0] == 
zlib.inflateRawSync(Buffer.from(pair[1], 'base64')).toString())"),
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Modules: improved checking for duplicate js_set variables.

2024-04-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/be271e8d0b3b
branches:  
changeset: 2318:be271e8d0b3b
user:  Dmitry Volyntsev 
date:  Mon Apr 22 17:51:45 2024 -0700
description:
Modules: improved checking for duplicate js_set variables.

Since 6fb1aca4eeaf (0.8.4) the identical js_set variables introduced as
a part of an include file that is shared amongst multiple vhosts are
rejected during configuration parsing.

The patch ignores duplicate js_set variables when they refer to the same
JS function.

This fixes #705 issue on Github.

diffstat:

 nginx/ngx_http_js_module.c   |  15 ++--
 nginx/ngx_stream_js_module.c |  15 ++--
 nginx/t/js_dup_set.t |  74 
 nginx/t/stream_js_dup_set.t  |  72 ++
 4 files changed, 168 insertions(+), 8 deletions(-)

diffs (218 lines):

diff -r b73f99c7bc54 -r be271e8d0b3b nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cMon Apr 22 17:51:24 2024 -0700
+++ b/nginx/ngx_http_js_module.cMon Apr 22 17:51:45 2024 -0700
@@ -4732,7 +4732,7 @@ invalid:
 static char *
 ngx_http_js_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
-ngx_str_t*value, *fname;
+ngx_str_t*value, *fname, *prev;
 ngx_http_variable_t  *v;
 
 value = cf->args->elts;
@@ -4759,9 +4759,16 @@ ngx_http_js_set(ngx_conf_t *cf, ngx_comm
 *fname = value[2];
 
 if (v->get_handler == ngx_http_js_variable_set) {
-ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-   "variable \"%V\" is already declared", [1]);
-return NGX_CONF_ERROR;
+prev = (ngx_str_t *) v->data;
+
+if (fname->len != prev->len
+|| ngx_strncmp(fname->data, prev->data, fname->len) != 0)
+{
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "variable \"%V\" is redeclared with "
+   "different function name", [1]);
+return NGX_CONF_ERROR;
+}
 }
 
 v->get_handler = ngx_http_js_variable_set;
diff -r b73f99c7bc54 -r be271e8d0b3b nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c  Mon Apr 22 17:51:24 2024 -0700
+++ b/nginx/ngx_stream_js_module.c  Mon Apr 22 17:51:45 2024 -0700
@@ -2191,7 +2191,7 @@ invalid:
 static char *
 ngx_stream_js_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
-ngx_str_t  *value, *fname;
+ngx_str_t  *value, *fname, *prev;
 ngx_stream_variable_t  *v;
 
 value = cf->args->elts;
@@ -2218,9 +2218,16 @@ ngx_stream_js_set(ngx_conf_t *cf, ngx_co
 *fname = value[2];
 
 if (v->get_handler == ngx_stream_js_variable_set) {
-ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-   "variable \"%V\" is already declared", [1]);
-return NGX_CONF_ERROR;
+prev = (ngx_str_t *) v->data;
+
+if (fname->len != prev->len
+|| ngx_strncmp(fname->data, prev->data, fname->len) != 0)
+{
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "variable \"%V\" is redeclared with "
+   "different function name", [1]);
+return NGX_CONF_ERROR;
+}
 }
 
 v->get_handler = ngx_stream_js_variable_set;
diff -r b73f99c7bc54 -r be271e8d0b3b nginx/t/js_dup_set.t
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/nginx/t/js_dup_set.t  Mon Apr 22 17:51:45 2024 -0700
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (C) Nginx, Inc.
+
+# Tests for http njs module, duplicate identical js_set directives.
+
+###
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+
+###
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/http/)
+   ->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+http {
+%%TEST_GLOBALS_HTTP%%
+
+js_import test.js;
+
+server {
+listen   127.0.0.1:8080;
+server_name  localhost;
+
+location /set1 {
+js_set $test test.foo;
+return 200 set1:$test;
+}
+
+location /set2 {
+js_set $test test.foo;
+return 200 set2:$test;
+}
+}
+}
+
+EOF
+
+$t->write_file('test.js', <try_run('no njs')->plan(2);
+
+###
+
+like(http_get('/set1'), qr/set1:42/, '/set1 location');
+like(http_get('/set2'), qr/set2:42/, '/set2 location');
+
+#

[njs] Version bump.

2024-04-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/b73f99c7bc54
branches:  
changeset: 2317:b73f99c7bc54
user:  Dmitry Volyntsev 
date:  Mon Apr 22 17:51:24 2024 -0700
description:
Version bump.

diffstat:

 src/njs.h |  4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diffs (14 lines):

diff -r 7133f0400019 -r b73f99c7bc54 src/njs.h
--- a/src/njs.h Mon Apr 15 16:44:33 2024 -0700
+++ b/src/njs.h Mon Apr 22 17:51:24 2024 -0700
@@ -11,8 +11,8 @@
 
 #include 
 
-#define NJS_VERSION "0.8.4"
-#define NJS_VERSION_NUMBER  0x000804
+#define NJS_VERSION "0.8.5"
+#define NJS_VERSION_NUMBER  0x000805
 
 
 #include 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


njs-0.8.4

2024-04-16 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

This release introduced the initial QuickJS engine support in CLI
as well as regular bugfixes.

Notable new features:
- QuickJS in njs CLI:
: $ ./configure --cc-opt="-I/path/to/quickjs -L/path/to/quickjs" && make njs
: $ ./build/njs -n QuickJS
:
: >> new Map()
: [object Map]

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues
- Mailing list:
  https://mailman.nginx.org/mailman/listinfo/nginx-devel

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.4   16 Apr 2024

    nginx modules:

    *) Feature: allowing to set Server header for outgoing headers.

    *) Improvement: validating URI and args arguments in r.subrequest().

    *) Improvement: checking for duplicate js_set variables.

    *) Bugfix: fixed clear() method of a shared dictionary without
   timeout introduced in 0.8.3.

    *) Bugfix: fixed r.send() with Buffer argument.

    Core:

    *) Feature: added QuickJS engine support in CLI.

    *) Bugfix: fixed atob() with non-padded base64 strings.
___
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx


[nginx-announce] njs-0.8.4

2024-04-16 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

This release introduced the initial QuickJS engine support in CLI
as well as regular bugfixes.

Notable new features:
- QuickJS in njs CLI:
: $ ./configure --cc-opt="-I/path/to/quickjs -L/path/to/quickjs" && make njs
: $ ./build/njs -n QuickJS
:
: >> new Map()
: [object Map]

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues
- Mailing list:
  https://mailman.nginx.org/mailman/listinfo/nginx-devel

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.4   16 Apr 2024

    nginx modules:

    *) Feature: allowing to set Server header for outgoing headers.

    *) Improvement: validating URI and args arguments in r.subrequest().

    *) Improvement: checking for duplicate js_set variables.

    *) Bugfix: fixed clear() method of a shared dictionary without
   timeout introduced in 0.8.3.

    *) Bugfix: fixed r.send() with Buffer argument.

    Core:

    *) Feature: added QuickJS engine support in CLI.

    *) Bugfix: fixed atob() with non-padded base64 strings.
___
nginx-announce mailing list
nginx-announce@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-announce


[njs] Added tag 0.8.4 for changeset 11d956c1577c

2024-04-15 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/7133f0400019
branches:  
changeset: 2316:7133f0400019
user:  Dmitry Volyntsev 
date:  Mon Apr 15 16:44:33 2024 -0700
description:
Added tag 0.8.4 for changeset 11d956c1577c

diffstat:

 .hgtags |  1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diffs (8 lines):

diff -r 11d956c1577c -r 7133f0400019 .hgtags
--- a/.hgtags   Mon Apr 15 16:40:21 2024 -0700
+++ b/.hgtags   Mon Apr 15 16:44:33 2024 -0700
@@ -66,3 +66,4 @@ 0ed1952588ab1e0e1c18425fe7923b2b76f38a65
 a52b49f9afcf410597dc6657ad39ae3dbbfeec56 0.8.1
 45f81882c780a12e56be519cd3106c4fe5567a64 0.8.2
 3aba7ee620807ad10bc34bff3677350fa8a3c3b2 0.8.3
+11d956c1577c91037a2c122d4a9d818a9733562d 0.8.4
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Version 0.8.4.

2024-04-15 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/11d956c1577c
branches:  
changeset: 2315:11d956c1577c
user:  Dmitry Volyntsev 
date:  Mon Apr 15 16:40:21 2024 -0700
description:
Version 0.8.4.

diffstat:

 CHANGES |  21 +
 1 files changed, 21 insertions(+), 0 deletions(-)

diffs (28 lines):

diff -r adaeb3c3f59a -r 11d956c1577c CHANGES
--- a/CHANGES   Mon Apr 08 22:47:28 2024 -0700
+++ b/CHANGES   Mon Apr 15 16:40:21 2024 -0700
@@ -1,3 +1,24 @@
+Changes with njs 0.8.4   16 Apr 2024
+
+nginx modules:
+
+*) Feature: allowing to set Server header for outgoing headers.
+
+*) Improvement: validating URI and args arguments in r.subrequest().
+
+*) Improvement: checking for duplicate js_set variables.
+
+*) Bugfix: fixed clear() method of a shared dictionary without
+   timeout introduced in 0.8.3.
+
+*) Bugfix: fixed r.send() with Buffer argument.
+
+Core:
+
+*) Feature: added QuickJS engine support in CLI.
+
+*) Bugfix: fixed atob() with non-padded base64 strings.
+
 Changes with njs 0.8.3   07 Feb 2024
 
 nginx modules:
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] HTTP: fixed r.send() with Buffer argument.

2024-04-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/adaeb3c3f59a
branches:  
changeset: 2314:adaeb3c3f59a
user:  Dmitry Volyntsev 
date:  Mon Apr 08 22:47:28 2024 -0700
description:
HTTP: fixed r.send() with Buffer argument.

Previously, only string value type was accepted.

This closes #701 issue on Github.

diffstat:

 nginx/ngx_http_js_module.c |  69 ++
 nginx/t/js.t   |  22 +-
 src/njs.h  |   2 -
 src/njs_vm.c   |  41 ---
 4 files changed, 47 insertions(+), 87 deletions(-)

diffs (208 lines):

diff -r 6fb1aca4eeaf -r adaeb3c3f59a nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cMon Apr 08 22:47:24 2024 -0700
+++ b/nginx/ngx_http_js_module.cMon Apr 08 22:47:28 2024 -0700
@@ -2199,10 +2199,8 @@ static njs_int_t
 ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 njs_index_t unused, njs_value_t *retval)
 {
-njs_int_tret;
 njs_str_ts;
 ngx_buf_t   *b;
-uintptr_tnext;
 ngx_uint_t   n;
 ngx_chain_t *out, *cl, **ll;
 ngx_http_js_ctx_t   *ctx;
@@ -2226,47 +2224,34 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_v
 ll = 
 
 for (n = 1; n < nargs; n++) {
-next = 0;
-
-for ( ;; ) {
-ret = njs_vm_value_string_copy(vm, , njs_argument(args, n),
-   );
-
-if (ret == NJS_DECLINED) {
-break;
-}
-
-if (ret == NJS_ERROR) {
-return NJS_ERROR;
-}
-
-if (s.length == 0) {
-continue;
-}
-
-/* TODO: njs_value_release(vm, value) in buf completion */
-
-b = ngx_calloc_buf(r->pool);
-if (b == NULL) {
-return NJS_ERROR;
-}
-
-b->start = s.start;
-b->pos = b->start;
-b->end = s.start + s.length;
-b->last = b->end;
-b->memory = 1;
-
-cl = ngx_alloc_chain_link(r->pool);
-if (cl == NULL) {
-return NJS_ERROR;
-}
-
-cl->buf = b;
-
-*ll = cl;
-ll = >next;
+if (ngx_js_string(vm, njs_argument(args, n), ) != NGX_OK) {
+return NJS_ERROR;
+}
+
+if (s.length == 0) {
+continue;
+}
+
+b = ngx_calloc_buf(r->pool);
+if (b == NULL) {
+return NJS_ERROR;
 }
+
+b->start = s.start;
+b->pos = b->start;
+b->end = s.start + s.length;
+b->last = b->end;
+b->memory = 1;
+
+cl = ngx_alloc_chain_link(r->pool);
+if (cl == NULL) {
+return NJS_ERROR;
+}
+
+cl->buf = b;
+
+*ll = cl;
+ll = >next;
 }
 
 *ll = NULL;
diff -r 6fb1aca4eeaf -r adaeb3c3f59a nginx/t/js.t
--- a/nginx/t/js.t  Mon Apr 08 22:47:24 2024 -0700
+++ b/nginx/t/js.t  Mon Apr 08 22:47:28 2024 -0700
@@ -112,6 +112,10 @@ http {
 js_content test.send;
 }
 
+location /send_buffer {
+js_content test.send_buffer;
+}
+
 location /return_method {
 js_content test.return_method;
 }
@@ -219,6 +223,13 @@ EOF
 r.finish();
 }
 
+function send_buffer(r) {
+r.status = 200;
+r.sendHeader();
+r.send(Buffer.from("send_buffer"));
+r.finish();
+}
+
 function return_method(r) {
 r.return(Number(r.args.c), r.args.t);
 }
@@ -265,11 +276,11 @@ EOF
 variable, global_obj, status, request_body, internal,
 request_body_cache, send, return_method, sub_internal,
 type, log, buffer_variable, except, content_except,
-content_empty};
+content_empty, send_buffer};
 
 EOF
 
-$t->try_run('no njs available')->plan(28);
+$t->try_run('no njs available')->plan(29);
 
 ###
 
@@ -289,6 +300,13 @@ like(http_post_big('/body'), qr/200.*^(1
 like(http_get('/send?foo=12345=11=bar==z'),
qr/n=foo, v=12 n=foo-2, v=ba n=foo-3, v=z/, 'r.send');
 
+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.4');
+
+like(http_get('/send_buffer'), qr/send_buffer/, 'r.send accepts buffer');
+
+}
+
 like(http_get('/return_method?c=200'), qr/200 OK.*\x0d\x0a?\x0d\x0a?$/s,
'return code');
 like(http_get('/return_method?c=200=SEE-THIS'), qr/200 OK.*^SEE-THIS$/ms,
diff -r 6fb1aca4eeaf -r adaeb3c3f59a src/njs.h
--- a/src/njs.h Mon Apr 08 22:47:24 2024 -0700
+++ b/src/njs.h Mon Apr 08 22:47:28 2024 -0700
@@ -412,8 +412,6 @@ NJS_EXPORT njs_int_t njs_vm_value_string
 njs_value_t *value

[njs] Modules: checking for duplicate js_set variables.

2024-04-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/6fb1aca4eeaf
branches:  
changeset: 2313:6fb1aca4eeaf
user:  Dmitry Volyntsev 
date:  Mon Apr 08 22:47:24 2024 -0700
description:
Modules: checking for duplicate js_set variables.

This closes #700 issue on Github.

diffstat:

 nginx/ngx_http_js_module.c   |  6 ++
 nginx/ngx_stream_js_module.c |  6 ++
 2 files changed, 12 insertions(+), 0 deletions(-)

diffs (32 lines):

diff -r 1c8b6b9bc06c -r 6fb1aca4eeaf nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cThu Apr 04 16:07:53 2024 -0700
+++ b/nginx/ngx_http_js_module.cMon Apr 08 22:47:24 2024 -0700
@@ -4773,6 +4773,12 @@ ngx_http_js_set(ngx_conf_t *cf, ngx_comm
 
 *fname = value[2];
 
+if (v->get_handler == ngx_http_js_variable_set) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "variable \"%V\" is already declared", [1]);
+return NGX_CONF_ERROR;
+}
+
 v->get_handler = ngx_http_js_variable_set;
 v->data = (uintptr_t) fname;
 
diff -r 1c8b6b9bc06c -r 6fb1aca4eeaf nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c  Thu Apr 04 16:07:53 2024 -0700
+++ b/nginx/ngx_stream_js_module.c  Mon Apr 08 22:47:24 2024 -0700
@@ -2217,6 +2217,12 @@ ngx_stream_js_set(ngx_conf_t *cf, ngx_co
 
 *fname = value[2];
 
+if (v->get_handler == ngx_stream_js_variable_set) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "variable \"%V\" is already declared", [1]);
+return NGX_CONF_ERROR;
+}
+
 v->get_handler = ngx_stream_js_variable_set;
 v->data = (uintptr_t) fname;
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Configure: added --with-quickjs option.

2024-04-04 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/1c8b6b9bc06c
branches:  
changeset: 2312:1c8b6b9bc06c
user:  Dmitry Volyntsev 
date:  Thu Apr 04 16:07:53 2024 -0700
description:
Configure: added --with-quickjs option.

diffstat:

 auto/help|   1 +
 auto/options |   6 --
 auto/quickjs |  13 ++---
 3 files changed, 15 insertions(+), 5 deletions(-)

diffs (81 lines):

diff -r 834096122cef -r 1c8b6b9bc06c auto/help
--- a/auto/help Thu Apr 04 16:07:46 2024 -0700
+++ b/auto/help Thu Apr 04 16:07:53 2024 -0700
@@ -48,4 +48,5 @@ default: "$NJS_LD_OPT"
   --no-zlib disables zlib discovery. When this option is
 enabled zlib dependant code is not built as a
 part of libnjs.a.
+  --with-quickjsrequires QuickJS engine.
 END
diff -r 834096122cef -r 1c8b6b9bc06c auto/options
--- a/auto/options  Thu Apr 04 16:07:46 2024 -0700
+++ b/auto/options  Thu Apr 04 16:07:53 2024 -0700
@@ -14,7 +14,8 @@ NJS_DEBUG_GENERATOR=NO
 NJS_ADDRESS_SANITIZER=NO
 NJS_ADDR2LINE=NO
 
-NJS_QUICKJS=YES
+NJS_QUICKJS=NO
+NJS_TRY_QUICKJS=YES
 NJS_OPENSSL=YES
 NJS_LIBXML2=YES
 NJS_ZLIB=YES
@@ -48,7 +49,7 @@ do
 --debug-opcode=*)NJS_DEBUG_OPCODE="$value"   ;;
 --debug-generator=*) NJS_DEBUG_GENERATOR="$value";;
 
---no-quickjs)NJS_QUICKJS=NO  ;;
+--no-quickjs)NJS_TRY_QUICKJS=NO  ;;
 --no-openssl)NJS_OPENSSL=NO  ;;
 --no-libxml2)NJS_LIBXML2=NO  ;;
 --no-zlib)   NJS_ZLIB=NO ;;
@@ -57,6 +58,7 @@ do
 --no-pcre2)  NJS_TRY_PCRE2=NO;;
 
 --no-goto)   NJS_TRY_GOTO=NO ;;
+--with-quickjs)  NJS_TRY_QUICKJS=YES; NJS_QUICKJS=YES 
;;
 
 --help)
 . auto/help
diff -r 834096122cef -r 1c8b6b9bc06c auto/quickjs
--- a/auto/quickjs  Thu Apr 04 16:07:46 2024 -0700
+++ b/auto/quickjs  Thu Apr 04 16:07:53 2024 -0700
@@ -6,7 +6,7 @@
 NJS_QUICKJS_LIB=
 NJS_HAVE_QUICKJS=NO
 
-if [ $NJS_QUICKJS = YES ]; then
+if [ $NJS_TRY_QUICKJS = YES ]; then
 njs_found=no
 
 njs_feature="QuickJS library -lquickjs.lto"
@@ -40,7 +40,7 @@ if [ $NJS_QUICKJS = YES ]; then
 if [ $njs_found = no ]; then
 njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs.lto"
 njs_feature_incs="/usr/include/quickjs/"
-njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs.lto -lm -ldl -lpthread"
+njs_feature_libs="-L/usr/lib/quickjs/ -lquijs.lto -lm -ldl -lpthread"
 
 . auto/feature
 fi
@@ -48,7 +48,7 @@ if [ $NJS_QUICKJS = YES ]; then
 if [ $njs_found = no ]; then
 njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs"
 njs_feature_incs="/usr/include/quickjs/"
-njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs -lm -ldl -lpthread"
+njs_feature_libs="-L/usr/lib/quickjs/ -lquijs -lm -ldl -lpthread"
 
 . auto/feature
 fi
@@ -60,4 +60,11 @@ if [ $NJS_QUICKJS = YES ]; then
 NJS_LIB_AUX_LIBS="$NJS_LIB_AUX_LIBS $njs_feature_libs"
 fi
 
+if [ $NJS_QUICKJS = YES -a $njs_found = no ]; then
+echo
+echo $0: error: no QuickJS library found.
+echo
+exit 1;
+fi
+
 fi
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Configure: improved QuickJS discovery.

2024-04-04 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/834096122cef
branches:  
changeset: 2311:834096122cef
user:  Dmitry Volyntsev 
date:  Thu Apr 04 16:07:46 2024 -0700
description:
Configure: improved QuickJS discovery.

At the first try do not assume the exact library and includes location.

diffstat:

 auto/quickjs |  16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diffs (43 lines):

diff -r b83e2ae81937 -r 834096122cef auto/quickjs
--- a/auto/quickjs  Thu Apr 04 16:07:39 2024 -0700
+++ b/auto/quickjs  Thu Apr 04 16:07:46 2024 -0700
@@ -9,11 +9,11 @@ NJS_HAVE_QUICKJS=NO
 if [ $NJS_QUICKJS = YES ]; then
 njs_found=no
 
-njs_feature="QuickJS library"
+njs_feature="QuickJS library -lquickjs.lto"
 njs_feature_name=NJS_HAVE_QUICKJS
 njs_feature_run=yes
 njs_feature_incs=
-njs_feature_libs=""
+njs_feature_libs="-lquickjs.lto -lm -ldl -lpthread"
 njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
   #pragma GCC diagnostic push
   #pragma GCC diagnostic ignored \"-Wcast-function-type\"
@@ -31,7 +31,14 @@ if [ $NJS_QUICKJS = YES ]; then
 . auto/feature
 
 if [ $njs_found = no ]; then
-njs_feature="QuickJS library -lquickjs.lto"
+njs_feature="QuickJS library -lquickjs"
+njs_feature_libs="-lquickjs -lm -ldl -lpthread"
+
+. auto/feature
+fi
+
+if [ $njs_found = no ]; then
+njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs.lto"
 njs_feature_incs="/usr/include/quickjs/"
 njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs.lto -lm -ldl -lpthread"
 
@@ -39,7 +46,8 @@ if [ $NJS_QUICKJS = YES ]; then
 fi
 
 if [ $njs_found = no ]; then
-njs_feature="QuickJS library -lquickjs"
+njs_feature="QuickJS library -I/usr/include/quickjs/ 
-L/usr/lib/quickjs/ -lquickjs"
+njs_feature_incs="/usr/include/quickjs/"
 njs_feature_libs="-L/usr/lib/quickjs/ -lquickjs -lm -ldl -lpthread"
 
 . auto/feature
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Configure: added --no-quickjs description in configure --help.

2024-04-04 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/b83e2ae81937
branches:  
changeset: 2310:b83e2ae81937
user:  Dmitry Volyntsev 
date:  Thu Apr 04 16:07:39 2024 -0700
description:
Configure: added --no-quickjs description in configure --help.

Forgotten in cb3e068a511c.

diffstat:

 auto/help |  1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diffs (11 lines):

diff -r 3a5b8b59cce9 -r b83e2ae81937 auto/help
--- a/auto/help Thu Apr 04 16:07:37 2024 -0700
+++ b/auto/help Thu Apr 04 16:07:39 2024 -0700
@@ -44,6 +44,7 @@ default: "$NJS_LD_OPT"
   --no-pcre2disables PCRE2 discovery for RegExp backend.
 When this option is enabled only PCRE library
 is discovered.
+  --no-quickjs  disables QuickJS engine discovery.
   --no-zlib disables zlib discovery. When this option is
 enabled zlib dependant code is not built as a
 part of libnjs.a.
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Configure: sorted options alphabetically in configure --help.

2024-04-04 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/3a5b8b59cce9
branches:  
changeset: 2309:3a5b8b59cce9
user:  Dmitry Volyntsev 
date:  Thu Apr 04 16:07:37 2024 -0700
description:
Configure: sorted options alphabetically in configure --help.

diffstat:

 auto/help |  68 +++---
 1 files changed, 30 insertions(+), 38 deletions(-)

diffs (85 lines):

diff -r 2d6d9d1e8b8f -r 3a5b8b59cce9 auto/help
--- a/auto/help Tue Apr 02 08:52:56 2024 -0700
+++ b/auto/help Thu Apr 04 16:07:37 2024 -0700
@@ -7,46 +7,15 @@ cat << END
 
 ./configure options:
 
-  --cc=FILE set C compiler filename, default: "$CC"
-  --cc-opt=OPTIONS  set additional C compiler options, \
-default: "$NJS_CC_OPT"
-  --ld-opt=OPTIONS  set additional linker options, \
-default: "$NJS_LD_OPT"
-  --ar=FILE set static linking program, default: "$AR"
-
-  --build-dir=DIR   set build directory, default: "$NJS_BUILD_DIR"
-
-  --no-pcre disables PCRE/PCRE2 discovery for RegExp
-backend. This flag allows to build PCRE/PCRE2
-outside of libnjs.a.  When this option is enabled
-functions described in njs_regex.h are not built.
-Instead this functions are expected to be provided
-while linking.
-
-  --no-pcre2disables PCRE2 discovery for RegExp backend.
-When this option is enabled only PCRE library
-is discovered.
-
-  --no-goto disables computed goto discovery.
-When this option is enabled 'switch' statement
-will be always used in instead of computed goto.
-
-  --no-openssl  disables OpenSSL discovery. When this option is
-enabled OpenSSL dependant code is not built as a
-part of libnjs.a.
-
-  --no-libxml2  disabled libxml2 discovery. When this option is
-enabled libxml2 dependant code is not built as a
-part of libnjs.a.
-
-  --no-zlib disabled zlib discovery. When this option is
-enabled zlib dependant code is not built as a
-part of libnjs.a.
-
+  --addr2line=YES   enables native function symbolization, \
+default: "$NJS_ADDR2LINE"
   --address-sanitizer=YES   enables build with address sanitizer, \
 default: "$NJS_ADDRESS_SANITIZER"
-  --addr2line=YES   enables native function symbolization, \
-default: "$NJS_ADDR2LINE"
+  --ar=FILE sets static linking program, default: "$AR"
+  --build-dir=DIR   sets build directory, default: "$NJS_BUILD_DIR"
+  --cc=FILE sets C compiler filename, default: "$CC"
+  --cc-opt=OPTIONS  sets additional C compiler options, \
+default: "$NJS_CC_OPT"
   --debug=YES   enables additional runtime checks, \
 default: "$NJS_DEBUG"
   --debug-memory=YESenables memory alloc debug, \
@@ -55,4 +24,27 @@ default: "$NJS_DEBUG_MEMORY"
 default: "$NJS_DEBUG_OPCODE"
   --debug-generator=YES enables generator debug, \
 default: "$NJS_DEBUG_GENERATOR"
+  --ld-opt=OPTIONS  sets additional linker options, \
+default: "$NJS_LD_OPT"
+  --no-goto disables computed goto discovery.
+When this option is enabled 'switch' statement
+will be always used in instead of computed goto.
+  --no-libxml2  disables libxml2 discovery. When this option is
+enabled libxml2 dependant code is not built as a
+part of libnjs.a.
+  --no-openssl  disables OpenSSL discovery. When this option is
+enabled OpenSSL dependant code is not built as a
+part of libnjs.a.
+  --no-pcre disables PCRE/PCRE2 discovery for RegExp
+backend. This flag allows to build PCRE/PCRE2
+outside of libnjs.a.  When this option is enabled
+functions described in njs_regex.h are not built.
+Instead this functions are expected to be provided
+while linking.
+  --no-pcre2disables PCRE2 discovery for RegExp backend.
+When this option is enabled only PCRE library
+is discovered.
+  --no-zlib disables zlib discovery. When this option is
+enabled zlib dep

[njs] HTTP: validating URI and args arguments in r.subrequest().

2024-04-02 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/2d6d9d1e8b8f
branches:  
changeset: 2308:2d6d9d1e8b8f
user:  Dmitry Volyntsev 
date:  Tue Apr 02 08:52:56 2024 -0700
description:
HTTP: validating URI and args arguments in r.subrequest().

diffstat:

 nginx/ngx_http_js_module.c |  37 +
 nginx/t/js_subrequests.t   |  40 ++--
 2 files changed, 75 insertions(+), 2 deletions(-)

diffs (138 lines):

diff -r 17af51d42ad9 -r 2d6d9d1e8b8f nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cMon Apr 01 23:13:25 2024 -0700
+++ b/nginx/ngx_http_js_module.cTue Apr 02 08:52:56 2024 -0700
@@ -305,6 +305,9 @@ static char *ngx_http_js_merge_loc_conf(
 static ngx_ssl_t *ngx_http_js_ssl(njs_vm_t *vm, ngx_http_request_t *r);
 static ngx_flag_t ngx_http_js_ssl_verify(njs_vm_t *vm, ngx_http_request_t *r);
 
+static ngx_int_t ngx_http_js_parse_unsafe_uri(ngx_http_request_t *r,
+njs_str_t *uri, njs_str_t *args);
+
 #if (NGX_HTTP_SSL)
 
 static ngx_conf_bitmask_t  ngx_http_js_ssl_protocols[] = {
@@ -3272,6 +3275,11 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
 }
 }
 
+if (ngx_http_js_parse_unsafe_uri(r, _arg, _arg) != NGX_OK) {
+njs_vm_error(vm, "unsafe uri");
+return NJS_ERROR;
+}
+
 arg = njs_arg(args, nargs, 3);
 
 if (callback == NULL && !njs_value_is_undefined(arg)) {
@@ -4979,3 +4987,32 @@ ngx_http_js_ssl_verify(njs_vm_t *vm, ngx
 return 0;
 #endif
 }
+
+
+static ngx_int_t
+ngx_http_js_parse_unsafe_uri(ngx_http_request_t *r, njs_str_t *uri,
+njs_str_t *args)
+{
+ngx_str_t   uri_arg, args_arg;
+ngx_uint_t  flags;
+
+flags = NGX_HTTP_LOG_UNSAFE;
+
+uri_arg.data = uri->start;
+uri_arg.len = uri->length;
+
+args_arg.data = args->start;
+args_arg.len = args->length;
+
+if (ngx_http_parse_unsafe_uri(r, _arg, _arg, ) != NGX_OK) {
+return NGX_ERROR;
+}
+
+uri->start = uri_arg.data;
+uri->length = uri_arg.len;
+
+args->start = args_arg.data;
+args->length = args_arg.len;
+
+return NGX_OK;
+}
diff -r 17af51d42ad9 -r 2d6d9d1e8b8f nginx/t/js_subrequests.t
--- a/nginx/t/js_subrequests.t  Mon Apr 01 23:13:25 2024 -0700
+++ b/nginx/t/js_subrequests.t  Tue Apr 02 08:52:56 2024 -0700
@@ -148,6 +148,10 @@ http {
 js_content test.sr_unavail_pr;
 }
 
+location /sr_unsafe {
+js_content test.sr_unsafe;
+}
+
 location /sr_broken {
 js_content test.sr_broken;
 }
@@ -385,6 +389,11 @@ EOF
 subrequest_fn_pr(req, ['/unavail'], ['uri', 'status']);
 }
 
+function sr_unsafe(r) {
+r.subrequest('../dir');
+r.return(200);
+}
+
 function sr_broken(r) {
 r.subrequest('/daemon/unfinished', reply => {
 r.return(200, JSON.stringify({code:reply.status}));
@@ -498,13 +507,14 @@ EOF
 sr_unavail_pr, sr_broken, sr_too_large, sr_in_sr,
 sr_js_in_subrequest, sr_js_in_subrequest_pr, js_sub,
 sr_in_sr_callback, sr_out_of_order, sr_except_not_a_func,
-sr_uri_except, sr_except_failed_to_convert_options_arg};
+sr_uri_except, sr_except_failed_to_convert_options_arg,
+sr_unsafe};
 
 EOF
 
 $t->write_file('t', '["SEE-THIS"]');
 
-$t->try_run('no njs available')->plan(32);
+$t->try_run('no njs available')->plan(33);
 $t->run_daemon(\_daemon);
 
 ###
@@ -558,6 +568,13 @@ is(get_json('/sr_in_sr_callback'),
'{"e":"subrequest can only be created for the primary request"}',
'subrequest for non-primary request');
 
+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.4');
+
+like(http_get('/sr_unsafe'), qr/500/s, 'unsafe subrequest uri');
+
+}
+
 $t->stop();
 
 ok(index($t->read_file('error.log'), 'callback is not a function') > 0,
@@ -634,3 +651,22 @@ sub http_daemon {
 }
 
 ###
+
+sub has_version {
+   my $need = shift;
+
+   http_get('/njs') =~ /^([.0-9]+)$/m;
+
+   my @v = split(/\./, $1);
+   my ($n, $v);
+
+   for $n (split(/\./, $need)) {
+   $v = shift @v || 0;
+   return 0 if $n > $v;
+   return 1 if $v > $n;
+   }
+
+   return 1;
+}
+
+###
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Tests: adapt stream_js.t to nginx changes.

2024-04-02 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/17af51d42ad9
branches:  
changeset: 2307:17af51d42ad9
user:  Dmitry Volyntsev 
date:  Mon Apr 01 23:13:25 2024 -0700
description:
Tests: adapt stream_js.t to nginx changes.

Make the test more robust against changes in nginx, specifically
cf890df37bb6 (Stream: socket peek in preread phase).

The filter callbacks may be called multiple times by nginx and the exact
number is not specified. The new test avoids relying on the exact number
of calls from nginx.

diffstat:

 nginx/t/stream_js.t |  15 ---
 1 files changed, 8 insertions(+), 7 deletions(-)

diffs (57 lines):

diff -r 454d9c032c60 -r 17af51d42ad9 nginx/t/stream_js.t
--- a/nginx/t/stream_js.t   Mon Apr 01 23:13:24 2024 -0700
+++ b/nginx/t/stream_js.t   Mon Apr 01 23:13:25 2024 -0700
@@ -227,9 +227,10 @@ EOF
 }
 
 var res = '';
+var step = (v) => { if (!res || res[res.length - 1] != v) res += v };
 
 function access_step(s) {
-res += '1';
+step(1);
 
 setTimeout(function() {
 if (s.remoteAddress.match('127.0.0.1')) {
@@ -240,8 +241,8 @@ EOF
 
 function preread_step(s) {
 s.on('upload', function (data) {
-res += '2';
-if (res.length >= 3) {
+step(2);
+if (data.length > 0) {
 s.done();
 }
 });
@@ -249,18 +250,18 @@ EOF
 
 function filter_step(s) {
 s.on('upload', function(data, flags) {
+step(3);
 s.send(data);
-res += '3';
 });
 
 s.on('download', function(data, flags) {
 
 if (!flags.last) {
-res += '4';
+step(4);
 s.send(data);
 
 } else {
-res += '5';
+step(5);
 s.send(res, {last:1});
 s.off('download');
 }
@@ -409,7 +410,7 @@ is(stream('127.0.0.1:' . port(8082))->re
 is(stream('127.0.0.1:' . port(8083))->read(), '', 'stream js unknown 
function');
 is(stream('127.0.0.1:' . port(8084))->read(), 'sess_unk=undefined', 's.unk');
 
-is(stream('127.0.0.1:' . port(8086))->io('0'), '0122345',
+is(stream('127.0.0.1:' . port(8086))->io('0'), '012345',
'async handlers order');
 is(stream('127.0.0.1:' . port(8087))->io('#'), 'OK', 'access_undecided');
 is(stream('127.0.0.1:' . port(8088))->io('#'), 'OK', 'access_allow');
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Tests: adapt stream_js_preload_object.t to nginx changes.

2024-04-02 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/454d9c032c60
branches:  
changeset: 2306:454d9c032c60
user:  Dmitry Volyntsev 
date:  Mon Apr 01 23:13:24 2024 -0700
description:
Tests: adapt stream_js_preload_object.t to nginx changes.

Make the test more robust against changes in nginx, specifically
cf890df37bb6 (Stream: socket peek in preread phase).

The filter callbacks may be called multiple times by nginx and the exact
number is not specified. The new test avoids relying on the exact number
of calls from nginx.

diffstat:

 nginx/t/stream_js_preload_object.t |  21 ++---
 1 files changed, 10 insertions(+), 11 deletions(-)

diffs (56 lines):

diff -r 498b2387ef04 -r 454d9c032c60 nginx/t/stream_js_preload_object.t
--- a/nginx/t/stream_js_preload_object.tMon Apr 01 23:13:23 2024 -0700
+++ b/nginx/t/stream_js_preload_object.tMon Apr 01 23:13:24 2024 -0700
@@ -66,16 +66,17 @@ EOF
 
 $t->write_file('lib.js', <= 3) {
+pup = g1.b[1];
+if (data.length > 0) {
 s.done();
 }
 });
@@ -83,18 +84,16 @@ EOF
 
 function filter(s) {
 s.on('upload', function(data, flags) {
+fup = g1.c.prop[0].a;
 s.send(data);
-res += g1.c.prop[0].a;
 });
 
 s.on('download', function(data, flags) {
-if (!flags.last) {
-res += g1.b[3];
-s.send(data);
+fdown = g1.b[3];
+s.send(data);
 
-} else {
-res += g1.b[4];
-s.send(res, {last:1});
+if (flags.last) {
+s.send(`\${acc}\${pup}\${fup}\${fdown}`, flags);
 s.off('download');
 }
 });
@@ -117,6 +116,6 @@ EOF
 ###
 
 is(stream('127.0.0.1:' . port(8081))->read(), 'element', 'foo.bar.p');
-is(stream('127.0.0.1:' . port(8082))->io('0'), 'x122345', 'lib.access');
+is(stream('127.0.0.1:' . port(8082))->io('0'), 'x1234', 'filter chain');
 
 ###
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Tests: simplified stream_js_import2.t.

2024-04-02 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/498b2387ef04
branches:  
changeset: 2305:498b2387ef04
user:  Dmitry Volyntsev 
date:  Mon Apr 01 23:13:23 2024 -0700
description:
Tests: simplified stream_js_import2.t.

The test should only verify js_import directive in server context
according to its description.

diffstat:

 nginx/t/stream_js_import2.t |  59 +
 1 files changed, 1 insertions(+), 58 deletions(-)

diffs (81 lines):

diff -r e16e93f43303 -r 498b2387ef04 nginx/t/stream_js_import2.t
--- a/nginx/t/stream_js_import2.t   Mon Apr 01 23:13:21 2024 -0700
+++ b/nginx/t/stream_js_import2.t   Mon Apr 01 23:13:23 2024 -0700
@@ -42,76 +42,19 @@ stream {
 js_set $test foo.bar.p;
 return  $test;
 }
-
-server {
-listen  127.0.0.1:8082;
-
-js_import lib.js;
-
-js_access   lib.access;
-js_preread  lib.preread;
-js_filter   lib.filter;
-proxy_pass  127.0.0.1:8083;
-}
-
-server {
-listen  127.0.0.1:8083;
-return  "x";
-}
 }
 
 EOF
 
-$t->write_file('lib.js', <= 3) {
-s.done();
-}
-});
-}
-
-function filter(s) {
-s.on('upload', function(data, flags) {
-s.send(data);
-res += '3';
-});
-
-s.on('download', function(data, flags) {
-if (!flags.last) {
-res += '4';
-s.send(data);
-
-} else {
-res += '5';
-s.send(res, {last:1});
-s.off('download');
-}
-});
-}
-
-export default {access, preread, filter};
-
-EOF
-
 $t->write_file('main.js', <try_run('no njs available')->plan(2);
+$t->try_run('no njs available')->plan(1);
 
 ###
 
 is(stream('127.0.0.1:' . port(8081))->read(), 'P-TEST', 'foo.bar.p');
-is(stream('127.0.0.1:' . port(8082))->io('0'), 'x122345', 'lib.access');
 
 ###
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Tests: removed stream_js_import.t.

2024-04-02 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/e16e93f43303
branches:  
changeset: 2304:e16e93f43303
user:  Dmitry Volyntsev 
date:  Mon Apr 01 23:13:21 2024 -0700
description:
Tests: removed stream_js_import.t.

js_import is the only directive to load JS code since 0.7.1, so the test is
redundant.

diffstat:

 nginx/t/stream_js_import.t |  117 -
 1 files changed, 0 insertions(+), 117 deletions(-)

diffs (121 lines):

diff -r f632fe16ba05 -r e16e93f43303 nginx/t/stream_js_import.t
--- a/nginx/t/stream_js_import.tTue Mar 19 21:05:51 2024 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,117 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Dmitry Volyntsev
-# (C) Nginx, Inc.
-
-# Tests for stream njs module, js_import directive.
-
-###
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::Stream qw/ stream /;
-
-###
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-my $t = Test::Nginx->new()->has(qw/http stream stream_return/)
-   ->write_file_expand('nginx.conf', <<'EOF');
-
-%%TEST_GLOBALS%%
-
-daemon off;
-
-events {
-}
-
-stream {
-%%TEST_GLOBALS_STREAM%%
-
-js_set $test foo.bar.p;
-
-js_import lib.js;
-js_import foo from ./main.js;
-
-server {
-listen  127.0.0.1:8081;
-return  $test;
-}
-
-server {
-listen  127.0.0.1:8082;
-js_access   lib.access;
-js_preread  lib.preread;
-js_filter   lib.filter;
-proxy_pass  127.0.0.1:8083;
-}
-
-server {
-listen  127.0.0.1:8083;
-return  "x";
-}
-}
-
-EOF
-
-$t->write_file('lib.js', <= 3) {
-s.done();
-}
-});
-}
-
-function filter(s) {
-s.on('upload', function(data, flags) {
-s.send(data);
-res += '3';
-});
-
-s.on('download', function(data, flags) {
-if (!flags.last) {
-res += '4';
-s.send(data);
-
-} else {
-res += '5';
-s.send(res, {last:1});
-s.off('download');
-}
-});
-}
-
-export default {access, preread, filter};
-
-EOF
-
-$t->write_file('main.js', <try_run('no njs available')->plan(2);
-
-###
-
-is(stream('127.0.0.1:' . port(8081))->read(), 'P-TEST', 'foo.bar.p');
-is(stream('127.0.0.1:' . port(8082))->io('0'), 'x122345', 'lib.access');
-
-###
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Modules: fixed clear() method of a shared dictionary without timeout.

2024-03-20 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f632fe16ba05
branches:  
changeset: 2303:f632fe16ba05
user:  Dmitry Volyntsev 
date:  Tue Mar 19 21:05:51 2024 -0700
description:
Modules: fixed clear() method of a shared dictionary without timeout.

Previously, the code did not unlock the rwlock when a dict was empty.

The issue was introduced in 4a15613f4e8b (0.8.3).

This closes issue #699 on Github.

diffstat:

 nginx/ngx_js_shared_dict.c |  4 +++-
 nginx/t/js_shared_dict.t   |  1 +
 2 files changed, 4 insertions(+), 1 deletions(-)

diffs (32 lines):

diff -r 85313a068147 -r f632fe16ba05 nginx/ngx_js_shared_dict.c
--- a/nginx/ngx_js_shared_dict.cMon Mar 18 22:24:57 2024 -0700
+++ b/nginx/ngx_js_shared_dict.cTue Mar 19 21:05:51 2024 -0700
@@ -479,7 +479,7 @@ njs_js_ext_shared_dict_clear(njs_vm_t *v
 rbtree = >sh->rbtree;
 
 if (rbtree->root == rbtree->sentinel) {
-return NJS_OK;
+goto done;
 }
 
 for (rn = ngx_rbtree_min(rbtree->root, rbtree->sentinel);
@@ -494,6 +494,8 @@ njs_js_ext_shared_dict_clear(njs_vm_t *v
 }
 }
 
+done:
+
 ngx_rwlock_unlock(>sh->rwlock);
 
 njs_value_undefined_set(retval);
diff -r 85313a068147 -r f632fe16ba05 nginx/t/js_shared_dict.t
--- a/nginx/t/js_shared_dict.t  Mon Mar 18 22:24:57 2024 -0700
+++ b/nginx/t/js_shared_dict.t  Tue Mar 19 21:05:51 2024 -0700
@@ -266,6 +266,7 @@ EOF
 
 function set_clear(r) {
 var dict = ngx.shared.no_timeout;
+dict.clear();
 dict.set("test", "test value");
 dict.set("test1", "test1 value");
 dict.clear();
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Shell: added completions for QuickJS engine.

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/85313a068147
branches:  
changeset: 2302:85313a068147
user:  Dmitry Volyntsev 
date:  Mon Mar 18 22:24:57 2024 -0700
description:
Shell: added completions for QuickJS engine.

diffstat:

 external/njs_shell.c|  202 +++-
 test/shell_test.exp |  147 ++
 test/shell_test_njs.exp |  148 ---
 3 files changed, 345 insertions(+), 152 deletions(-)

diffs (541 lines):

diff -r fe94552843d7 -r 85313a068147 external/njs_shell.c
--- a/external/njs_shell.c  Mon Mar 18 22:15:48 2024 -0700
+++ b/external/njs_shell.c  Mon Mar 18 22:24:57 2024 -0700
@@ -3106,6 +3106,203 @@ njs_engine_qjs_output(njs_engine_t *engi
 return NJS_OK;
 }
 
+
+static njs_arr_t *
+njs_qjs_object_completions(njs_engine_t *engine, JSContext *ctx,
+JSValueConst object, njs_str_t *expression)
+{
+u_char  *prefix;
+size_t  len, prefix_len;
+JSValue prototype;
+uint32_tk, n, length;
+njs_int_t   ret;
+njs_arr_t   *array;
+njs_str_t   *completion, key;
+JSPropertyEnum  *ptab;
+
+prefix = expression->start + expression->length;
+
+while (prefix > expression->start && *prefix != '.') {
+prefix--;
+}
+
+if (prefix != expression->start) {
+prefix++;
+}
+
+ptab = NULL;
+key.start = NULL;
+prefix_len = prefix - expression->start;
+len = expression->length - prefix_len;
+
+array = njs_arr_create(engine->pool, 8, sizeof(njs_str_t));
+if (njs_slow_path(array == NULL)) {
+goto fail;
+}
+
+while (!JS_IsNull(object)) {
+ret = JS_GetOwnPropertyNames(ctx, , , object,
+ JS_GPN_STRING_MASK);
+if (ret < 0) {
+goto fail;
+}
+
+for (n = 0; n < length; n++) {
+key.start = (u_char *) JS_AtomToCString(ctx, ptab[n].atom);
+JS_FreeAtom(ctx, ptab[n].atom);
+if (njs_slow_path(key.start == NULL)) {
+goto fail;
+}
+
+key.length = njs_strlen(key.start);
+
+if (len > key.length || njs_strncmp(key.start, prefix, len) != 0) {
+goto next;
+}
+
+for (k = 0; k < array->items; k++) {
+completion = njs_arr_item(array, k);
+
+if ((completion->length - prefix_len - 1) == key.length
+&& njs_strncmp(>start[prefix_len],
+   key.start, key.length)
+   == 0)
+{
+goto next;
+}
+}
+
+completion = njs_arr_add(array);
+if (njs_slow_path(completion == NULL)) {
+goto fail;
+}
+
+completion->length = prefix_len + key.length + 1;
+completion->start = njs_mp_alloc(engine->pool, completion->length);
+if (njs_slow_path(completion->start == NULL)) {
+goto fail;
+}
+
+njs_sprintf(completion->start,
+completion->start + completion->length,
+"%*s%V%Z", prefix_len, expression->start, );
+
+next:
+
+JS_FreeCString(ctx, (const char *) key.start);
+}
+
+js_free_rt(JS_GetRuntime(ctx), ptab);
+
+prototype = JS_GetPrototype(ctx, object);
+if (JS_IsException(prototype)) {
+goto fail;
+}
+
+JS_FreeValue(ctx, object);
+object = prototype;
+}
+
+return array;
+
+fail:
+
+if (array != NULL) {
+njs_arr_destroy(array);
+}
+
+if (key.start != NULL) {
+JS_FreeCString(ctx, (const char *) key.start);
+}
+
+if (ptab != NULL) {
+js_free_rt(JS_GetRuntime(ctx), ptab);
+}
+
+JS_FreeValue(ctx, object);
+
+return NULL;
+}
+
+
+static njs_arr_t *
+njs_engine_qjs_complete(njs_engine_t *engine, njs_str_t *expression)
+{
+u_char  *p, *start, *end;
+JSAtom  key;
+JSValue value, retval;
+njs_arr_t   *arr;
+JSContext   *ctx;
+njs_bool_t  global;
+
+ctx = engine->u.qjs.ctx;
+
+p = expression->start;
+end = p + expression->length;
+
+global = 1;
+value = JS_GetGlobalObject(ctx);
+
+while (p < end && *p != '.') { p++; }
+
+if (p == end) {
+goto done;
+}
+
+p = expression->start;
+
+for ( ;; ) {
+
+start = (*p == '.' && p < end) ? ++p: p;
+
+if (p == end) {
+break;
+}
+
+while (p < end && *p != '.') { p++; }
+
+key = JS_NewAtomLen(ctx, (char *) start, p - start);
+if (key == JS_ATOM_NULL) {
+goto fail;
+}
+
+retval = JS_GetPropert

[njs] Shell: completions are refactored and moved out of the core.

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/fe94552843d7
branches:  
changeset: 2301:fe94552843d7
user:  Dmitry Volyntsev 
date:  Mon Mar 18 22:15:48 2024 -0700
description:
Shell: completions are refactored and moved out of the core.

diffstat:

 external/njs_shell.c|  275 +++-
 src/njs.h   |2 -
 src/njs_builtin.c   |  294 +---
 test/shell_test_njs.exp |   26 +--
 4 files changed, 201 insertions(+), 396 deletions(-)

diffs (737 lines):

diff -r 1aa2bb15c966 -r fe94552843d7 external/njs_shell.c
--- a/external/njs_shell.c  Fri Mar 15 23:14:39 2024 -0700
+++ b/external/njs_shell.c  Mon Mar 18 22:15:48 2024 -0700
@@ -83,15 +83,7 @@ typedef enum {
 
 typedef struct {
 size_t  index;
-size_t  length;
-njs_arr_t   *completions;
 njs_arr_t   *suffix_completions;
-njs_rbtree_node_t   *node;
-
-enum {
-   NJS_COMPLETION_SUFFIX = 0,
-   NJS_COMPLETION_GLOBAL
-}   phase;
 } njs_completion_t;
 
 
@@ -157,7 +149,6 @@ struct njs_engine_s {
 njs_vm_t*vm;
 
 njs_opaque_value_t  value;
-njs_completion_tcompletion;
 }   njs;
 #if (NJS_HAVE_QUICKJS)
 struct {
@@ -174,9 +165,11 @@ struct njs_engine_s {
 njs_int_t (*process_events)(njs_engine_t *engine);
 njs_int_t (*destroy)(njs_engine_t *engine);
 njs_int_t (*output)(njs_engine_t *engine, njs_int_t ret);
+njs_arr_t*(*complete)(njs_engine_t *engine, njs_str_t *ex);
 
 unsignedtype;
 njs_mp_t*pool;
+njs_completion_tcompletion;
 };
 
 typedef struct {
@@ -1361,11 +1354,6 @@ njs_engine_njs_init(njs_engine_t *engine
 return NJS_ERROR;
 }
 
-engine->u.njs.completion.completions = njs_vm_completions(vm, NULL);
-if (engine->u.njs.completion.completions == NULL) {
-return NJS_ERROR;
-}
-
 if (opts->unhandled_rejection) {
 njs_vm_set_rejection_tracker(vm, njs_rejection_tracker,
  njs_vm_external_ptr(vm));
@@ -1455,6 +1443,179 @@ njs_engine_njs_output(njs_engine_t *engi
 }
 
 
+static njs_arr_t *
+njs_object_completions(njs_vm_t *vm, njs_value_t *object, njs_str_t 
*expression)
+{
+u_char  *prefix;
+size_t  len, prefix_len;
+int64_t k, n, length;
+njs_int_t   ret;
+njs_arr_t   *array;
+njs_str_t   *completion, key;
+njs_value_t *keys;
+njs_opaque_value_t  *start, retval, prototype;
+
+prefix = expression->start + expression->length;
+
+while (prefix > expression->start && *prefix != '.') {
+prefix--;
+}
+
+if (prefix != expression->start) {
+prefix++;
+}
+
+prefix_len = prefix - expression->start;
+len = expression->length - prefix_len;
+
+array = njs_arr_create(njs_vm_memory_pool(vm), 8, sizeof(njs_str_t));
+if (njs_slow_path(array == NULL)) {
+goto fail;
+}
+
+while (!njs_value_is_null(object)) {
+keys = njs_vm_value_enumerate(vm, object, NJS_ENUM_KEYS
+  | NJS_ENUM_STRING,
+  njs_value_arg());
+if (njs_slow_path(keys == NULL)) {
+goto fail;
+}
+
+(void) njs_vm_array_length(vm, keys, );
+
+start = (njs_opaque_value_t *) njs_vm_array_start(vm, keys);
+if (start == NULL) {
+goto fail;
+}
+
+
+for (n = 0; n < length; n++) {
+ret = njs_vm_value_to_string(vm, , njs_value_arg(start));
+if (njs_slow_path(ret != NJS_OK)) {
+goto fail;
+}
+
+start++;
+
+if (len > key.length || njs_strncmp(key.start, prefix, len) != 0) {
+continue;
+}
+
+for (k = 0; k < array->items; k++) {
+completion = njs_arr_item(array, k);
+
+if ((completion->length - prefix_len - 1) == key.length
+&& njs_strncmp(>start[prefix_len],
+   key.start, key.length)
+   == 0)
+{
+break;
+}
+}
+
+if (k != array->items) {
+continue;
+}
+
+completion = njs_arr_add(array);
+if (njs_slow_path(completion == NULL)) {
+goto fail;
+}
+
+completion->length = prefix_len + key.length + 1;
+completion->start = njs_mp_alloc(njs_vm_memory_pool(vm),
+ comp

[njs] Introduced njs_vm_value_enumerate() and njs_vm_value_own_enumerate().

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/1aa2bb15c966
branches:  
changeset: 2300:1aa2bb15c966
user:  Dmitry Volyntsev 
date:  Fri Mar 15 23:14:39 2024 -0700
description:
Introduced njs_vm_value_enumerate() and njs_vm_value_own_enumerate().

diffstat:

 src/njs.h   |  16 ++
 src/njs_value.h |  12 ---
 src/njs_vm.c|  88 +
 3 files changed, 104 insertions(+), 12 deletions(-)

diffs (153 lines):

diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs.h
--- a/src/njs.h Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs.h Fri Mar 15 23:14:39 2024 -0700
@@ -129,6 +129,18 @@ typedef enum {
 
 
 typedef enum {
+#define njs_object_enum_kind(flags) (flags & 7)
+NJS_ENUM_KEYS = 1,
+NJS_ENUM_VALUES = 2,
+NJS_ENUM_BOTH = 4,
+#define njs_object_enum(flags) (flags & (NJS_ENUM_STRING | NJS_ENUM_SYMBOL))
+NJS_ENUM_STRING = 8,
+NJS_ENUM_SYMBOL = 16,
+NJS_ENUM_ENUMERABLE_ONLY = 32,
+} njs_object_enum_t;
+
+
+typedef enum {
 /*
  * Extern property type.
  */
@@ -497,6 +509,10 @@ NJS_EXPORT njs_int_t njs_vm_object_alloc
 ...);
 NJS_EXPORT njs_value_t *njs_vm_object_keys(njs_vm_t *vm, njs_value_t *value,
 njs_value_t *retval);
+NJS_EXPORT njs_value_t *njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t 
*value,
+uint32_t flags, njs_value_t *retval);
+NJS_EXPORT njs_value_t *njs_vm_value_own_enumerate(njs_vm_t *vm,
+njs_value_t *value, uint32_t flags, njs_value_t *retval);
 NJS_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm,
 njs_value_t *value, const njs_str_t *key, njs_opaque_value_t *retval);
 NJS_EXPORT njs_int_t njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value,
diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs_value.h
--- a/src/njs_value.h   Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs_value.h   Fri Mar 15 23:14:39 2024 -0700
@@ -313,18 +313,6 @@ struct njs_object_type_init_s {
 
 
 typedef enum {
-#define njs_object_enum_kind(flags) (flags & 7)
-NJS_ENUM_KEYS = 1,
-NJS_ENUM_VALUES = 2,
-NJS_ENUM_BOTH = 4,
-#define njs_object_enum(flags) (flags & (NJS_ENUM_STRING | NJS_ENUM_SYMBOL))
-NJS_ENUM_STRING = 8,
-NJS_ENUM_SYMBOL = 16,
-NJS_ENUM_ENUMERABLE_ONLY = 32,
-} njs_object_enum_t;
-
-
-typedef enum {
 NJS_PROPERTY = 0,
 NJS_ACCESSOR,
 NJS_PROPERTY_REF,
diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs_vm.c
--- a/src/njs_vm.c  Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs_vm.c  Fri Mar 15 23:14:39 2024 -0700
@@ -1114,6 +1114,94 @@ njs_vm_exception_string(njs_vm_t *vm, nj
 }
 
 
+njs_value_t *
+njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
+njs_value_t *retval)
+{
+ssize_t  length;
+njs_int_tret;
+njs_value_t  *val;
+njs_array_t  *keys;
+njs_rbtree_t *variables;
+njs_rbtree_node_t*rb_node;
+njs_variable_node_t  *node;
+const njs_lexer_entry_t  *lex_entry;
+
+static const njs_str_t  njs_this_str = njs_str("this");
+
+keys = njs_value_enumerate(vm, value, flags);
+if (njs_slow_path(keys == NULL)) {
+return NULL;
+}
+
+if (!njs_values_same(value, >global_value)
+|| vm->global_scope == NULL)
+{
+goto done;
+}
+
+/* TODO: workaround for values in global object. */
+
+variables = >global_scope->variables;
+rb_node = njs_rbtree_min(variables);
+
+while (njs_rbtree_is_there_successor(variables, rb_node)) {
+node = (njs_variable_node_t *) rb_node;
+
+lex_entry = njs_lexer_entry(node->variable->unique_id);
+if (njs_slow_path(lex_entry == NULL)) {
+return NULL;
+}
+
+if (njs_strstr_eq(_entry->name, _this_str)) {
+rb_node = njs_rbtree_node_successor(variables, rb_node);
+continue;
+}
+
+length = njs_utf8_length(lex_entry->name.start, 
lex_entry->name.length);
+if (njs_slow_path(length < 0)) {
+return NULL;
+}
+
+val = njs_array_push(vm, keys);
+if (njs_slow_path(value == NULL)) {
+return NULL;
+}
+
+ret = njs_string_new(vm, val, lex_entry->name.start,
+ lex_entry->name.length, length);
+if (njs_slow_path(ret != NJS_OK)) {
+return NULL;
+}
+
+rb_node = njs_rbtree_node_successor(variables, rb_node);
+}
+
+done:
+
+ njs_set_array(retval, keys);
+
+ return retval;
+}
+
+
+njs_value_t *
+njs_vm_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
+njs_value_t *retval)
+{
+njs_array_t  *keys;
+
+keys = njs_value_own_enumerate(vm, value, flags);
+if (njs_slow_path(keys == NULL)) {
+return NULL;
+}
+
+njs_set_array(retval, keys);
+
+return retval;
+}
+
+
 njs_int_t
 njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...)

[njs] Refactoring njs_value_own_enumerate() and friends.

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/b0e42db5ca84
branches:  
changeset: 2299:b0e42db5ca84
user:  Dmitry Volyntsev 
date:  Fri Mar 15 22:47:50 2024 -0700
description:
Refactoring njs_value_own_enumerate() and friends.

All three flag-like arguments are merged into a single flag argument.

diffstat:

 src/njs_array.c   |4 +-
 src/njs_builtin.c |2 +-
 src/njs_json.c|8 +-
 src/njs_object.c  |  154 +
 src/njs_object.h  |4 +-
 src/njs_value.c   |   20 ++
 src/njs_value.h   |   21 +++---
 src/njs_vm.c  |4 +-
 src/njs_vmcode.c  |6 +-
 9 files changed, 106 insertions(+), 117 deletions(-)

diffs (727 lines):

diff -r 6808a27d254a -r b0e42db5ca84 src/njs_array.c
--- a/src/njs_array.c   Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_array.c   Fri Mar 15 22:47:50 2024 -0700
@@ -1868,8 +1868,8 @@ njs_array_keys(njs_vm_t *vm, njs_value_t
 {
 njs_array_t  *keys;
 
-keys = njs_value_own_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING,
-   all);
+keys = njs_value_own_enumerate(vm, object, NJS_ENUM_KEYS | NJS_ENUM_STRING
+   | (!all ? NJS_ENUM_ENUMERABLE_ONLY : 0));
 if (njs_slow_path(keys == NULL)) {
 return NULL;
 }
diff -r 6808a27d254a -r b0e42db5ca84 src/njs_builtin.c
--- a/src/njs_builtin.c Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_builtin.c Fri Mar 15 22:47:50 2024 -0700
@@ -648,7 +648,7 @@ njs_object_completions(njs_vm_t *vm, njs
 object->type = NJS_OBJECT;
 }
 
-keys = njs_value_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING, 1);
+keys = njs_value_enumerate(vm, object, NJS_ENUM_KEYS | NJS_ENUM_STRING);
 if (njs_slow_path(keys == NULL)) {
 goto done;
 }
diff -r 6808a27d254a -r b0e42db5ca84 src/njs_json.c
--- a/src/njs_json.cThu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_json.cFri Mar 15 22:47:50 2024 -0700
@@ -44,7 +44,7 @@ typedef struct {
 njs_value_treplacer;
 njs_str_t  space;
 u_char space_buf[16];
-njs_object_enum_type_t keys_type;
+uint32_t   keys_type;
 } njs_json_stringify_t;
 
 
@@ -998,8 +998,10 @@ njs_json_push_stringify_state(njs_json_s
 }
 
 } else {
-state->keys = njs_value_own_enumerate(stringify->vm, value, 
NJS_ENUM_KEYS,
-  stringify->keys_type, 0);
+state->keys = njs_value_own_enumerate(stringify->vm, value,
+  NJS_ENUM_KEYS
+  | stringify->keys_type
+  | NJS_ENUM_ENUMERABLE_ONLY);
 
 if (njs_slow_path(state->keys == NULL)) {
 return NULL;
diff -r 6808a27d254a -r b0e42db5ca84 src/njs_object.c
--- a/src/njs_object.c  Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_object.c  Fri Mar 15 22:47:50 2024 -0700
@@ -18,17 +18,16 @@ static njs_int_t njs_object_hash_test(nj
 static njs_object_prop_t *njs_object_exist_in_proto(const njs_object_t *begin,
 const njs_object_t *end, njs_lvlhsh_query_t *lhq);
 static njs_int_t njs_object_enumerate_array(njs_vm_t *vm,
-const njs_array_t *array, njs_array_t *items, njs_object_enum_t kind);
+const njs_array_t *array, njs_array_t *items, uint32_t flags);
 static njs_int_t njs_object_enumerate_typed_array(njs_vm_t *vm,
-const njs_typed_array_t *array, njs_array_t *items, njs_object_enum_t 
kind);
+const njs_typed_array_t *array, njs_array_t *items, uint32_t flags);
 static njs_int_t njs_object_enumerate_string(njs_vm_t *vm,
-const njs_value_t *value, njs_array_t *items, njs_object_enum_t kind);
+const njs_value_t *value, njs_array_t *items, uint32_t flags);
 static njs_int_t njs_object_enumerate_object(njs_vm_t *vm,
-const njs_object_t *object, njs_array_t *items, njs_object_enum_t kind,
-njs_object_enum_type_t type, njs_bool_t all);
+const njs_object_t *object, njs_array_t *items, uint32_t flags);
 static njs_int_t njs_object_own_enumerate_object(njs_vm_t *vm,
 const njs_object_t *object, const njs_object_t *parent, njs_array_t *items,
-njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all);
+uint32_t flags);
 static njs_int_t njs_object_define_properties(njs_vm_t *vm, njs_value_t *args,
 njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_object_set_prototype(njs_vm_t *vm, njs_object_t *object,
@@ -324,8 +323,8 @@ njs_object_keys(njs_vm_t *vm, njs_value_
 return NJS_ERROR;
 }
 
-keys = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS,
-   NJS_ENUM_STRING, 0);
+keys = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS | NJS_ENUM_STRING
+   | NJS_ENUM_ENUMERABLE_ONLY);
 if (keys == NULL) {
 return NJS

[njs] Introduced njs_vm_prototype() to get a value's prototype.

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/6808a27d254a
branches:  
changeset: 2298:6808a27d254a
user:  Dmitry Volyntsev 
date:  Thu Mar 14 23:28:03 2024 -0700
description:
Introduced njs_vm_prototype() to get a value's prototype.

diffstat:

 src/njs.h|   2 ++
 src/njs_object.c |   2 +-
 src/njs_object.h |   2 ++
 src/njs_vm.c |  13 +
 4 files changed, 18 insertions(+), 1 deletions(-)

diffs (59 lines):

diff -r 00b89201fb71 -r 6808a27d254a src/njs.h
--- a/src/njs.h Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs.h Thu Mar 14 23:28:03 2024 -0700
@@ -373,6 +373,8 @@ NJS_EXPORT njs_int_t njs_vm_value(njs_vm
 njs_value_t *retval);
 NJS_EXPORT njs_function_t *njs_vm_function(njs_vm_t *vm, const njs_str_t 
*name);
 NJS_EXPORT njs_bool_t njs_vm_constructor(njs_vm_t *vm);
+NJS_EXPORT njs_int_t njs_vm_prototype(njs_vm_t *vm, njs_value_t *value,
+njs_value_t *retval);
 
 NJS_EXPORT void njs_vm_throw(njs_vm_t *vm, const njs_value_t *value);
 NJS_EXPORT void njs_vm_error2(njs_vm_t *vm, unsigned error_type,
diff -r 00b89201fb71 -r 6808a27d254a src/njs_object.c
--- a/src/njs_object.c  Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_object.c  Thu Mar 14 23:28:03 2024 -0700
@@ -1598,7 +1598,7 @@ njs_object_get_own_property(njs_vm_t *vm
 }
 
 
-static njs_int_t
+njs_int_t
 njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 njs_index_t unused, njs_value_t *retval)
 {
diff -r 00b89201fb71 -r 6808a27d254a src/njs_object.h
--- a/src/njs_object.h  Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_object.h  Thu Mar 14 23:28:03 2024 -0700
@@ -106,6 +106,8 @@ njs_int_t njs_object_prop_define(njs_vm_
 njs_value_t *name, njs_value_t *value, unsigned flags, uint32_t hash);
 njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
 njs_value_t *value, njs_value_t *setval);
+njs_int_t njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args,
+njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 const char *njs_prop_type_string(njs_object_prop_type_t type);
 njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init,
 const njs_object_prop_t *base, njs_value_t *value, njs_value_t *retval);
diff -r 00b89201fb71 -r 6808a27d254a src/njs_vm.c
--- a/src/njs_vm.c  Thu Mar 14 23:28:03 2024 -0700
+++ b/src/njs_vm.c  Thu Mar 14 23:28:03 2024 -0700
@@ -1201,6 +1201,19 @@ njs_vm_object_keys(njs_vm_t *vm, njs_val
 
 
 njs_int_t
+njs_vm_prototype(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
+{
+njs_value_t arguments[2];
+
+njs_set_undefined([0]);
+njs_value_assign([1], value);
+
+return njs_object_get_prototype_of(vm, njs_value_arg(), 2, 0,
+   retval);
+}
+
+
+njs_int_t
 njs_vm_array_alloc(njs_vm_t *vm, njs_value_t *retval, uint32_t spare)
 {
 njs_array_t  *array;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Introduced njs_vm_global() to get global object.

2024-03-18 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/00b89201fb71
branches:  
changeset: 2297:00b89201fb71
user:  Dmitry Volyntsev 
date:  Thu Mar 14 23:28:03 2024 -0700
description:
Introduced njs_vm_global() to get global object.

diffstat:

 src/njs.h|  1 +
 src/njs_vm.c |  8 
 2 files changed, 9 insertions(+), 0 deletions(-)

diffs (29 lines):

diff -r 8309b884e265 -r 00b89201fb71 src/njs.h
--- a/src/njs.h Tue Mar 05 11:43:49 2024 -0800
+++ b/src/njs.h Thu Mar 14 23:28:03 2024 -0700
@@ -368,6 +368,7 @@ NJS_EXPORT njs_int_t njs_vm_bind(njs_vm_
 njs_int_t njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name,
 njs_prop_handler_t handler, uint16_t magic16, uint32_t magic32,
 njs_bool_t shared);
+NJS_EXPORT njs_int_t njs_vm_global(njs_vm_t *vm, njs_value_t *retval);
 NJS_EXPORT njs_int_t njs_vm_value(njs_vm_t *vm, const njs_str_t *path,
 njs_value_t *retval);
 NJS_EXPORT njs_function_t *njs_vm_function(njs_vm_t *vm, const njs_str_t 
*name);
diff -r 8309b884e265 -r 00b89201fb71 src/njs_vm.c
--- a/src/njs_vm.c  Tue Mar 05 11:43:49 2024 -0800
+++ b/src/njs_vm.c  Thu Mar 14 23:28:03 2024 -0700
@@ -814,6 +814,14 @@ njs_vm_error3(njs_vm_t *vm, unsigned typ
 
 
 njs_int_t
+njs_vm_global(njs_vm_t *vm, njs_value_t *retval)
+{
+njs_value_assign(retval, >global_value);
+return NJS_OK;
+}
+
+
+njs_int_t
 njs_vm_value(njs_vm_t *vm, const njs_str_t *path, njs_value_t *retval)
 {
 u_char   *start, *p, *end;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: lock in nginx/njs

2024-03-13 Thread Dmitry Volyntsev


On 12.03.2024 23:00, Eugene Prokopiev wrote:

Здравствуйте!

Скажите, нет ли чего-нибудь похожего на
https://github.com/openresty/lua-resty-lock/ в nginx/njs?
Или может есть другой способ разрешить выполнять запросы с одинаковым
$uri строго по очереди (один выполняется, остальные ждут)?

А чем вас 
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock 
не устраивает?

Или более подробно опишите свою задачу
___
nginx-ru mailing list
nginx-ru@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-ru


Re: [PATCH] HTTP: remove needless code

2024-03-05 Thread Dmitry Volyntsev


On 3/5/24 10:15 AM, Sergey A. Osokin wrote:

# HG changeset patch
# User Sergey A. Osokin 
# Date 1709662441 -10800
#  Tue Mar 05 21:14:01 2024 +0300
# Node ID 00de871f1e5e0936e2401aaec863bf7040de8608
# Parent  eb01434865d7b698f036f199084308726c2827ea
HTTP: remove needless code.

diff -r eb01434865d7 -r 00de871f1e5e nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cThu Feb 29 20:56:56 2024 -0800
+++ b/nginx/ngx_http_js_module.cTue Mar 05 21:14:01 2024 +0300
@@ -4193,8 +4193,6 @@
  }
  
  return NJS_OK;

-
-return NJS_OK;
  }
  


Thank you for catching the issue. It is already fixed here

https://hg.nginx.org/njs/rev/8309b884e265.

  
___

nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed typo introduced in eb01434865d7.

2024-03-05 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/8309b884e265
branches:  
changeset: 2296:8309b884e265
user:  Dmitry Volyntsev 
date:  Tue Mar 05 11:43:49 2024 -0800
description:
Fixed typo introduced in eb01434865d7.

diffstat:

 nginx/ngx_http_js_module.c |  2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diffs (12 lines):

diff -r eb01434865d7 -r 8309b884e265 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cThu Feb 29 20:56:56 2024 -0800
+++ b/nginx/ngx_http_js_module.cTue Mar 05 11:43:49 2024 -0800
@@ -4193,8 +4193,6 @@ ngx_http_js_server(njs_vm_t *vm, ngx_htt
 }
 
 return NJS_OK;
-
-return NJS_OK;
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] HTTP: allowing to set Server header.

2024-03-05 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/eb01434865d7
branches:  
changeset: 2295:eb01434865d7
user:  Dmitry Volyntsev 
date:  Thu Feb 29 20:56:56 2024 -0800
description:
HTTP: allowing to set Server header.

diffstat:

 nginx/ngx_http_js_module.c |  38 ++
 nginx/t/js_headers.t   |  22 --
 2 files changed, 58 insertions(+), 2 deletions(-)

diffs (140 lines):

diff -r d7a0bbcba46e -r eb01434865d7 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cThu Feb 29 18:56:13 2024 -0800
+++ b/nginx/ngx_http_js_module.cThu Feb 29 20:56:56 2024 -0800
@@ -149,6 +149,9 @@ static njs_int_t ngx_http_js_last_modifi
 static njs_int_t ngx_http_js_location122(njs_vm_t *vm, ngx_http_request_t *r,
 ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
 njs_value_t *retval);
+static njs_int_t ngx_http_js_server122(njs_vm_t *vm, ngx_http_request_t *r,
+ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+njs_value_t *retval);
 #endif
 static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm,
 njs_value_t *value, njs_value_t *keys);
@@ -255,6 +258,9 @@ static njs_int_t ngx_http_js_last_modifi
 static njs_int_t ngx_http_js_location(njs_vm_t *vm, ngx_http_request_t *r,
 unsigned flags, njs_str_t *name, njs_value_t *setval,
 njs_value_t *retval);
+static njs_int_t ngx_http_js_server(njs_vm_t *vm, ngx_http_request_t *r,
+unsigned flags, njs_str_t *name, njs_value_t *setval,
+njs_value_t *retval);
 
 static ngx_pool_t *ngx_http_js_pool(njs_vm_t *vm, ngx_http_request_t *r);
 static ngx_resolver_t *ngx_http_js_resolver(njs_vm_t *vm,
@@ -1617,6 +1623,7 @@ ngx_http_js_ext_header_out(njs_vm_t *vm,
 { njs_str("Expires"), ngx_http_js_header_single },
 { njs_str("Last-Modified"), ngx_http_js_last_modified122 },
 { njs_str("Location"), ngx_http_js_location122 },
+{ njs_str("Server"), ngx_http_js_server122 },
 { njs_str("Set-Cookie"), ngx_http_js_header_array },
 { njs_str("Retry-After"), ngx_http_js_header_single },
 { njs_str(""), ngx_http_js_header_generic },
@@ -1630,6 +1637,7 @@ ngx_http_js_ext_header_out(njs_vm_t *vm,
 { njs_str("Expires"), NJS_HEADER_SINGLE, ngx_http_js_header_out },
 { njs_str("Last-Modified"), 0, ngx_http_js_last_modified },
 { njs_str("Location"), 0, ngx_http_js_location },
+{ njs_str("Server"), 0, ngx_http_js_server },
 { njs_str("Set-Cookie"), NJS_HEADER_ARRAY, ngx_http_js_header_out },
 { njs_str("Retry-After"), NJS_HEADER_SINGLE, ngx_http_js_header_out },
 { njs_str(""), 0, ngx_http_js_header_out },
@@ -2065,6 +2073,14 @@ ngx_http_js_location122(njs_vm_t *vm, ng
 {
 return ngx_http_js_location(vm, r, 0, v, setval, retval);
 }
+
+
+static njs_int_t
+ngx_http_js_server122(njs_vm_t *vm, ngx_http_request_t *r,
+ngx_list_t *headers, njs_str_t *v, njs_value_t *setval, njs_value_t 
*retval)
+{
+return ngx_http_js_server(vm, r, 0, v, setval, retval);
+}
 #endif
 
 
@@ -4160,6 +4176,28 @@ ngx_http_js_location(njs_vm_t *vm, ngx_h
 }
 
 
+static njs_int_t
+ngx_http_js_server(njs_vm_t *vm, ngx_http_request_t *r, unsigned flags,
+njs_str_t *v, njs_value_t *setval, njs_value_t *retval)
+{
+njs_int_t rc;
+ngx_table_elt_t  *h;
+
+rc = ngx_http_js_header_out_special(vm, r, v, setval, retval, );
+if (rc == NJS_ERROR) {
+return NJS_ERROR;
+}
+
+if (setval != NULL || retval == NULL) {
+r->headers_out.server = h;
+}
+
+return NJS_OK;
+
+return NJS_OK;
+}
+
+
 static void
 ngx_http_js_periodic_handler(ngx_event_t *ev)
 {
diff -r d7a0bbcba46e -r eb01434865d7 nginx/t/js_headers.t
--- a/nginx/t/js_headers.t  Thu Feb 29 18:56:13 2024 -0800
+++ b/nginx/t/js_headers.t  Thu Feb 29 20:56:56 2024 -0800
@@ -160,6 +160,10 @@ http {
 js_content test.copy_subrequest_hdrs;
 }
 
+location /server {
+js_content test.server;
+}
+
 location = /subrequest {
 internal;
 
@@ -435,6 +439,11 @@ EOF
 r.return(200, resp.responseText);
 }
 
+function server(r) {
+r.headersOut['Server'] = 'Foo';
+r.return(200);
+}
+
 function subrequest(r) {
 r.headersOut['A'] = 'a';
 r.headersOut['Content-Encoding'] = 'ce';
@@ -456,12 +465,12 @@ EOF
 hdr_out, raw_hdr_out, hdr_out_array, hdr_out_single,
 hdr_out_set_cookie, ihdr_out, hdr_out_special_set,
 copy_subrequest_hdrs, subrequest, date, last_modified,
-location, location_sr};
+location, location_sr, server};
 
 
 EOF
 
-$t->try_run('no njs')->plan(46);
+$t->try_run('no njs')->plan(49);
 
 

[njs] Shell: revert -t option back to preserve backward compatibility.

2024-02-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/d7a0bbcba46e
branches:  
changeset: 2294:d7a0bbcba46e
user:  Dmitry Volyntsev 
date:  Thu Feb 29 18:56:13 2024 -0800
description:
Shell: revert -t option back to preserve backward compatibility.

The issue was introduced in cb3e068a511c.

diffstat:

 external/njs_shell.c |  16 
 1 files changed, 16 insertions(+), 0 deletions(-)

diffs (26 lines):

diff -r 49417e2749e0 -r d7a0bbcba46e external/njs_shell.c
--- a/external/njs_shell.c  Tue Feb 27 23:25:11 2024 -0800
+++ b/external/njs_shell.c  Thu Feb 29 18:56:13 2024 -0800
@@ -726,6 +726,22 @@ njs_options_parse(njs_opts_t *opts, int 
 opts->sandbox = 1;
 break;
 
+case 't':
+if (++i < argc) {
+if (strcmp(argv[i], "module") == 0) {
+opts->module = 1;
+
+} else if (strcmp(argv[i], "script") != 0) {
+njs_stderror("option \"-t\" unexpected source type: %s\n",
+ argv[i]);
+return NJS_ERROR;
+}
+
+break;
+}
+
+njs_stderror("option \"-t\" requires source type\n");
+return NJS_ERROR;
 case 'v':
 case 'V':
 opts->version = 1;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Removed duplicate expect tests introduced in cb3e068a511c.

2024-02-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/49417e2749e0
branches:  
changeset: 2293:49417e2749e0
user:  Dmitry Volyntsev 
date:  Tue Feb 27 23:25:11 2024 -0800
description:
Removed duplicate expect tests introduced in cb3e068a511c.

diffstat:

 test/shell_test_njs.exp |  32 
 1 files changed, 0 insertions(+), 32 deletions(-)

diffs (42 lines):

diff -r 46699330f4f2 -r 49417e2749e0 test/shell_test_njs.exp
--- a/test/shell_test_njs.exp   Tue Feb 27 23:25:05 2024 -0800
+++ b/test/shell_test_njs.exp   Tue Feb 27 23:25:11 2024 -0800
@@ -212,38 +212,6 @@ njs_test {
  "TypeError: cannot get property \"a\" of undefined"}
 }
 
-# console.time* functions
-njs_test {
-{"console.time()\r\n"
- "console.time()\r\nundefined\r\n>> "}
-{"console.timeEnd()\r\n"
- "console.timeEnd()\r\ndefault: *.*ms\r\nundefined\r\n>> "}
-{"console.time(undefined)\r\n"
- "console.time(undefined)\r\nundefined\r\n>> "}
-{"console.timeEnd(undefined)\r\n"
- "console.timeEnd(undefined)\r\ndefault: *.*ms\r\nundefined\r\n>> "}
-{"console.time('abc')\r\n"
- "console.time('abc')\r\nundefined\r\n>> "}
-{"console.time('abc')\r\n"
- "console.time('abc')\r\nTimer \"abc\" already exists.\r\nundefined\r\n>> 
"}
-{"console.timeEnd('abc')\r\n"
- "console.timeEnd('abc')\r\nabc: *.*ms\r\nundefined\r\n>> "}
-{"console.time(true)\r\n"
- "console.time(true)\r\nundefined\r\n>> "}
-{"console.timeEnd(true)\r\n"
- "console.timeEnd(true)\r\ntrue: *.*ms\r\nundefined\r\n>> "}
-{"console.time(42)\r\n"
- "console.time(42)\r\nundefined\r\n>> "}
-{"console.timeEnd(42)\r\n"
- "console.timeEnd(42)\r\n42: *.*ms\r\nundefined\r\n>> "}
-{"console.timeEnd()\r\n"
- "console.timeEnd()\r\nTimer \"default\" doesn’t exist."}
-{"console.timeEnd('abc')\r\n"
- "console.timeEnd('abc')\r\nTimer \"abc\" doesn’t exist."}
-{"console.time('abc')\r\n"
- "console.time('abc')\r\nundefined\r\n>> "}
-}
-
 njs_test {
 {"console.ll()\r\n"
  "console.ll()\r\nThrown:\r\nTypeError: (intermediate value)\\\[\"ll\"] is 
not a function"}
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Shell: fixed memory pool issues introduced in cb3e068a511c.

2024-02-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/46699330f4f2
branches:  
changeset: 2292:46699330f4f2
user:  Dmitry Volyntsev 
date:  Tue Feb 27 23:25:05 2024 -0800
description:
Shell: fixed memory pool issues introduced in cb3e068a511c.

diffstat:

 external/njs_shell.c |  15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diffs (52 lines):

diff -r e73d4947372d -r 46699330f4f2 external/njs_shell.c
--- a/external/njs_shell.c  Tue Feb 27 23:24:55 2024 -0800
+++ b/external/njs_shell.c  Tue Feb 27 23:25:05 2024 -0800
@@ -1270,7 +1270,7 @@ njs_module_loader(njs_vm_t *vm, njs_exte
 return NULL;
 }
 
-ret = njs_module_read(njs_vm_memory_pool(vm), info.fd, );
+ret = njs_module_read(console->engine->pool, info.fd, );
 
 (void) close(info.fd);
 
@@ -1293,10 +1293,10 @@ njs_module_loader(njs_vm_t *vm, njs_exte
 module = njs_vm_compile_module(vm, , ,
[text.length]);
 
-njs_mp_free(njs_vm_memory_pool(vm), console->cwd.start);
+njs_mp_free(console->engine->pool, console->cwd.start);
 console->cwd = prev_cwd;
 
-njs_mp_free(njs_vm_memory_pool(vm), text.start);
+njs_mp_free(console->engine->pool, text.start);
 
 return module;
 }
@@ -3716,7 +3716,7 @@ njs_clear_timeout(njs_vm_t *vm, njs_valu
 njs_queue_remove(>link);
 njs_rbtree_delete(>events, (njs_rbtree_part_t *) rb);
 
-njs_mp_free(console->engine->pool, ev);
+njs_mp_free(njs_vm_memory_pool(vm), ev);
 
 njs_value_undefined_set(retval);
 
@@ -3780,12 +3780,15 @@ njs_console_time(njs_console_t *console,
 link = njs_queue_next(link);
 }
 
-label = njs_mp_alloc(console->engine->pool, sizeof(njs_timelabel_t));
+label = njs_mp_alloc(console->engine->pool,
+ sizeof(njs_timelabel_t) + name->length);
 if (njs_slow_path(label == NULL)) {
 return NJS_ERROR;
 }
 
-label->name = *name;
+label->name.start = (u_char *) label + sizeof(njs_timelabel_t);
+memcpy(label->name.start, name->start, name->length);
+label->name.length = name->length;
 label->time = njs_time();
 
 njs_queue_insert_tail(>labels, >link);
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Simplified working with global value.

2024-02-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/e73d4947372d
branches:  
changeset: 2291:e73d4947372d
user:  Dmitry Volyntsev 
date:  Tue Feb 27 23:24:55 2024 -0800
description:
Simplified working with global value.

diffstat:

 src/njs_builtin.c  |  6 ++
 src/njs_function.c |  2 +-
 src/njs_vm.c   |  4 +---
 3 files changed, 4 insertions(+), 8 deletions(-)

diffs (63 lines):

diff -r cb3e068a511c -r e73d4947372d src/njs_builtin.c
--- a/src/njs_builtin.c Thu Feb 22 20:25:43 2024 -0800
+++ b/src/njs_builtin.c Tue Feb 27 23:24:55 2024 -0800
@@ -258,8 +258,6 @@ njs_builtin_objects_create(njs_vm_t *vm)
 vm->global_object = shared->objects[0];
 vm->global_object.shared = 0;
 
-njs_set_object(>global_value, >global_object);
-
 string_object = >string_object;
 njs_lvlhsh_init(_object->hash);
 string_object->shared_hash = shared->string_instance_hash;
@@ -442,7 +440,7 @@ njs_builtin_completions(njs_vm_t *vm)
 ctx.type = NJS_BUILTIN_TRAVERSE_KEYS;
 njs_lvlhsh_init();
 
-ret = njs_object_traverse(vm, >global_object, ,
+ret = njs_object_traverse(vm, njs_object(>global_value), ,
   njs_builtin_traverse);
 if (njs_slow_path(ret != NJS_OK)) {
 return NULL;
@@ -753,7 +751,7 @@ njs_builtin_match_native_function(njs_vm
 
 ctx.match = njs_str_value("");
 
-ret = njs_object_traverse(vm, >global_object, ,
+ret = njs_object_traverse(vm, njs_object(>global_value), ,
   njs_builtin_traverse);
 
 if (ret == NJS_DONE) {
diff -r cb3e068a511c -r e73d4947372d src/njs_function.c
--- a/src/njs_function.cThu Feb 22 20:25:43 2024 -0800
+++ b/src/njs_function.cTue Feb 27 23:24:55 2024 -0800
@@ -435,7 +435,7 @@ njs_function_lambda_frame(njs_vm_t *vm, 
 if (njs_slow_path(function->global_this
   && njs_is_null_or_undefined(this)))
 {
-njs_set_object(native_frame->local[0], >global_object);
+njs_value_assign(native_frame->local[0], >global_value);
 }
 
 /* Copy arguments. */
diff -r cb3e068a511c -r e73d4947372d src/njs_vm.c
--- a/src/njs_vm.c  Thu Feb 22 20:25:43 2024 -0800
+++ b/src/njs_vm.c  Tue Feb 27 23:24:55 2024 -0800
@@ -425,8 +425,6 @@ njs_vm_clone(njs_vm_t *vm, njs_external_
 
 nvm->levels[NJS_LEVEL_GLOBAL] = global;
 
-njs_set_object(>global_value, >global_object);
-
 /* globalThis and this */
 njs_scope_value_set(nvm, njs_scope_global_this_index(), 
>global_value);
 
@@ -826,7 +824,7 @@ njs_vm_value(njs_vm_t *vm, const njs_str
 start = path->start;
 end = start + path->length;
 
-njs_set_object(, >global_object);
+njs_value_assign(, >global_value);
 
 for ( ;; ) {
 p = njs_strlchr(start, end, '.');
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Shell: added QuickJS engine support.

2024-02-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/cb3e068a511c
branches:  
changeset: 2290:cb3e068a511c
user:  Dmitry Volyntsev 
date:  Thu Feb 22 20:25:43 2024 -0800
description:
Shell: added QuickJS engine support.

diffstat:

 auto/expect  |22 +-
 auto/make|23 +-
 auto/options | 2 +
 auto/quickjs |55 +
 auto/summary | 4 +
 configure| 1 +
 external/njs_shell.c |  2225 -
 src/njs_builtin.c| 3 +
 src/test/njs_unit_test.c | 4 +-
 test/setup   | 5 +
 test/shell_test.exp  |   361 +---
 test/shell_test_njs.exp  |   418 
 test/test262 | 5 +
 13 files changed, 2531 insertions(+), 597 deletions(-)

diffs (truncated from 3866 to 1000 lines):

diff -r 272af619b821 -r cb3e068a511c auto/expect
--- a/auto/expect   Thu Feb 22 17:38:58 2024 -0800
+++ b/auto/expect   Thu Feb 22 20:25:43 2024 -0800
@@ -20,11 +20,31 @@ fi
 if [ $njs_found = yes -a $NJS_HAVE_READLINE = YES ]; then
 cat << END >> $NJS_MAKEFILE
 
-shell_test:njs test/shell_test.exp
+shell_test_njs:njs test/shell_test.exp
PATH=$NJS_BUILD_DIR:\$(PATH) LANG=C.UTF-8 TERM=screen \
 expect -f test/shell_test.exp
+   PATH=$NJS_BUILD_DIR:\$(PATH) LANG=C.UTF-8 TERM=screen \
+expect -f test/shell_test_njs.exp
 END
 
+if [ $NJS_HAVE_QUICKJS = YES ]; then
+cat << END >> $NJS_MAKEFILE
+
+shell_test:shell_test_njs shell_test_quickjs
+
+shell_test_quickjs:njs test/shell_test.exp
+   PATH=$NJS_BUILD_DIR:\$(PATH) LANG=C.UTF-8 TERM=screen 
NJS_ENGINE=QuickJS \
+expect -f test/shell_test.exp
+END
+
+else
+cat << END >> $NJS_MAKEFILE
+
+shell_test:shell_test_njs
+END
+
+fi
+
 else
 echo " - expect tests are disabled"
 
diff -r 272af619b821 -r cb3e068a511c auto/make
--- a/auto/make Thu Feb 22 17:38:58 2024 -0800
+++ b/auto/make Thu Feb 22 20:25:43 2024 -0800
@@ -241,8 +241,7 @@ lib_test: $NJS_BUILD_DIR/njs_auto_config
$NJS_BUILD_DIR/lvlhsh_unit_test
$NJS_BUILD_DIR/unicode_unit_test
 
-test262: njs
-
+test262_njs: njs
test/test262 --binary=$NJS_BUILD_DIR/njs
 
 unit_test: $NJS_BUILD_DIR/njs_auto_config.h \\
@@ -265,6 +264,26 @@ dist:
&& echo njs-\$(NJS_VER).tar.gz done
 END
 
+if [ $NJS_HAVE_QUICKJS = YES ]; then
+cat << END >> $NJS_MAKEFILE
+
+test262: njs test262_njs test262_quickjs
+
+test262_quickjs: njs
+   NJS_SKIP_LIST="test/js/promise_rejection_tracker_recursive.t.js \\
+test/js/async_exception_in_await.t.js" \\
+   test/test262 --binary='$NJS_BUILD_DIR/njs -n QuickJS -m'
+END
+
+else
+cat << END >> $NJS_MAKEFILE
+
+test262: njs test262_njs
+END
+
+fi
+
+
 njs_ts_deps=`echo $NJS_TS_SRCS \
 | sed -e "s# *\([^ ][^ ]*\)#\1$njs_regex_cont#g"`
 
diff -r 272af619b821 -r cb3e068a511c auto/options
--- a/auto/options  Thu Feb 22 17:38:58 2024 -0800
+++ b/auto/options  Thu Feb 22 20:25:43 2024 -0800
@@ -14,6 +14,7 @@ NJS_DEBUG_GENERATOR=NO
 NJS_ADDRESS_SANITIZER=NO
 NJS_ADDR2LINE=NO
 
+NJS_QUICKJS=YES
 NJS_OPENSSL=YES
 NJS_LIBXML2=YES
 NJS_ZLIB=YES
@@ -47,6 +48,7 @@ do
 --debug-opcode=*)NJS_DEBUG_OPCODE="$value"   ;;
 --debug-generator=*) NJS_DEBUG_GENERATOR="$value";;
 
+--no-quickjs)NJS_QUICKJS=NO  ;;
 --no-openssl)NJS_OPENSSL=NO  ;;
 --no-libxml2)NJS_LIBXML2=NO  ;;
 --no-zlib)   NJS_ZLIB=NO ;;
diff -r 272af619b821 -r cb3e068a511c auto/quickjs
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/auto/quickjs  Thu Feb 22 20:25:43 2024 -0800
@@ -0,0 +1,55 @@
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+
+NJS_QUICKJS_LIB=
+NJS_HAVE_QUICKJS=NO
+
+if [ $NJS_QUICKJS = YES ]; then
+njs_found=no
+
+njs_feature="QuickJS library"
+njs_feature_name=NJS_HAVE_QUICKJS
+njs_feature_run=yes
+njs_feature_incs=
+njs_feature_libs=""
+njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored \"-Wcast-function-type\"
+  #endif
+
+  #include 
+
+  int main() {
+  JSRuntime *rt;
+
+  rt = JS_NewRuntime();
+  JS_FreeRuntime(rt);
+  return 0;
+ }"
+. auto/feature
+
+if [ $njs_found = no ]; then
+njs_feature="QuickJS library -lquickjs.lto"
+njs_feature_incs="/usr/inclu

[njs] Fixed atob() with non-padded base64 strings.

2024-02-22 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/272af619b821
branches:  
changeset: 2289:272af619b821
user:  Dmitry Volyntsev 
date:  Thu Feb 22 17:38:58 2024 -0800
description:
Fixed atob() with non-padded base64 strings.

This fixes #695 issue on Github.

diffstat:

 src/njs_string.c |   9 -
 src/test/njs_unit_test.c |  12 
 2 files changed, 20 insertions(+), 1 deletions(-)

diffs (41 lines):

diff -r 0479e5821ab2 -r 272af619b821 src/njs_string.c
--- a/src/njs_string.c  Wed Feb 14 21:34:02 2024 -0800
+++ b/src/njs_string.c  Thu Feb 22 17:38:58 2024 -0800
@@ -4298,7 +4298,14 @@ njs_string_atob(njs_vm_t *vm, njs_value_
 }
 }
 
-len = njs_base64_decoded_length(str.length, pad);
+len = str.length;
+
+if (len % 4 != 0) {
+pad = 4 - (len % 4);
+len += pad;
+}
+
+len = njs_base64_decoded_length(len, pad);
 
 njs_chb_init(, vm->mem_pool);
 
diff -r 0479e5821ab2 -r 272af619b821 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Wed Feb 14 21:34:02 2024 -0800
+++ b/src/test/njs_unit_test.c  Thu Feb 22 17:38:58 2024 -0800
@@ -10093,6 +10093,18 @@ static njs_unit_test_t  njs_test[] =
   "].every(v => c(atob(v)).toString() == '8,52,86')"),
   njs_str("true")},
 
+{ njs_str("atob('aGVsbG8=')"),
+  njs_str("hello") },
+
+{ njs_str("atob('aGVsbG8')"),
+  njs_str("hello") },
+
+{ njs_str("atob('TQ==')"),
+  njs_str("M") },
+
+{ njs_str("atob('TQ')"),
+  njs_str("M") },
+
 /* Functions. */
 
 { njs_str("return"),
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Moving hash code out of the njs core.

2024-02-14 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/0479e5821ab2
branches:  
changeset: 2288:0479e5821ab2
user:  Dmitry Volyntsev 
date:  Wed Feb 14 21:34:02 2024 -0800
description:
Moving hash code out of the njs core.

diffstat:

 auto/modules |5 +-
 auto/sources |3 -
 external/njs_crypto_module.c |2 +-
 external/njs_hash.h  |   32 
 external/njs_md5.c   |  270 
 external/njs_sha1.c  |  298 
 external/njs_sha2.c  |  320 +++
 src/njs_hash.h   |   32 
 src/njs_main.h   |2 -
 src/njs_md5.c|  266 ---
 src/njs_sha1.c   |  294 ---
 src/njs_sha2.c   |  316 --
 12 files changed, 925 insertions(+), 915 deletions(-)

diffs (truncated from 1914 to 1000 lines):

diff -r 6fa96ea99037 -r 0479e5821ab2 auto/modules
--- a/auto/modules  Wed Feb 14 21:33:56 2024 -0800
+++ b/auto/modules  Wed Feb 14 21:34:02 2024 -0800
@@ -9,7 +9,10 @@ njs_module_srcs=src/njs_buffer.c
 
 njs_module_name=njs_crypto_module
 njs_module_incs=
-njs_module_srcs=external/njs_crypto_module.c
+njs_module_srcs="external/njs_crypto_module.c \
+ external/njs_md5.c \
+ external/njs_sha1.c \
+ external/njs_sha2.c"
 
 . auto/module
 
diff -r 6fa96ea99037 -r 0479e5821ab2 auto/sources
--- a/auto/sources  Wed Feb 14 21:33:56 2024 -0800
+++ b/auto/sources  Wed Feb 14 21:34:02 2024 -0800
@@ -13,9 +13,6 @@ NJS_LIB_SRCS=" \
src/njs_flathsh.c \
src/njs_trace.c \
src/njs_random.c \
-   src/njs_md5.c \
-   src/njs_sha1.c \
-   src/njs_sha2.c \
src/njs_malloc.c \
src/njs_mp.c \
src/njs_sprintf.c \
diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_crypto_module.c
--- a/external/njs_crypto_module.c  Wed Feb 14 21:33:56 2024 -0800
+++ b/external/njs_crypto_module.c  Wed Feb 14 21:34:02 2024 -0800
@@ -6,9 +6,9 @@
 
 
 #include 
-#include 
 #include 
 #include 
+#include "njs_hash.h"
 
 
 typedef void (*njs_hash_init)(njs_hash_t *ctx);
diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_hash.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/external/njs_hash.h   Wed Feb 14 21:34:02 2024 -0800
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#ifndef _NJS_HASH_H_INCLUDED_
+#define _NJS_HASH_H_INCLUDED_
+
+
+typedef struct {
+uint64_t  bytes;
+uint32_t  a, b, c, d, e, f, g, h;
+u_charbuffer[64];
+} njs_hash_t;
+
+
+NJS_EXPORT void njs_md5_init(njs_hash_t *ctx);
+NJS_EXPORT void njs_md5_update(njs_hash_t *ctx, const void *data, size_t size);
+NJS_EXPORT void njs_md5_final(u_char result[32], njs_hash_t *ctx);
+
+NJS_EXPORT void njs_sha1_init(njs_hash_t *ctx);
+NJS_EXPORT void njs_sha1_update(njs_hash_t *ctx, const void *data, size_t 
size);
+NJS_EXPORT void njs_sha1_final(u_char result[32], njs_hash_t *ctx);
+
+NJS_EXPORT void njs_sha2_init(njs_hash_t *ctx);
+NJS_EXPORT void njs_sha2_update(njs_hash_t *ctx, const void *data, size_t 
size);
+NJS_EXPORT void njs_sha2_final(u_char result[32], njs_hash_t *ctx);
+
+
+#endif /* _NJS_HASH_H_INCLUDED_ */
diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_md5.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +
+++ b/external/njs_md5.cWed Feb 14 21:34:02 2024 -0800
@@ -0,0 +1,270 @@
+
+/*
+ * An internal implementation, based on Alexander Peslyak's
+ * public domain implementation:
+ * 
http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include "njs_hash.h"
+
+
+static const u_char *njs_md5_body(njs_hash_t *ctx, const u_char *data,
+size_t size);
+
+
+void
+njs_md5_init(njs_hash_t *ctx)
+{
+ctx->a = 0x67452301;
+ctx->b = 0xefcdab89;
+ctx->c = 0x98badcfe;
+ctx->d = 0x10325476;
+
+ctx->bytes = 0;
+}
+
+
+void
+njs_md5_update(njs_hash_t *ctx, const void *data, size_t size)
+{
+size_t  used, free;
+
+used = (size_t) (ctx->bytes & 0x3f);
+ctx->bytes += size;
+
+if (used) {
+free = 64 - used;
+
+if (size < free) {
+memcpy(>buffer[used], data, size);
+return;
+}
+
+memcpy(>buffer[used], data, free);
+data = (u_char *) data + free;
+size -= free;
+(void) njs_md5_body(ctx, ctx->buffer, 64);
+}
+
+if (size >= 64) {
+data = njs_md5_body(ctx, data, size & ~(size_t) 0x3f);
+size &= 0x3f;
+}
+
+memcpy(ctx->buffer, data, size);
+}
+
+
+void
+njs_md5_final(u_char result[32], njs_hash_t *ctx)
+{
+size_t  used, free;
+
+used = (size_t) (ctx->bytes & 0x3f);
+
+ctx->buffer[used++] 

[njs] Moved njs_time() out of the core as it is not a part of the spec.

2024-02-14 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/6fa96ea99037
branches:  
changeset: 2287:6fa96ea99037
user:  Dmitry Volyntsev 
date:  Wed Feb 14 21:33:56 2024 -0800
description:
Moved njs_time() out of the core as it is not a part of the spec.

diffstat:

 auto/sources |   1 -
 external/njs_shell.c |  21 -
 src/njs_date.c   |  13 +
 src/njs_main.h   |   1 -
 src/njs_time.c   |  27 ---
 src/njs_time.h   |  27 ---
 src/test/njs_benchmark.c |  19 +++
 7 files changed, 52 insertions(+), 57 deletions(-)

diffs (178 lines):

diff -r d3a9f2f153f8 -r 6fa96ea99037 auto/sources
--- a/auto/sources  Wed Feb 07 17:57:02 2024 -0800
+++ b/auto/sources  Wed Feb 14 21:33:56 2024 -0800
@@ -16,7 +16,6 @@ NJS_LIB_SRCS=" \
src/njs_md5.c \
src/njs_sha1.c \
src/njs_sha2.c \
-   src/njs_time.c \
src/njs_malloc.c \
src/njs_mp.c \
src/njs_sprintf.c \
diff -r d3a9f2f153f8 -r 6fa96ea99037 external/njs_shell.c
--- a/external/njs_shell.c  Wed Feb 07 17:57:02 2024 -0800
+++ b/external/njs_shell.c  Wed Feb 14 21:33:56 2024 -0800
@@ -7,7 +7,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -169,6 +168,7 @@ static void njs_console_logger(njs_log_l
 
 static intptr_t njs_event_rbtree_compare(njs_rbtree_node_t *node1,
 njs_rbtree_node_t *node2);
+static uint64_t njs_time(void);
 
 njs_int_t njs_array_buffer_detach(njs_vm_t *vm, njs_value_t *args,
 njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
@@ -2122,3 +2122,22 @@ njs_event_rbtree_compare(njs_rbtree_node
 
 return 0;
 }
+
+
+static uint64_t
+njs_time(void)
+{
+#if (NJS_HAVE_CLOCK_MONOTONIC)
+struct timespec ts;
+
+clock_gettime(CLOCK_MONOTONIC, );
+
+return (uint64_t) ts.tv_sec * 10 + ts.tv_nsec;
+#else
+struct timeval tv;
+
+gettimeofday(, NULL);
+
+return (uint64_t) tv.tv_sec * 10 + tv.tv_usec * 1000;
+#endif
+}
diff -r d3a9f2f153f8 -r 6fa96ea99037 src/njs_date.c
--- a/src/njs_date.cWed Feb 07 17:57:02 2024 -0800
+++ b/src/njs_date.cWed Feb 14 21:33:56 2024 -0800
@@ -22,6 +22,19 @@
 #define NJS_DATE_MSEC   7
 
 
+#if (NJS_HAVE_TM_GMTOFF)
+
+#define njs_timezone(tm)  \
+((tm)->tm_gmtoff)
+
+#elif (NJS_HAVE_ALTZONE)
+
+#define njs_timezone(tm)  \
+(-(((tm)->tm_isdst > 0) ? altzone : timezone))
+
+#endif
+
+
 #define njs_date_magic(field, local)  \
 ((local << 6) + field)
 
diff -r d3a9f2f153f8 -r 6fa96ea99037 src/njs_main.h
--- a/src/njs_main.hWed Feb 07 17:57:02 2024 -0800
+++ b/src/njs_main.hWed Feb 14 21:33:56 2024 -0800
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff -r d3a9f2f153f8 -r 6fa96ea99037 src/njs_time.c
--- a/src/njs_time.cWed Feb 07 17:57:02 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,27 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-
-#include 
-
-
-uint64_t
-njs_time(void)
-{
-#if (NJS_HAVE_CLOCK_MONOTONIC)
-struct timespec ts;
-
-clock_gettime(CLOCK_MONOTONIC, );
-
-return (uint64_t) ts.tv_sec * 10 + ts.tv_nsec;
-#else
-struct timeval tv;
-
-gettimeofday(, NULL);
-
-return (uint64_t) tv.tv_sec * 10 + tv.tv_usec * 1000;
-#endif
-}
diff -r d3a9f2f153f8 -r 6fa96ea99037 src/njs_time.h
--- a/src/njs_time.hWed Feb 07 17:57:02 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,27 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-#ifndef _NJS_TIME_H_INCLUDED_
-#define _NJS_TIME_H_INCLUDED_
-
-
-#if (NJS_HAVE_TM_GMTOFF)
-
-#define njs_timezone(tm)  \
-((tm)->tm_gmtoff)
-
-#elif (NJS_HAVE_ALTZONE)
-
-#define njs_timezone(tm)  \
-(-(((tm)->tm_isdst > 0) ? altzone : timezone))
-
-#endif
-
-
-uint64_t njs_time(void);
-
-
-#endif /* _NJS_TIME_H_INCLUDED_ */
diff -r d3a9f2f153f8 -r 6fa96ea99037 src/test/njs_benchmark.c
--- a/src/test/njs_benchmark.c  Wed Feb 07 17:57:02 2024 -0800
+++ b/src/test/njs_benchmark.c  Wed Feb 14 21:33:56 2024 -0800
@@ -35,6 +35,25 @@ njs_module_t *njs_benchmark_addon_extern
 };
 
 
+static uint64_t
+njs_time(void)
+{
+#if (NJS_HAVE_CLOCK_MONOTONIC)
+struct timespec ts;
+
+clock_gettime(CLOCK_MONOTONIC, );
+
+return (uint64_t) ts.tv_sec * 10 + ts.tv_nsec;
+#else
+struct timeval tv;
+
+gettimeofday(, NULL);
+
+return (uint64_t) tv.tv_sec * 10 + tv.tv_usec * 1000;
+#endif
+}
+
+
 static njs_int_t
 njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report,
 njs_benchmark_test_t *test)

[njs] Test262: fix import_global_ref_var.t.js.

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/d3a9f2f153f8
branches:  
changeset: 2286:d3a9f2f153f8
user:  Dmitry Volyntsev 
date:  Wed Feb 07 17:57:02 2024 -0800
description:
Test262: fix import_global_ref_var.t.js.

diffstat:

 test/js/import_global_ref_var.t.js |  2 +-
 test/js/module/export_global_a.js  |  2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diffs (22 lines):

diff -r 82ae061db9d0 -r d3a9f2f153f8 test/js/import_global_ref_var.t.js
--- a/test/js/import_global_ref_var.t.jsWed Feb 07 17:57:01 2024 -0800
+++ b/test/js/import_global_ref_var.t.jsWed Feb 07 17:57:02 2024 -0800
@@ -4,7 +4,7 @@ flags: []
 paths: [test/js/module/]
 ---*/
 
-var a = 42;
+globalThis.a = 42;
 import m from 'export_global_a.js';
 
 assert.sameValue(m.f(), 42);
diff -r 82ae061db9d0 -r d3a9f2f153f8 test/js/module/export_global_a.js
--- a/test/js/module/export_global_a.js Wed Feb 07 17:57:01 2024 -0800
+++ b/test/js/module/export_global_a.js Wed Feb 07 17:57:02 2024 -0800
@@ -1,5 +1,5 @@
 function f() {
-return a;
+return globalThis.a;
 }
 
 export default {f};
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Test262: simplified import_chain.t.js.

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/82ae061db9d0
branches:  
changeset: 2285:82ae061db9d0
user:  Dmitry Volyntsev 
date:  Wed Feb 07 17:57:01 2024 -0800
description:
Test262: simplified import_chain.t.js.

Avoid using "crypto" module, which unnessesary complicates the test.

diffstat:

 test/js/import_chain.t.js   |  8 ++--
 test/js/module/libs/hash.js |  5 +
 test/js/module/sub/sub1.js  |  3 +--
 3 files changed, 4 insertions(+), 12 deletions(-)

diffs (49 lines):

diff -r 45f72ce8761b -r 82ae061db9d0 test/js/import_chain.t.js
--- a/test/js/import_chain.t.js Wed Feb 07 17:57:01 2024 -0800
+++ b/test/js/import_chain.t.js Wed Feb 07 17:57:01 2024 -0800
@@ -4,10 +4,6 @@ flags: []
 paths: [test/js/module/, test/js/module/libs/, test/js/module/sub]
 ---*/
 
-import lib2   from 'lib2.js';
+import lib2 from 'lib2.js';
 
-import crypto from 'crypto';
-var h = crypto.createHash('md5');
-var hash = h.update('AB').digest('hex');
-
-assert.sameValue(lib2.hash(), hash);
+assert.sameValue(lib2.hash(), "XXX");
diff -r 45f72ce8761b -r 82ae061db9d0 test/js/module/libs/hash.js
--- a/test/js/module/libs/hash.js   Wed Feb 07 17:57:01 2024 -0800
+++ b/test/js/module/libs/hash.js   Wed Feb 07 17:57:01 2024 -0800
@@ -1,11 +1,8 @@
 function hash() {
-var h = crypto.createHash('md5');
-var v = h.update('AB').digest('hex');
-return v;
+return "XXX";
 }
 
 import sub from 'sub/sub3.js';
 import name from 'name.js';
-import crypto from 'crypto';
 
 export default {hash, name};
diff -r 45f72ce8761b -r 82ae061db9d0 test/js/module/sub/sub1.js
--- a/test/js/module/sub/sub1.jsWed Feb 07 17:57:01 2024 -0800
+++ b/test/js/module/sub/sub1.jsWed Feb 07 17:57:01 2024 -0800
@@ -1,5 +1,5 @@
 function hash() {
-return sub2.hash(crypto);
+return sub2.hash();
 }
 
 function error() {
@@ -7,6 +7,5 @@ function error() {
 }
 
 import sub2 from 'sub2.js';
-import crypto from 'crypto';
 
 export default {hash, error};
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Removed njs_file.c not needed after 8aad26845b18 (0.8.3).

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/45f72ce8761b
branches:  
changeset: 2284:45f72ce8761b
user:  Dmitry Volyntsev 
date:  Wed Feb 07 17:57:01 2024 -0800
description:
Removed njs_file.c not needed after 8aad26845b18 (0.8.3).

diffstat:

 auto/sources |   1 -
 src/njs_file.c   |  69 -
 src/njs_file.h   |  15 ---
 src/njs_main.h   |   1 -
 src/test/njs_unit_test.c |  98 
 5 files changed, 0 insertions(+), 184 deletions(-)

diffs (236 lines):

diff -r 93562e512d26 -r 45f72ce8761b auto/sources
--- a/auto/sources  Wed Feb 07 17:56:59 2024 -0800
+++ b/auto/sources  Wed Feb 07 17:57:01 2024 -0800
@@ -17,7 +17,6 @@ NJS_LIB_SRCS=" \
src/njs_sha1.c \
src/njs_sha2.c \
src/njs_time.c \
-   src/njs_file.c \
src/njs_malloc.c \
src/njs_mp.c \
src/njs_sprintf.c \
diff -r 93562e512d26 -r 45f72ce8761b src/njs_file.c
--- a/src/njs_file.cWed Feb 07 17:56:59 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,69 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-
-#include 
-
-
-void
-njs_file_basename(const njs_str_t *path, njs_str_t *name)
-{
-const u_char  *p, *end;
-
-end = path->start + path->length;
-p = end - 1;
-
-/* Stripping dir prefix. */
-
-while (p >= path->start && *p != '/') { p--; }
-
-p++;
-
-name->start = (u_char *) p;
-name->length = end - p;
-}
-
-
-void
-njs_file_dirname(const njs_str_t *path, njs_str_t *name)
-{
-const u_char  *p, *end;
-
-if (path->length == 0) {
-goto current_dir;
-}
-
-p = path->start + path->length - 1;
-
-/* Stripping basename. */
-
-while (p >= path->start && *p != '/') { p--; }
-
-end = p + 1;
-
-if (end == path->start) {
-goto current_dir;
-}
-
-/* Stripping trailing slashes. */
-
-while (p >= path->start && *p == '/') { p--; }
-
-p++;
-
-if (p == path->start) {
-p = end;
-}
-
-name->start = path->start;
-name->length = p - path->start;
-
-return;
-
-current_dir:
-
-*name = njs_str_value(".");
-}
diff -r 93562e512d26 -r 45f72ce8761b src/njs_file.h
--- a/src/njs_file.hWed Feb 07 17:56:59 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,15 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-#ifndef _NJS_FILE_H_INCLUDED_
-#define _NJS_FILE_H_INCLUDED_
-
-
-void njs_file_basename(const njs_str_t *path, njs_str_t *name);
-void njs_file_dirname(const njs_str_t *path, njs_str_t *name);
-
-
-#endif /* _NJS_FILE_H_INCLUDED_ */
diff -r 93562e512d26 -r 45f72ce8761b src/njs_main.h
--- a/src/njs_main.hWed Feb 07 17:56:59 2024 -0800
+++ b/src/njs_main.hWed Feb 07 17:57:01 2024 -0800
@@ -28,7 +28,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff -r 93562e512d26 -r 45f72ce8761b src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Wed Feb 07 17:56:59 2024 -0800
+++ b/src/test/njs_unit_test.c  Wed Feb 07 17:57:01 2024 -0800
@@ -6,7 +6,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -24449,99 +24448,6 @@ njs_vm_object_alloc_test(njs_vm_t *vm, n
 
 
 static njs_int_t
-njs_file_basename_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat)
-{
-njs_str_t   name;
-njs_bool_t  success;
-njs_uint_t  i;
-
-static const struct {
-njs_str_t   path;
-njs_str_t   expected;
-} tests[] = {
-{ njs_str(""),njs_str("") },
-{ njs_str("/"),   njs_str("") },
-{ njs_str("/a"),  njs_str("a") },
-{ njs_str("///"), njs_str("") },
-{ njs_str("///a"),njs_str("a") },
-{ njs_str("///a/"),   njs_str("") },
-{ njs_str("a"),   njs_str("a") },
-{ njs_str("a/"),  njs_str("") },
-{ njs_str("a//"), njs_str("") },
-{ njs_str("path/name"),   njs_str("name") },
-{ njs_str("/path/name"),  njs_str("name") },
-{ njs_str("/path/name/"), njs_str("") },
-};
-
-for (i = 0; i < njs_nitems(tests); i++) {
-njs_file_basename([i].path, );
-
-success = njs_strstr_eq([i].expected, );
-
-if (!success) {
-njs_printf("njs_file_basename_test(\"%V\"):\n"
-   "expected: \"%V\"\n got: \"%V\"\n",
-   [i].path, [i].expected, );
-
-stat->failed++;
-
-} else {
-stat->passed++;
-}
-}
-

[njs] Version bump.

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/93562e512d26
branches:  
changeset: 2283:93562e512d26
user:  Dmitry Volyntsev 
date:  Wed Feb 07 17:56:59 2024 -0800
description:
Version bump.

diffstat:

 src/njs.h |  4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diffs (14 lines):

diff -r f98dd6884786 -r 93562e512d26 src/njs.h
--- a/src/njs.h Wed Feb 07 08:34:17 2024 -0800
+++ b/src/njs.h Wed Feb 07 17:56:59 2024 -0800
@@ -11,8 +11,8 @@
 
 #include 
 
-#define NJS_VERSION "0.8.3"
-#define NJS_VERSION_NUMBER  0x000803
+#define NJS_VERSION "0.8.4"
+#define NJS_VERSION_NUMBER  0x000804
 
 
 #include 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


njs-0.8.3

2024-02-07 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

This release focuses on stabilization of recently released features
and fixing bugs found by various fuzzers.

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues
- Mailing list:
  https://mailman.nginx.org/mailman/listinfo/nginx-devel

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.3   07 Feb 2024

    nginx modules:

    *) Bugfix: fixed Headers.set().

    *) Bugfix: fixed js_set with Buffer values.

    *) Bugfix: fixed clear() method of a shared dictionary when
   timeout is not specified.

    *) Bugfix: fixed stub_status statistic when js_periodic is
   enabled.

    Core:

    *) Bugfix: fixed building with libxml2 2.12 and later.

    *) Bugfix: fixed Date constructor for overflows and with
   NaN values.

    *) Bugfix: fixed underflow in querystring.parse().

    *) Bugfix: fixed potential buffer overread in
   String.prototype.match().

    *) Bugfix: fixed parsing of for-in loops.

    *) Bugfix: fixed parsing of hexadecimal, octal, and binary
   literals with no digits.
___
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx


[nginx-announce] njs-0.8.3

2024-02-07 Thread Dmitry Volyntsev

Hello,

I'm glad to announce a new release of NGINX JavaScript module (njs).

This release focuses on stabilization of recently released features
and fixing bugs found by various fuzzers.

Learn more about njs:

- Overview and introduction:
  https://nginx.org/en/docs/njs/
- NGINX JavaScript in Your Web Server Configuration:
  https://youtu.be/Jc_L6UffFOs
- Extending NGINX with Custom Code:
  https://youtu.be/0CVhq4AUU7M
- Using node modules with njs:
  https://nginx.org/en/docs/njs/node_modules.html
- Writing njs code using TypeScript definition files:
  https://nginx.org/en/docs/njs/typescript.html

Feel free to try it and give us feedback on:

- Github:
  https://github.com/nginx/njs/issues
- Mailing list:
  https://mailman.nginx.org/mailman/listinfo/nginx-devel

Additional examples and howtos can be found here:

- Github:
  https://github.com/nginx/njs-examples

Changes with njs 0.8.3   07 Feb 2024

    nginx modules:

    *) Bugfix: fixed Headers.set().

    *) Bugfix: fixed js_set with Buffer values.

    *) Bugfix: fixed clear() method of a shared dictionary when
   timeout is not specified.

    *) Bugfix: fixed stub_status statistic when js_periodic is
   enabled.

    Core:

    *) Bugfix: fixed building with libxml2 2.12 and later.

    *) Bugfix: fixed Date constructor for overflows and with
   NaN values.

    *) Bugfix: fixed underflow in querystring.parse().

    *) Bugfix: fixed potential buffer overread in
   String.prototype.match().

    *) Bugfix: fixed parsing of for-in loops.

    *) Bugfix: fixed parsing of hexadecimal, octal, and binary
   literals with no digits.
___
nginx-announce mailing list
nginx-announce@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-announce


[njs] Added tag 0.8.3 for changeset 3aba7ee62080

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f98dd6884786
branches:  
changeset: 2282:f98dd6884786
user:  Dmitry Volyntsev 
date:  Wed Feb 07 08:34:17 2024 -0800
description:
Added tag 0.8.3 for changeset 3aba7ee62080

diffstat:

 .hgtags |  1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diffs (8 lines):

diff -r 3aba7ee62080 -r f98dd6884786 .hgtags
--- a/.hgtags   Wed Feb 07 08:34:00 2024 -0800
+++ b/.hgtags   Wed Feb 07 08:34:17 2024 -0800
@@ -65,3 +65,4 @@ a1faa64d4972020413fd168e2b542bcc150819c0
 0ed1952588ab1e0e1c18425fe7923b2b76f38a65 0.8.0
 a52b49f9afcf410597dc6657ad39ae3dbbfeec56 0.8.1
 45f81882c780a12e56be519cd3106c4fe5567a64 0.8.2
+3aba7ee620807ad10bc34bff3677350fa8a3c3b2 0.8.3
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Version 0.8.3.

2024-02-07 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/3aba7ee62080
branches:  
changeset: 2281:3aba7ee62080
user:  Dmitry Volyntsev 
date:  Wed Feb 07 08:34:00 2024 -0800
description:
Version 0.8.3.

diffstat:

 CHANGES |  31 +++
 1 files changed, 31 insertions(+), 0 deletions(-)

diffs (38 lines):

diff -r 25e548de3d61 -r 3aba7ee62080 CHANGES
--- a/CHANGES   Tue Feb 06 19:32:08 2024 -0800
+++ b/CHANGES   Wed Feb 07 08:34:00 2024 -0800
@@ -1,3 +1,34 @@
+Changes with njs 0.8.3   07 Feb 2024
+
+nginx modules:
+
+*) Bugfix: fixed Headers.set().
+
+*) Bugfix: fixed js_set with Buffer values.
+
+*) Bugfix: fixed clear() method of a shared dictionary when
+   a timeout is not specified.
+
+*) Bugfix: fixed stub_status statistics when js_periodic is
+   enabled.
+
+Core:
+
+*) Bugfix: fixed building with libxml2 2.12 and later.
+
+*) Bugfix: fixed Date constructor for overflows and with
+   NaN values.
+
+*) Bugfix: fixed underflow in querystring.parse().
+
+*) Bugfix: fixed potential buffer overread in
+   String.prototype.match().
+
+*) Bugfix: fixed parsing of for-in loops.
+
+*) Bugfix: fixed parsing of hexadecimal, octal, and binary
+   literals with no digits.
+
 Changes with njs 0.8.2   24 Oct 2023
 
 nginx modules:
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Reverted changes introduced in 7eaaa7d57636 (not released) back.

2024-02-06 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/25e548de3d61
branches:  
changeset: 2280:25e548de3d61
user:  Dmitry Volyntsev 
date:  Tue Feb 06 19:32:08 2024 -0800
description:
Reverted changes introduced in 7eaaa7d57636 (not released) back.

Relative importing is again supported.

diffstat:

 external/njs_shell.c  |  101 -
 nginx/ngx_js.c|   88 -
 nginx/ngx_js.h|1 +
 nginx/t/js_import_relative.t  |  100 +
 test/js/import_relative_path.t.js |9 +++
 test/js/module/libs/hash.js   |1 +
 test/js/module/sub/sub3.js|1 +
 7 files changed, 296 insertions(+), 5 deletions(-)

diffs (468 lines):

diff -r 673d78618fc9 -r 25e548de3d61 external/njs_shell.c
--- a/external/njs_shell.c  Wed Jan 31 17:06:58 2024 -0800
+++ b/external/njs_shell.c  Tue Feb 06 19:32:08 2024 -0800
@@ -115,6 +115,8 @@ typedef struct {
 
 njs_queue_t labels;
 
+njs_str_t   cwd;
+
 njs_arr_t   *rejected_promises;
 
 njs_bool_t  suppress_stdout;
@@ -693,6 +695,8 @@ njs_console_init(njs_vm_t *vm, njs_conso
 njs_queue_init(>posted_events);
 njs_queue_init(>labels);
 
+njs_memzero(>cwd, sizeof(njs_str_t));
+
 console->rejected_promises = NULL;
 
 console->completion.completions = njs_vm_completions(vm, NULL);
@@ -869,7 +873,7 @@ njs_module_path(const njs_str_t *dir, nj
 if (dir != NULL) {
 length += dir->length;
 
-if (length == 0) {
+if (length == 0 || dir->length == 0) {
 return NJS_DECLINED;
 }
 
@@ -915,7 +919,8 @@ njs_module_path(const njs_str_t *dir, nj
 
 
 static njs_int_t
-njs_module_lookup(njs_opts_t *opts, njs_module_info_t *info)
+njs_module_lookup(njs_opts_t *opts, const njs_str_t *cwd,
+njs_module_info_t *info)
 {
 njs_int_t   ret;
 njs_str_t   *path;
@@ -925,6 +930,12 @@ njs_module_lookup(njs_opts_t *opts, njs_
 return njs_module_path(NULL, info);
 }
 
+ret = njs_module_path(cwd, info);
+
+if (ret != NJS_DECLINED) {
+return ret;
+}
+
 path = opts->paths;
 
 for (i = 0; i < opts->n_paths; i++) {
@@ -980,23 +991,86 @@ fail:
 }
 
 
+static void
+njs_file_dirname(const njs_str_t *path, njs_str_t *name)
+{
+const u_char  *p, *end;
+
+if (path->length == 0) {
+goto current_dir;
+}
+
+p = path->start + path->length - 1;
+
+/* Stripping basename. */
+
+while (p >= path->start && *p != '/') { p--; }
+
+end = p + 1;
+
+if (end == path->start) {
+goto current_dir;
+}
+
+/* Stripping trailing slashes. */
+
+while (p >= path->start && *p == '/') { p--; }
+
+p++;
+
+if (p == path->start) {
+p = end;
+}
+
+name->start = path->start;
+name->length = p - path->start;
+
+return;
+
+current_dir:
+
+*name = njs_str_value(".");
+}
+
+
+static njs_int_t
+njs_console_set_cwd(njs_vm_t *vm, njs_console_t *console, njs_str_t *file)
+{
+njs_str_t  cwd;
+
+njs_file_dirname(file, );
+
+console->cwd.start = njs_mp_alloc(njs_vm_memory_pool(vm), cwd.length);
+if (njs_slow_path(console->cwd.start == NULL)) {
+return NJS_ERROR;
+}
+
+memcpy(console->cwd.start, cwd.start, cwd.length);
+console->cwd.length = cwd.length;
+
+return NJS_OK;
+}
+
+
 static njs_mod_t *
 njs_module_loader(njs_vm_t *vm, njs_external_ptr_t external, njs_str_t *name)
 {
 u_char *start;
 njs_int_t  ret;
-njs_str_t  text;
+njs_str_t  text, prev_cwd;
 njs_mod_t  *module;
 njs_opts_t *opts;
+njs_console_t  *console;
 njs_module_info_t  info;
 
 opts = external;
+console = njs_vm_external_ptr(vm);
 
 njs_memzero(, sizeof(njs_module_info_t));
 
 info.name = *name;
 
-ret = njs_module_lookup(opts, );
+ret = njs_module_lookup(opts, >cwd, );
 if (njs_slow_path(ret != NJS_OK)) {
 return NULL;
 }
@@ -1010,11 +1084,23 @@ njs_module_loader(njs_vm_t *vm, njs_exte
 return NULL;
 }
 
+prev_cwd = console->cwd;
+
+ret = njs_console_set_cwd(vm, console, );
+if (njs_slow_path(ret != NJS_OK)) {
+njs_vm_internal_error(vm, "while setting cwd for \"%V\" module",
+  );
+return NULL;
+}
+
 start = text.start;
 
 module = njs_vm_compile_module(vm, , ,
[text.length]);
 
+njs_mp_free(njs_vm_memory_pool(vm), console->cwd.start);
+console->cwd = prev_cwd;
+
 njs_mp_free(njs_vm_memory_pool(vm), text.start);
 
 return module;
@@ -1025,6 +,7 @@ static njs_vm_t *
 njs_create_vm(njs_opts_t *opts)
 {
 njs_vm_t  *vm;
+  

[njs] HTTP: fixed stub_status statistic when js_periodic is enabled.

2024-01-31 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/673d78618fc9
branches:  
changeset: 2279:673d78618fc9
user:  Dmitry Volyntsev 
date:  Wed Jan 31 17:06:58 2024 -0800
description:
HTTP: fixed stub_status statistic when js_periodic is enabled.

Previously, when js_periodic is enabled the Reading statistic
was growing each time the js_periodic handler was called.

The issue was introduced in f1bd0b1db065 (0.8.1).

This fixes #692 issue on Github.

diffstat:

 nginx/ngx_http_js_module.c |  16 +---
 1 files changed, 5 insertions(+), 11 deletions(-)

diffs (39 lines):

diff -r fca50ba4db9d -r 673d78618fc9 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cMon Jan 29 17:16:08 2024 -0800
+++ b/nginx/ngx_http_js_module.cWed Jan 31 17:06:58 2024 -0800
@@ -4323,30 +4323,24 @@ ngx_http_js_periodic_finalize(ngx_http_r
 static void
 ngx_http_js_periodic_destroy(ngx_http_request_t *r, ngx_js_periodic_t 
*periodic)
 {
-ngx_connection_t*c;
-ngx_http_cleanup_t  *cln;
+ngx_connection_t  *c;
 
 c = r->connection;
 
 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-   "http js periodic destroy: \"%V\"",
-   >method);
+   "http js periodic destroy: \"%V\"", >method);
 
 periodic->connection = NULL;
 
-for (cln = r->cleanup; cln; cln = cln->next) {
-if (cln->handler) {
-cln->handler(cln->data);
-}
-}
+r->logged = 1;
+
+ngx_http_free_request(r, NGX_OK);
 
 ngx_free_connection(c);
 
 c->fd = (ngx_socket_t) -1;
 c->pool = NULL;
 c->destroyed = 1;
-
-ngx_destroy_pool(r->pool);
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Style.

2024-01-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/fca50ba4db9d
branches:  
changeset: 2278:fca50ba4db9d
user:  Dmitry Volyntsev 
date:  Mon Jan 29 17:16:08 2024 -0800
description:
Style.

diffstat:

 src/njs_builtin.c |   2 +-
 src/njs_clang.h   |  26 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diffs (48 lines):

diff -r 478795e3296b -r fca50ba4db9d src/njs_builtin.c
--- a/src/njs_builtin.c Mon Jan 29 17:16:07 2024 -0800
+++ b/src/njs_builtin.c Mon Jan 29 17:16:08 2024 -0800
@@ -28,7 +28,7 @@ static njs_int_t njs_global_this_prop_ha
 static njs_arr_t *njs_vm_expression_completions(njs_vm_t *vm,
 njs_str_t *expression);
 static njs_arr_t *njs_vm_global_var_completions(njs_vm_t *vm,
-   njs_str_t *expression);
+njs_str_t *expression);
 static njs_arr_t *njs_object_completions(njs_vm_t *vm, njs_value_t *object,
 njs_str_t *expression);
 static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
diff -r 478795e3296b -r fca50ba4db9d src/njs_clang.h
--- a/src/njs_clang.h   Mon Jan 29 17:16:07 2024 -0800
+++ b/src/njs_clang.h   Mon Jan 29 17:16:08 2024 -0800
@@ -193,19 +193,19 @@ njs_leading_zeros64(uint64_t x)
 njs_inline NJS_NOSANITIZE("float-cast-overflow") int64_t
 njs_unsafe_cast_double_to_int64(double num)
 {
-   /*
-* Casting NaN to integer is undefined behavior,
-* but it is fine in some cases where we do additional checks later.
-* For example:
-*  int64_t i64 = njs_unsafe_cast_double_to_int64(num);
-*  if (i64 == num) {
-*// num is integer
-*  }
-*
-* We do this as inline function to avoid UndefinedBehaviorSanitizer
-* warnings.
-*/
-   return (int64_t) num;
+/*
+ * Casting NaN to integer is undefined behavior,
+ * but it is fine in some cases where we do additional checks later.
+ * For example:
+ *  int64_t i64 = njs_unsafe_cast_double_to_int64(num);
+ *  if (i64 == num) {
+ *// num is integer
+ *  }
+ *
+ * We do this as inline function to avoid UndefinedBehaviorSanitizer
+ * warnings.
+ */
+return (int64_t) num;
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] 2024 year.

2024-01-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/478795e3296b
branches:  
changeset: 2277:478795e3296b
user:  Dmitry Volyntsev 
date:  Mon Jan 29 17:16:07 2024 -0800
description:
2024 year.

diffstat:

 LICENSE |  6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diffs (16 lines):

diff -r 9e2a757cb33e -r 478795e3296b LICENSE
--- a/LICENSE   Mon Jan 29 17:16:01 2024 -0800
+++ b/LICENSE   Mon Jan 29 17:16:07 2024 -0800
@@ -1,9 +1,9 @@
 /*
- * Copyright (C) 2015-2023 NGINX, Inc.
+ * Copyright (C) 2015-2024 NGINX, Inc.
  * Copyright (C) 2015-2021 Igor Sysoev
- * Copyright (C) 2017-2023 Dmitry Volyntsev
+ * Copyright (C) 2017-2024 Dmitry Volyntsev
  * Copyright (C) 2019-2022 Alexander Borisov
- * Copyright (C) 2022-2023 Vadim Zhestikov
+ * Copyright (C) 2022-2024 Vadim Zhestikov
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Test262: handling the mkdir issue with a host file system.

2024-01-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/9e2a757cb33e
branches:  
changeset: 2276:9e2a757cb33e
user:  Dmitry Volyntsev 
date:  Mon Jan 29 17:16:01 2024 -0800
description:
Test262: handling the mkdir issue with a host file system.

diffstat:

 test/fs/promises_05.t.js |  13 -
 1 files changed, 12 insertions(+), 1 deletions(-)

diffs (23 lines):

diff -r a2959e490279 -r 9e2a757cb33e test/fs/promises_05.t.js
--- a/test/fs/promises_05.t.js  Mon Jan 29 08:57:49 2024 -0800
+++ b/test/fs/promises_05.t.js  Mon Jan 29 17:16:01 2024 -0800
@@ -49,7 +49,18 @@ var testSync = () => new Promise((resolv
 try {
 fs.writeFileSync(fname(dname_utf8), fname(dname_utf8));
 
-throw new Error('fs.mkdirSync error 1');
+const mode = fs.statSync(fname(dname_utf8)).mode & 0o777;
+
+if (mode == 0o555) {
+/*
+ * Some file systems ignore the mode parameter for mkdir.
+ * For example: a shared folder on a MacOS host mounted
+ * to a Linux guest via Parallels Desktop.
+ */
+throw new Error('fs.writeFileSync did not respect mode');
+}
+
+fs.unlinkSync(fname(dname_utf8));
 
 } catch (e) {
 if (e.syscall != 'open' || e.code != 'EACCES') {
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed fuzzer build after 9b3dac56fd8a.

2024-01-25 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/6770c015efdc
branches:  
changeset: 2273:6770c015efdc
user:  Dmitry Volyntsev 
date:  Thu Jan 25 14:48:05 2024 -0800
description:
Fixed fuzzer build after 9b3dac56fd8a.

diffstat:

 external/njs_shell.c |  60 +++
 1 files changed, 27 insertions(+), 33 deletions(-)

diffs (120 lines):

diff -r 9b3dac56fd8a -r 6770c015efdc external/njs_shell.c
--- a/external/njs_shell.c  Tue Jan 23 16:34:10 2024 -0800
+++ b/external/njs_shell.c  Thu Jan 25 14:48:05 2024 -0800
@@ -137,8 +137,7 @@ static njs_int_t njs_process_script(njs_
 #ifndef NJS_FUZZER_TARGET
 
 static njs_int_t njs_options_parse(njs_opts_t *opts, int argc, char **argv);
-static njs_int_t njs_options_add_path(njs_opts_t *opts, u_char *path,
-size_t len);
+static njs_int_t njs_options_add_path(njs_opts_t *opts, char *path, size_t 
len);
 static void njs_options_free(njs_opts_t *opts);
 
 #ifdef NJS_HAVE_READLINE
@@ -400,7 +399,8 @@ done:
 static njs_int_t
 njs_options_parse(njs_opts_t *opts, int argc, char **argv)
 {
-char*p;
+char*p, *start;
+size_t  len;
 njs_int_t   i, ret;
 njs_uint_t  n;
 
@@ -447,6 +447,27 @@ njs_options_parse(njs_opts_t *opts, int 
 opts->exit_code = atoi(p);
 }
 
+start = getenv("NJS_PATH");
+if (start != NULL) {
+for ( ;; ) {
+p = (char *) njs_strchr(start, ':');
+
+len = (p != NULL) ? (size_t) (p - start) : njs_strlen(start);
+
+ret = njs_options_add_path(opts, start, len);
+if (ret != NJS_OK) {
+njs_stderror("failed to add path\n");
+return NJS_ERROR;
+}
+
+if (p == NULL) {
+break;
+}
+
+start = p + 1;
+}
+}
+
 for (i = 1; i < argc; i++) {
 
 p = argv[i];
@@ -526,8 +547,7 @@ njs_options_parse(njs_opts_t *opts, int 
 
 case 'p':
 if (++i < argc) {
-ret = njs_options_add_path(opts, (u_char *) argv[i],
-   njs_strlen(argv[i]));
+ret = njs_options_add_path(opts, argv[i], njs_strlen(argv[i]));
 if (ret != NJS_OK) {
 njs_stderror("failed to add path\n");
 return NJS_ERROR;
@@ -604,7 +624,7 @@ done:
 
 
 static njs_int_t
-njs_options_add_path(njs_opts_t *opts, u_char *path, size_t len)
+njs_options_add_path(njs_opts_t *opts, char *path, size_t len)
 {
 njs_str_t  *paths;
 
@@ -617,7 +637,7 @@ njs_options_add_path(njs_opts_t *opts, u
 }
 
 opts->paths = paths;
-opts->paths[opts->n_paths - 1].start = path;
+opts->paths[opts->n_paths - 1].start = (u_char *) path;
 opts->paths[opts->n_paths - 1].length = len;
 
 return NJS_OK;
@@ -1004,10 +1024,7 @@ njs_module_loader(njs_vm_t *vm, njs_exte
 static njs_vm_t *
 njs_create_vm(njs_opts_t *opts)
 {
-size_tlen;
-u_char*p, *start;
 njs_vm_t  *vm;
-njs_int_t ret;
 njs_vm_opt_t  vm_options;
 
 njs_vm_opt_init(_options);
@@ -1053,29 +1070,6 @@ njs_create_vm(njs_opts_t *opts)
 
 njs_vm_set_module_loader(vm, njs_module_loader, opts);
 
-start = (u_char *) getenv("NJS_PATH");
-if (start == NULL) {
-return vm;
-}
-
-for ( ;; ) {
-p = njs_strchr(start, ':');
-
-len = (p != NULL) ? (size_t) (p - start) : njs_strlen(start);
-
-ret = njs_options_add_path(opts, start, len);
-if (ret != NJS_OK) {
-njs_stderror("failed to add path\n");
-return NULL;
-}
-
-if (p == NULL) {
-break;
-}
-
-start = p + 1;
-}
-
 return vm;
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Moving out HostLoadImportedModule from njs core.

2024-01-23 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/9b3dac56fd8a
branches:  
changeset: 2272:9b3dac56fd8a
user:  Dmitry Volyntsev 
date:  Tue Jan 23 16:34:10 2024 -0800
description:
Moving out HostLoadImportedModule from njs core.

HostLoadImportedModule should be implemented by host
environment according to ECMAScript specs.

The following method was removed: njs_vm_add_path().

diffstat:

 external/njs_shell.c |  230 +-
 nginx/ngx_js.c   |  211 ++
 src/njs.h|2 -
 src/njs_module.c |  230 ---
 src/njs_module.h |1 -
 src/njs_parser.c |   39 
 src/njs_vm.c |   23 -
 src/njs_vm.h |1 -
 8 files changed, 438 insertions(+), 299 deletions(-)

diffs (915 lines):

diff -r 7eaaa7d57636 -r 9b3dac56fd8a external/njs_shell.c
--- a/external/njs_shell.c  Tue Jan 23 16:33:52 2024 -0800
+++ b/external/njs_shell.c  Tue Jan 23 16:34:10 2024 -0800
@@ -47,7 +47,7 @@ typedef struct {
 char*file;
 njs_str_t   command;
 size_t  n_paths;
-char**paths;
+njs_str_t   *paths;
 char**argv;
 njs_uint_t  argc;
 } njs_opts_t;
@@ -99,6 +99,14 @@ typedef struct {
 
 
 typedef struct {
+int fd;
+njs_str_t   name;
+njs_str_t   file;
+charpath[NJS_MAX_PATH + 1];
+} njs_module_info_t;
+
+
+typedef struct {
 njs_vm_t*vm;
 
 uint32_tevent_id;
@@ -129,6 +137,8 @@ static njs_int_t njs_process_script(njs_
 #ifndef NJS_FUZZER_TARGET
 
 static njs_int_t njs_options_parse(njs_opts_t *opts, int argc, char **argv);
+static njs_int_t njs_options_add_path(njs_opts_t *opts, u_char *path,
+size_t len);
 static void njs_options_free(njs_opts_t *opts);
 
 #ifdef NJS_HAVE_READLINE
@@ -390,7 +400,7 @@ done:
 static njs_int_t
 njs_options_parse(njs_opts_t *opts, int argc, char **argv)
 {
-char*p, **paths;
+char*p;
 njs_int_t   i, ret;
 njs_uint_t  n;
 
@@ -516,15 +526,13 @@ njs_options_parse(njs_opts_t *opts, int 
 
 case 'p':
 if (++i < argc) {
-opts->n_paths++;
-paths = realloc(opts->paths, opts->n_paths * sizeof(char *));
-if (paths == NULL) {
+ret = njs_options_add_path(opts, (u_char *) argv[i],
+   njs_strlen(argv[i]));
+if (ret != NJS_OK) {
 njs_stderror("failed to add path\n");
 return NJS_ERROR;
 }
 
-opts->paths = paths;
-opts->paths[opts->n_paths - 1] = argv[i];
 break;
 }
 
@@ -595,6 +603,27 @@ done:
 }
 
 
+static njs_int_t
+njs_options_add_path(njs_opts_t *opts, u_char *path, size_t len)
+{
+njs_str_t  *paths;
+
+opts->n_paths++;
+
+paths = realloc(opts->paths, opts->n_paths * sizeof(njs_str_t));
+if (paths == NULL) {
+njs_stderror("failed to add path\n");
+return NJS_ERROR;
+}
+
+opts->paths = paths;
+opts->paths[opts->n_paths - 1].start = path;
+opts->paths[opts->n_paths - 1].length = len;
+
+return NJS_OK;
+}
+
+
 static void
 njs_options_free(njs_opts_t *opts)
 {
@@ -806,14 +835,179 @@ njs_rejection_tracker(njs_vm_t *vm, njs_
 }
 
 
+static njs_int_t
+njs_module_path(const njs_str_t *dir, njs_module_info_t *info)
+{
+char*p;
+size_t  length;
+njs_bool_t  trail;
+charsrc[NJS_MAX_PATH + 1];
+
+trail = 0;
+length = info->name.length;
+
+if (dir != NULL) {
+length += dir->length;
+
+if (length == 0) {
+return NJS_DECLINED;
+}
+
+trail = (dir->start[dir->length - 1] != '/');
+
+if (trail) {
+length++;
+}
+}
+
+if (njs_slow_path(length > NJS_MAX_PATH)) {
+return NJS_ERROR;
+}
+
+p = [0];
+
+if (dir != NULL) {
+p = (char *) njs_cpymem(p, dir->start, dir->length);
+
+if (trail) {
+*p++ = '/';
+}
+}
+
+p = (char *) njs_cpymem(p, info->name.start, info->name.length);
+*p = '\0';
+
+p = realpath([0], >path[0]);
+if (p == NULL) {
+return NJS_DECLINED;
+}
+
+info->fd = open(>path[0], O_RDONLY);
+if (info->fd < 0) {
+return NJS_DECLINED;
+}
+
+info->file.start = (u_char *) >path[0];
+info->file.length = njs_strlen(info->file.start);
+
+return NJS_OK;
+}
+
+
+static njs_int_t
+njs_module_lookup(njs_opts_t *opts, njs_module_info_t *info)
+{
+njs_int_t   ret;
+njs_str_t   *path;
+njs_uint_t  i;

[njs] Change: imported modules are not resolved relative to current dir.

2024-01-23 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/7eaaa7d57636
branches:  
changeset: 2271:7eaaa7d57636
user:  Dmitry Volyntsev 
date:  Tue Jan 23 16:33:52 2024 -0800
description:
Change: imported modules are not resolved relative to current dir.

Previously, when a module was imported with a relative path
it was looked for first in the directory of the importing context
(global, or a module).

For example when:
main.js:
import libs/lib1.js;

libs/lib1.js:
import lib2.js;

lib2.js was looked for first in libs/.

Now, it is only looked for in directories speficied with js_path
and a directory of nginx configuration file.

diffstat:

 src/njs_module.c  |  24 ++--
 test/js/import_chain.t.js |   2 +-
 test/js/import_relative_path.t.js |  10 --
 test/shell_test.exp   |   4 ++--
 4 files changed, 9 insertions(+), 31 deletions(-)

diffs (120 lines):

diff -r 6485ad23565e -r 7eaaa7d57636 src/njs_module.c
--- a/src/njs_module.c  Tue Jan 23 16:33:29 2024 -0800
+++ b/src/njs_module.c  Tue Jan 23 16:33:52 2024 -0800
@@ -16,8 +16,7 @@ typedef struct {
 } njs_module_info_t;
 
 
-static njs_int_t njs_module_lookup(njs_vm_t *vm, const njs_str_t *cwd,
-njs_module_info_t *info);
+static njs_int_t njs_module_lookup(njs_vm_t *vm, njs_module_info_t *info);
 static njs_int_t njs_module_path(njs_vm_t *vm, const njs_str_t *dir,
 njs_module_info_t *info);
 static njs_int_t njs_module_read(njs_vm_t *vm, int fd, njs_str_t *body);
@@ -45,7 +44,7 @@ njs_parser_module(njs_parser_t *parser, 
 goto done;
 }
 
-external = parser;
+external = NULL;
 loader = njs_default_module_loader;
 
 if (vm->module_loader != NULL) {
@@ -70,7 +69,7 @@ done:
 
 
 static njs_int_t
-njs_module_lookup(njs_vm_t *vm, const njs_str_t *cwd, njs_module_info_t *info)
+njs_module_lookup(njs_vm_t *vm, njs_module_info_t *info)
 {
 njs_int_t   ret;
 njs_str_t   *path;
@@ -80,12 +79,6 @@ njs_module_lookup(njs_vm_t *vm, const nj
 return njs_module_path(vm, NULL, info);
 }
 
-ret = njs_module_path(vm, cwd, info);
-
-if (ret != NJS_DECLINED) {
-return ret;
-}
-
 if (vm->paths == NULL) {
 return NJS_DECLINED;
 }
@@ -158,7 +151,6 @@ njs_module_path(njs_vm_t *vm, const njs_
 return NJS_DECLINED;
 }
 
-
 info->file.start = (u_char *) >path[0];
 info->file.length = njs_strlen(info->file.start);
 
@@ -359,24 +351,20 @@ njs_module_require(njs_vm_t *vm, njs_val
 
 
 static njs_mod_t *
-njs_default_module_loader(njs_vm_t *vm, njs_external_ptr_t external,
+njs_default_module_loader(njs_vm_t *vm, njs_external_ptr_t unused,
 njs_str_t *name)
 {
 u_char *start;
 njs_int_t  ret;
-njs_str_t  cwd, text;
+njs_str_t  text;
 njs_mod_t  *module;
-njs_parser_t   *prev;
 njs_module_info_t  info;
 
-prev = external;
-
 njs_memzero(, sizeof(njs_module_info_t));
 
 info.name = *name;
-njs_file_dirname(>lexer->file, );
 
-ret = njs_module_lookup(vm, , );
+ret = njs_module_lookup(vm, );
 if (njs_slow_path(ret != NJS_OK)) {
 return NULL;
 }
diff -r 6485ad23565e -r 7eaaa7d57636 test/js/import_chain.t.js
--- a/test/js/import_chain.t.js Tue Jan 23 16:33:29 2024 -0800
+++ b/test/js/import_chain.t.js Tue Jan 23 16:33:52 2024 -0800
@@ -1,7 +1,7 @@
 /*---
 includes: []
 flags: []
-paths: [test/js/module/, test/js/module/libs/]
+paths: [test/js/module/, test/js/module/libs/, test/js/module/sub]
 ---*/
 
 import lib2   from 'lib2.js';
diff -r 6485ad23565e -r 7eaaa7d57636 test/js/import_relative_path.t.js
--- a/test/js/import_relative_path.t.js Tue Jan 23 16:33:29 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,10 +0,0 @@
-/*---
-includes: []
-flags: []
-paths: [test/js/module/]
*/
-
-import name from 'name.js';
-import hash from 'libs/hash.js';
-
-assert.sameValue(hash.name, "libs.name");
diff -r 6485ad23565e -r 7eaaa7d57636 test/shell_test.exp
--- a/test/shell_test.exp   Tue Jan 23 16:33:29 2024 -0800
+++ b/test/shell_test.exp   Tue Jan 23 16:33:52 2024 -0800
@@ -563,8 +563,8 @@ njs_test {
 
 # quiet mode
 
-njs_run {"-q" "test/js/import_relative_path.t.js"} \
-"SyntaxError: Cannot find module \"name.js\" in 7"
+njs_run {"-q" "test/js/import_chain.t.js"} \
+"SyntaxError: Cannot find module \"lib2.js\" in 7"
 
 # sandboxing
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Shell: fixed unhandled rejected promises handling.

2024-01-23 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/6485ad23565e
branches:  
changeset: 2270:6485ad23565e
user:  Dmitry Volyntsev 
date:  Tue Jan 23 16:33:29 2024 -0800
description:
Shell: fixed unhandled rejected promises handling.

The issue was introduced in dffdf7c50dfc (not released yet).

diffstat:

 external/njs_shell.c   |  10 +-
 test/js/promise_reject_post_catch.t.js |   9 -
 test/shell_test.exp|   9 +
 3 files changed, 14 insertions(+), 14 deletions(-)

diffs (59 lines):

diff -r 8aad26845b18 -r 6485ad23565e external/njs_shell.c
--- a/external/njs_shell.c  Thu Jan 18 18:03:35 2024 -0800
+++ b/external/njs_shell.c  Tue Jan 23 16:33:29 2024 -0800
@@ -1207,6 +1207,11 @@ njs_process_script(njs_vm_t *vm, void *r
 }
 }
 
+ret = njs_process_events(runtime);
+if (njs_slow_path(ret == NJS_ERROR)) {
+break;
+}
+
 if (njs_unhandled_rejection(runtime)) {
 njs_process_output(vm, NULL, NJS_ERROR);
 
@@ -1215,11 +1220,6 @@ njs_process_script(njs_vm_t *vm, void *r
 }
 }
 
-ret = njs_process_events(runtime);
-if (njs_slow_path(ret == NJS_ERROR)) {
-break;
-}
-
 if (ret == NJS_OK) {
 break;
 }
diff -r 8aad26845b18 -r 6485ad23565e test/js/promise_reject_post_catch.t.js
--- a/test/js/promise_reject_post_catch.t.jsThu Jan 18 18:03:35 2024 -0800
+++ /dev/null   Thu Jan 01 00:00:00 1970 +
@@ -1,9 +0,0 @@
-/*---
-includes: []
-flags: []
-negative:
-  phase: runtime
*/
-
-var p = Promise.reject();
-setImmediate(() => {p.catch(() => {})});
diff -r 8aad26845b18 -r 6485ad23565e test/shell_test.exp
--- a/test/shell_test.exp   Thu Jan 18 18:03:35 2024 -0800
+++ b/test/shell_test.exp   Tue Jan 23 16:33:29 2024 -0800
@@ -476,6 +476,15 @@ ReferenceError: \"ref\" is not defined
 at anonymous \\\(string:1\\\)
 at main \\\(string:1\\\)\n$"
 
+njs_test {
+{"setImmediate(() => { console.log('x'); return Promise.reject('xx'); 
})\r\n"
+ "0\r\nx\r\nThrown:\r\nError: unhandled promise rejection: xx\r\n"}
+{"setImmediate(() => { console.log('x'); return Promise.reject('xx'); 
})\r\n"
+ "1\r\nx\r\nThrown:\r\nError: unhandled promise rejection: xx\r\n"}
+{"42\r\n"
+ "42\r\n"}
+}
+
 # CLI OPTIONS
 
 # help
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Moving out HostPromiseRejectionTracker from njs core.

2024-01-19 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/8aad26845b18
branches:  
changeset: 2269:8aad26845b18
user:  Dmitry Volyntsev 
date:  Thu Jan 18 18:03:35 2024 -0800
description:
Moving out HostPromiseRejectionTracker from njs core.

HostPromiseRejectionTracker should be implemented by host
environment according to ECMAScript specs.

The following method was removed: njs_vm_unhandled_rejection().
The following method was introduced: njs_vm_set_rejection_tracker().

diffstat:

 external/njs_shell.c |  103 +-
 nginx/ngx_http_js_module.c   |1 -
 nginx/ngx_js.c   |  101 +++--
 nginx/ngx_js.h   |2 +
 nginx/ngx_stream_js_module.c |1 -
 src/njs.h|   15 ++---
 src/njs_promise.c|   74 --
 src/njs_value.c  |7 ++
 src/njs_vm.c |   40 +++
 src/njs_vm.h |4 +-
 10 files changed, 230 insertions(+), 118 deletions(-)

diffs (651 lines):

diff -r da8b044e1c61 -r 8aad26845b18 external/njs_shell.c
--- a/external/njs_shell.c  Thu Jan 18 18:03:24 2024 -0800
+++ b/external/njs_shell.c  Thu Jan 18 18:03:35 2024 -0800
@@ -93,6 +93,12 @@ typedef struct {
 
 
 typedef struct {
+void*promise;
+njs_opaque_value_t  message;
+} njs_rejected_promise_t;
+
+
+typedef struct {
 njs_vm_t*vm;
 
 uint32_tevent_id;
@@ -101,6 +107,8 @@ typedef struct {
 
 njs_queue_t labels;
 
+njs_arr_t   *rejected_promises;
+
 njs_bool_t  suppress_stdout;
 
 njs_completion_tcompletion;
@@ -422,7 +430,7 @@ njs_options_parse(njs_opts_t *opts, int 
 
 opts->denormals = 1;
 opts->exit_code = EXIT_FAILURE;
-opts->unhandled_rejection = NJS_VM_OPT_UNHANDLED_REJECTION_THROW;
+opts->unhandled_rejection = 1;
 
 p = getenv("NJS_EXIT_CODE");
 if (p != NULL) {
@@ -528,7 +536,7 @@ njs_options_parse(njs_opts_t *opts, int 
 break;
 
 case 'r':
-opts->unhandled_rejection = NJS_VM_OPT_UNHANDLED_REJECTION_IGNORE;
+opts->unhandled_rejection = 0;
 break;
 
 case 's':
@@ -636,6 +644,8 @@ njs_console_init(njs_vm_t *vm, njs_conso
 njs_queue_init(>posted_events);
 njs_queue_init(>labels);
 
+console->rejected_promises = NULL;
+
 console->completion.completions = njs_vm_completions(vm, NULL);
 if (console->completion.completions == NULL) {
 return NJS_ERROR;
@@ -749,6 +759,53 @@ njs_externals_init(njs_vm_t *vm)
 }
 
 
+static void
+njs_rejection_tracker(njs_vm_t *vm, njs_external_ptr_t external,
+njs_bool_t is_handled, njs_value_t *promise, njs_value_t *reason)
+{
+void*promise_obj;
+uint32_ti, length;
+njs_console_t   *console;
+njs_rejected_promise_t  *rejected_promise;
+
+console = external;
+
+if (is_handled && console->rejected_promises != NULL) {
+rejected_promise = console->rejected_promises->start;
+length = console->rejected_promises->items;
+
+promise_obj = njs_value_ptr(promise);
+
+for (i = 0; i < length; i++) {
+if (rejected_promise[i].promise == promise_obj) {
+njs_arr_remove(console->rejected_promises,
+   _promise[i]);
+
+break;
+}
+}
+
+return;
+}
+
+if (console->rejected_promises == NULL) {
+console->rejected_promises = njs_arr_create(njs_vm_memory_pool(vm), 4,
+
sizeof(njs_rejected_promise_t));
+if (njs_slow_path(console->rejected_promises == NULL)) {
+return;
+}
+}
+
+rejected_promise = njs_arr_add(console->rejected_promises);
+if (njs_slow_path(rejected_promise == NULL)) {
+return;
+}
+
+rejected_promise->promise = njs_value_ptr(promise);
+njs_value_assign(_promise->message, reason);
+}
+
+
 static njs_vm_t *
 njs_create_vm(njs_opts_t *opts)
 {
@@ -784,7 +841,6 @@ njs_create_vm(njs_opts_t *opts)
 vm_options.argv = opts->argv;
 vm_options.argc = opts->argc;
 vm_options.ast = opts->ast;
-vm_options.unhandled_rejection = opts->unhandled_rejection;
 
 if (opts->stack_size != 0) {
 vm_options.max_stack_size = opts->stack_size;
@@ -796,6 +852,11 @@ njs_create_vm(njs_opts_t *opts)
 return NULL;
 }
 
+if (opts->unhandled_rejection) {
+njs_vm_set_rejection_tracker(vm, njs_rejection_tracker,
+ njs_vm_external_ptr(vm));
+}
+
 for (i = 0; i < opts->n_paths; i++) {
 path.start = (u_char *) opts->paths[i];
 path.length = njs_strlen(opt

[njs] Fixed tracking of unhandled rejected promises.

2024-01-19 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/da8b044e1c61
branches:  
changeset: 2268:da8b044e1c61
user:  Dmitry Volyntsev 
date:  Thu Jan 18 18:03:24 2024 -0800
description:
Fixed tracking of unhandled rejected promises.

Checking for unhandled promise rejections while looping for pending jobs
produces false-positive reports when an rejected promised is handled
by one of the pending jobs later.

The fix is to check for unhandled promise rejections only at top level
calls like ngx_js_name_invoke() and ngx_js_name_call() and only after
all pending jobs are processed.

The issue was introduced in bc80bcb3102c (not released yet).

diffstat:

 external/njs_shell.c  |  10 +-
 nginx/ngx_js.c|  11 +--
 src/test/njs_externals_test.c |   2 +-
 src/test/njs_unit_test.c  |   4 +---
 4 files changed, 20 insertions(+), 7 deletions(-)

diffs (88 lines):

diff -r 4fba78789fe4 -r da8b044e1c61 external/njs_shell.c
--- a/external/njs_shell.c  Thu Jan 11 15:13:47 2024 -0800
+++ b/external/njs_shell.c  Thu Jan 18 18:03:24 2024 -0800
@@ -1100,7 +1100,7 @@ njs_process_script(njs_vm_t *vm, void *r
 for ( ;; ) {
 ret = njs_vm_execute_pending_job(vm);
 if (ret <= NJS_OK) {
-if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+if (ret == NJS_ERROR) {
 njs_process_output(vm, NULL, ret);
 
 if (!njs_vm_options(vm)->interactive) {
@@ -1112,6 +1112,14 @@ njs_process_script(njs_vm_t *vm, void *r
 }
 }
 
+if (njs_vm_unhandled_rejection(vm)) {
+njs_process_output(vm, NULL, NJS_ERROR);
+
+if (!njs_vm_options(vm)->interactive) {
+return NJS_ERROR;
+}
+}
+
 ret = njs_process_events(runtime);
 if (njs_slow_path(ret == NJS_ERROR)) {
 break;
diff -r 4fba78789fe4 -r da8b044e1c61 nginx/ngx_js.c
--- a/nginx/ngx_js.cThu Jan 11 15:13:47 2024 -0800
+++ b/nginx/ngx_js.cThu Jan 18 18:03:24 2024 -0800
@@ -357,7 +357,7 @@ ngx_js_call(njs_vm_t *vm, njs_function_t
 if (ret <= NJS_OK) {
 c = ngx_external_connection(vm, njs_vm_external_ptr(vm));
 
-if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+if (ret == NJS_ERROR) {
 ngx_js_exception(vm, );
 
 ngx_log_error(NGX_LOG_ERR, c->log, 0,
@@ -417,7 +417,7 @@ ngx_js_name_invoke(njs_vm_t *vm, ngx_str
 for ( ;; ) {
 ret = njs_vm_execute_pending_job(vm);
 if (ret <= NJS_OK) {
-if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+if (ret == NJS_ERROR) {
 ngx_js_exception(vm, );
 
 ngx_log_error(NGX_LOG_ERR, log, 0,
@@ -429,6 +429,13 @@ ngx_js_name_invoke(njs_vm_t *vm, ngx_str
 }
 }
 
+if (njs_vm_unhandled_rejection(vm)) {
+ngx_js_exception(vm, );
+
+ngx_log_error(NGX_LOG_ERR, log, 0, "js exception: %V", );
+return NGX_ERROR;
+}
+
 ctx = ngx_external_ctx(vm, njs_vm_external_ptr(vm));
 
 return njs_rbtree_is_empty(>waiting_events) ? NGX_OK : NGX_AGAIN;
diff -r 4fba78789fe4 -r da8b044e1c61 src/test/njs_externals_test.c
--- a/src/test/njs_externals_test.c Thu Jan 11 15:13:47 2024 -0800
+++ b/src/test/njs_externals_test.c Thu Jan 18 18:03:24 2024 -0800
@@ -1485,7 +1485,7 @@ njs_external_call(njs_vm_t *vm, const nj
 for ( ;; ) {
 ret = njs_vm_execute_pending_job(vm);
 if (ret <= NJS_OK) {
-if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+if (ret == NJS_ERROR) {
 return NJS_ERROR;
 }
 
diff -r 4fba78789fe4 -r da8b044e1c61 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c  Thu Jan 11 15:13:47 2024 -0800
+++ b/src/test/njs_unit_test.c  Thu Jan 18 18:03:24 2024 -0800
@@ -23708,9 +23708,7 @@ njs_process_test(njs_external_state_t *s
 for ( ;; ) {
 ret = njs_vm_execute_pending_job(state->vm);
 if (ret <= NJS_OK) {
-if (ret == NJS_ERROR
-|| njs_vm_unhandled_rejection(state->vm))
-{
+if (ret == NJS_ERROR) {
 return NJS_ERROR;
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] HTTP: avoiding arithmetic ops with NULL pointer in r.args getter.

2024-01-11 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/4fba78789fe4
branches:  
changeset: 2267:4fba78789fe4
user:  Dmitry Volyntsev 
date:  Thu Jan 11 15:13:47 2024 -0800
description:
HTTP: avoiding arithmetic ops with NULL pointer in r.args getter.

Found by UndefinedBehaviorSanitizer.

diffstat:

 nginx/ngx_http_js_module.c |  7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diffs (24 lines):

diff -r 2b221f44efa6 -r 4fba78789fe4 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cThu Jan 11 15:13:43 2024 -0800
+++ b/nginx/ngx_http_js_module.cThu Jan 11 15:13:47 2024 -0800
@@ -2615,7 +2615,8 @@ static njs_int_t
 ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop,
 njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
-njs_int_t   ret;
+u_char  *data;
+njs_int_tret;
 njs_value_t *args;
 ngx_http_js_ctx_t   *ctx;
 ngx_http_request_t  *r;
@@ -2631,8 +2632,8 @@ ngx_http_js_ext_get_args(njs_vm_t *vm, n
 args = njs_value_arg(>args);
 
 if (njs_value_is_null(args)) {
-ret = njs_vm_query_string_parse(vm, r->args.data,
-r->args.data + r->args.len, args);
+data = (r->args.len != 0) ? r->args.data : (u_char *) "";
+ret = njs_vm_query_string_parse(vm, data, data + r->args.len, args);
 
 if (ret == NJS_ERROR) {
 return NJS_ERROR;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] QueryString: avoiding arithmetic ops with NULL in parse().

2024-01-11 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/2b221f44efa6
branches:  
changeset: 2266:2b221f44efa6
user:  Dmitry Volyntsev 
date:  Thu Jan 11 15:13:43 2024 -0800
description:
QueryString: avoiding arithmetic ops with NULL in parse().

Found by UndefinedBehaviorSanitizer.

diffstat:

 external/njs_query_string_module.c |  5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diffs (22 lines):

diff -r a5f279148c9f -r 2b221f44efa6 external/njs_query_string_module.c
--- a/external/njs_query_string_module.cWed Jan 10 16:26:35 2024 -0800
+++ b/external/njs_query_string_module.cThu Jan 11 15:13:43 2024 -0800
@@ -491,7 +491,7 @@ njs_query_string_parser(njs_vm_t *vm, u_
 
 key = query;
 
-do {
+while (key < end) {
 if (count++ == max_keys) {
 break;
 }
@@ -519,8 +519,7 @@ njs_query_string_parser(njs_vm_t *vm, u_
 next:
 
 key = part + sep->length;
-
-} while (key < end);
+}
 
 return NJS_OK;
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed potential buffer overread in String.prototype.match().

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/476f7b3e617d
branches:  
changeset: 2264:476f7b3e617d
user:  Dmitry Volyntsev 
date:  Tue Jan 09 17:56:19 2024 -0800
description:
Fixed potential buffer overread in String.prototype.match().

diffstat:

 src/njs_string.c |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r 50c587f74a09 -r 476f7b3e617d src/njs_string.c
--- a/src/njs_string.c  Tue Jan 09 09:14:42 2024 -0800
+++ b/src/njs_string.c  Tue Jan 09 17:56:19 2024 -0800
@@ -2797,7 +2797,7 @@ njs_string_prototype_match(njs_vm_t *vm,
 
 match:
 
-return njs_regexp_prototype_exec(vm, arguments, nargs, unused, retval);
+return njs_regexp_prototype_exec(vm, arguments, 2, unused, retval);
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] Satisfy UBSan in njs

2024-01-09 Thread Dmitry Volyntsev


On 1/3/24 4:55 PM, Ben Kallus wrote:

When I run my nginx+njs application with UBSan enabled, I encounter a
few instances of undefined behavior in njs:

1. A memcpy from NULL
2. A couple of offsets applied to NULL
3. A u32 assigned to nan
4. A u32 assigned to inf

This patch adds checks to prevent these undefined operations. With it,
my application no longer has any UBSan alerts.


Hi Ben,

I did a bunch of patches related to UBSan in njs core, most notably
https://hg.nginx.org/njs/rev/0490f1ae4cf5.
Now unit tests and test262 pass without warnings.

Thank you for prodding.



# HG changeset patch
# User Ben Kallus 
# Date 1704329280 18000
#  Wed Jan 03 19:48:00 2024 -0500
# Node ID 85d5846984fc2731ad74f91f21c74be67d6974a9
# Parent  4a15613f4e8bb4a8349ee1cefbae07585da4cbc6
Prevent undefined operations on NULL, INF, and NAN

diff -r 4a15613f4e8b -r 85d5846984fc nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cTue Dec 19 12:37:05 2023 -0800
+++ b/nginx/ngx_http_js_module.cWed Jan 03 19:48:00 2024 -0500
@@ -2717,7 +2717,9 @@

  for ( /* void */ ; cl; cl = cl->next) {
  buf = cl->buf;
-p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+if (buf->last - buf->pos > 0) {
+p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+}
  }

  done:
diff -r 4a15613f4e8b -r 85d5846984fc src/njs_extern.c
--- a/src/njs_extern.c  Tue Dec 19 12:37:05 2023 -0800
+++ b/src/njs_extern.c  Wed Jan 03 19:48:00 2024 -0500
@@ -38,7 +38,10 @@
  lhq.proto = _object_hash_proto;
  lhq.pool = vm->mem_pool;

-end = external + n;
+end = external;
+if (n > 0) {
+end += n;
+}

  while (external < end) {

diff -r 4a15613f4e8b -r 85d5846984fc src/njs_number.h
--- a/src/njs_number.h  Tue Dec 19 12:37:05 2023 -0800
+++ b/src/njs_number.h  Wed Jan 03 19:48:00 2024 -0500
@@ -41,6 +41,10 @@
  {
  uint32_t  u32;

+if (isnan(num) || isinf(num)) {
+return 0;
+}
+
  u32 = num;

  return (u32 == num && u32 != 0x);
diff -r 4a15613f4e8b -r 85d5846984fc src/njs_object.c
--- a/src/njs_object.c  Tue Dec 19 12:37:05 2023 -0800
+++ b/src/njs_object.c  Wed Jan 03 19:48:00 2024 -0500
@@ -598,7 +598,10 @@
  start = array->start;

  p = start;
-end = p + array->length;
+end = p;
+if (array->length > 0) {
+end += array->length;
+}

  switch (kind) {
  case NJS_ENUM_KEYS:
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Avoiding arithmetic ops with NULL in %TypedArray%.prototype.sort().

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/50c587f74a09
branches:  
changeset: 2263:50c587f74a09
user:  Dmitry Volyntsev 
date:  Tue Jan 09 09:14:42 2024 -0800
description:
Avoiding arithmetic ops with NULL in %TypedArray%.prototype.sort().

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_typed_array.c |  9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diffs (26 lines):

diff -r f4cb0dc3e8ea -r 50c587f74a09 src/njs_typed_array.c
--- a/src/njs_typed_array.c Mon Jan 08 22:21:14 2024 -0800
+++ b/src/njs_typed_array.c Tue Jan 09 09:14:42 2024 -0800
@@ -2035,6 +2035,11 @@ njs_typed_array_prototype_sort(njs_vm_t 
 }
 
 njs_qsort(base, length, element_size, cmp, );
+
+if (njs_slow_path(ctx.exception)) {
+return NJS_ERROR;
+}
+
 if (ctx.function != NULL) {
 if (>u.u8[array->offset * element_size] == orig) {
 memcpy(orig, base, length * element_size);
@@ -2043,10 +2048,6 @@ njs_typed_array_prototype_sort(njs_vm_t 
 njs_mp_free(vm->mem_pool, base);
 }
 
-if (njs_slow_path(ctx.exception)) {
-return NJS_ERROR;
-}
-
 njs_set_typed_array(retval, array);
 
 return NJS_OK;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Avoiding casting Infinity to integer in String.fromCodePoint().

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f4cb0dc3e8ea
branches:  
changeset: 2262:f4cb0dc3e8ea
user:  Dmitry Volyntsev 
date:  Mon Jan 08 22:21:14 2024 -0800
description:
Avoiding casting Infinity to integer in String.fromCodePoint().

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_string.c |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r 5d2a3da0674f -r f4cb0dc3e8ea src/njs_string.c
--- a/src/njs_string.c  Mon Jan 08 22:20:19 2024 -0800
+++ b/src/njs_string.c  Mon Jan 08 22:21:14 2024 -0800
@@ -1617,7 +1617,7 @@ njs_string_from_char_code(njs_vm_t *vm, 
 
 if (is_point) {
 num = njs_number([i]);
-if (isnan(num)) {
+if (isnan(num) || isinf(num)) {
 goto range_error;
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Avoiding arithmetic operations with NULL pointer in TextDecoder().

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/5d2a3da0674f
branches:  
changeset: 2261:5d2a3da0674f
user:  Dmitry Volyntsev 
date:  Mon Jan 08 22:20:19 2024 -0800
description:
Avoiding arithmetic operations with NULL pointer in TextDecoder().

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_encoding.c |   2 +-
 src/njs_utf8.c |  30 --
 2 files changed, 17 insertions(+), 15 deletions(-)

diffs (57 lines):

diff -r c15a6129ade7 -r 5d2a3da0674f src/njs_encoding.c
--- a/src/njs_encoding.cMon Jan 08 22:20:10 2024 -0800
+++ b/src/njs_encoding.cMon Jan 08 22:20:19 2024 -0800
@@ -543,7 +543,7 @@ njs_text_decoder_decode(njs_vm_t *vm, nj
 
 /* Looking for BOM. */
 
-if (!data->ignore_bom) {
+if (start != NULL && !data->ignore_bom) {
 start += njs_utf8_bom(start, end);
 }
 
diff -r c15a6129ade7 -r 5d2a3da0674f src/njs_utf8.c
--- a/src/njs_utf8.cMon Jan 08 22:20:10 2024 -0800
+++ b/src/njs_utf8.cMon Jan 08 22:20:19 2024 -0800
@@ -361,25 +361,27 @@ njs_utf8_stream_length(njs_unicode_decod
 size = 0;
 length = 0;
 
-end = p + len;
+if (p != NULL) {
+end = p + len;
+
+while (p < end) {
+codepoint = njs_utf8_decode(ctx, , end);
 
-while (p < end) {
-codepoint = njs_utf8_decode(ctx, , end);
+if (codepoint > NJS_UNICODE_MAX_CODEPOINT) {
+if (codepoint == NJS_UNICODE_CONTINUE) {
+break;
+}
 
-if (codepoint > NJS_UNICODE_MAX_CODEPOINT) {
-if (codepoint == NJS_UNICODE_CONTINUE) {
-break;
+if (fatal) {
+return -1;
+}
+
+codepoint = NJS_UNICODE_REPLACEMENT;
 }
 
-if (fatal) {
-return -1;
-}
-
-codepoint = NJS_UNICODE_REPLACEMENT;
+size += njs_utf8_size(codepoint);
+length++;
 }
-
-size += njs_utf8_size(codepoint);
-length++;
 }
 
 if (last && ctx->need != 0x00) {
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Avoiding casting NaN value to int64_t in njs.dump().

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/c15a6129ade7
branches:  
changeset: 2260:c15a6129ade7
user:  Dmitry Volyntsev 
date:  Mon Jan 08 22:20:10 2024 -0800
description:
Avoiding casting NaN value to int64_t in njs.dump().

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_json.c |  10 ++
 1 files changed, 6 insertions(+), 4 deletions(-)

diffs (41 lines):

diff -r e2c6451435a0 -r c15a6129ade7 src/njs_json.c
--- a/src/njs_json.cMon Jan 08 22:19:59 2024 -0800
+++ b/src/njs_json.cMon Jan 08 22:20:10 2024 -0800
@@ -1894,7 +1894,7 @@ njs_dump_visited(njs_vm_t *vm, njs_json_
 }
 
 
-njs_inline njs_bool_t
+njs_inline void
 njs_dump_empty(njs_json_stringify_t *stringify, njs_json_state_t *state,
 njs_chb_t *chain, njs_bool_t sep_position)
 {
@@ -1902,7 +1902,7 @@ njs_dump_empty(njs_json_stringify_t *str
 int64_t  diff;
 
 if (!state->array) {
-return 0;
+return;
 }
 
 if (sep_position) {
@@ -1919,6 +1919,10 @@ njs_dump_empty(njs_json_stringify_t *str
 }
 }
 
+if (isnan(prev)) {
+return;
+}
+
 if (isnan(key)) {
 key = state->length;
 }
@@ -1947,8 +1951,6 @@ njs_dump_empty(njs_json_stringify_t *str
 njs_json_stringify_indent(stringify, chain, 1);
 }
 }
-
-return 1;
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Avoiding pointer wraparound for padded integer specifier.

2024-01-09 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/e2c6451435a0
branches:  
changeset: 2259:e2c6451435a0
user:  Dmitry Volyntsev 
date:  Mon Jan 08 22:19:59 2024 -0800
description:
Avoiding pointer wraparound for padded integer specifier.

Previously, when integer was larger than the padded width in a integer
specifier, the "end" pointer was evaluated to a value before "buf"
pointer.

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_sprintf.c |  9 -
 1 files changed, 4 insertions(+), 5 deletions(-)

diffs (28 lines):

diff -r 0490f1ae4cf5 -r e2c6451435a0 src/njs_sprintf.c
--- a/src/njs_sprintf.c Sun Jul 30 10:21:51 2023 +0100
+++ b/src/njs_sprintf.c Mon Jan 08 22:19:59 2024 -0800
@@ -522,12 +522,12 @@ njs_integer(njs_sprintf_t *spf, u_char *
 } while (ui64 != 0);
 }
 
+length = (temp + NJS_INT64_T_LEN) - p;
+
 /* Zero or space padding. */
 
-if (spf->width != 0) {
-
-length = (temp + NJS_INT64_T_LEN) - p;
-end = buf + (spf->width - length);
+if (length < spf->width) {
+end = buf + spf->width - length;
 end = njs_min(end, spf->end);
 
 while (buf < end) {
@@ -537,7 +537,6 @@ njs_integer(njs_sprintf_t *spf, u_char *
 
 /* Number copying. */
 
-length = (temp + NJS_INT64_T_LEN) - p;
 end = buf + length;
 end = njs_min(end, spf->end);
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Ignoring UndefinedBehaviorSanitizer warnings where appropriate.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/0490f1ae4cf5
branches:  
changeset: 2258:0490f1ae4cf5
user:  Dmitry Volyntsev 
date:  Sun Jul 30 10:21:51 2023 +0100
description:
Ignoring UndefinedBehaviorSanitizer warnings where appropriate.

Prodded by David Carlier and Ben Kallus.

diffstat:

 auto/clang|  11 +++
 src/njs_clang.h   |  25 +
 src/njs_number.c  |   4 +++-
 src/njs_number.h  |   2 +-
 src/njs_typed_array.c |   2 +-
 5 files changed, 41 insertions(+), 3 deletions(-)

diffs (94 lines):

diff -r 275d785ab5bf -r 0490f1ae4cf5 auto/clang
--- a/auto/clangMon Jan 08 16:40:42 2024 -0800
+++ b/auto/clangSun Jul 30 10:21:51 2023 +0100
@@ -161,6 +161,17 @@ njs_feature_test="int main(int argc, cha
 . auto/feature
 
 
+njs_feature="GCC __attribute__ no_sanitize"
+njs_feature_name=NJS_HAVE_GCC_ATTRIBUTE_NO_SANITIZE
+njs_feature_run=no
+njs_feature_path=
+njs_feature_libs=
+njs_feature_test="__attribute__((no_sanitize(\"undefined\"))) int main(void) {
+return 0;
+  }"
+. auto/feature
+
+
 njs_feature="Address sanitizer"
 njs_feature_name=NJS_HAVE_ADDRESS_SANITIZER
 njs_feature_run=no
diff -r 275d785ab5bf -r 0490f1ae4cf5 src/njs_clang.h
--- a/src/njs_clang.h   Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_clang.h   Sun Jul 30 10:21:51 2023 +0100
@@ -183,6 +183,31 @@ njs_leading_zeros64(uint64_t x)
 #define njs_msan_unpoison(ptr, size)
 #endif
 
+#if (NJS_HAVE_GCC_ATTRIBUTE_NO_SANITIZE)
+#define NJS_NOSANITIZE(options) __attribute__((no_sanitize(options)))
+#else
+#define NJS_NOSANITIZE(options)
+#endif
+
+
+njs_inline NJS_NOSANITIZE("float-cast-overflow") int64_t
+njs_unsafe_cast_double_to_int64(double num)
+{
+   /*
+* Casting NaN to integer is undefined behavior,
+* but it is fine in some cases where we do additional checks later.
+* For example:
+*  int64_t i64 = njs_unsafe_cast_double_to_int64(num);
+*  if (i64 == num) {
+*// num is integer
+*  }
+*
+* We do this as inline function to avoid UndefinedBehaviorSanitizer
+* warnings.
+*/
+   return (int64_t) num;
+}
+
 
 #if (NJS_HAVE_DENORMALS_CONTROL)
 #include 
diff -r 275d785ab5bf -r 0490f1ae4cf5 src/njs_number.c
--- a/src/njs_number.c  Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_number.c  Sun Jul 30 10:21:51 2023 +0100
@@ -382,7 +382,9 @@ njs_number_is_safe_integer(njs_vm_t *vm,
 if (nargs > 1 && njs_is_number([1])) {
 num = njs_number([1]);
 
-if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) {
+if (num == njs_unsafe_cast_double_to_int64(num)
+&& fabs(num) <= NJS_MAX_SAFE_INTEGER)
+{
 integer = 1;
 }
 }
diff -r 275d785ab5bf -r 0490f1ae4cf5 src/njs_number.h
--- a/src/njs_number.h  Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_number.h  Sun Jul 30 10:21:51 2023 +0100
@@ -36,7 +36,7 @@ njs_int_t njs_number_parse_float(njs_vm_
 njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 
-njs_inline njs_bool_t
+njs_inline NJS_NOSANITIZE("float-cast-overflow") njs_bool_t
 njs_number_is_integer_index(double num)
 {
 uint32_t  u32;
diff -r 275d785ab5bf -r 0490f1ae4cf5 src/njs_typed_array.c
--- a/src/njs_typed_array.c Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_typed_array.c Sun Jul 30 10:21:51 2023 +0100
@@ -1388,7 +1388,7 @@ njs_typed_array_prototype_index_of(njs_v
 
 v = njs_number(njs_argument(args, 1));
 
-i64 = v;
+i64 = njs_unsafe_cast_double_to_int64(v);
 integer = (v == i64);
 
 buffer = array->buffer;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed RegExp.prototype.exec() when second argument is absent.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/275d785ab5bf
branches:  
changeset: 2257:275d785ab5bf
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
Fixed RegExp.prototype.exec() when second argument is absent.

Previously, when the second argument is undefined, NaN is casted to
unsigned which is undefined behavior.

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_regexp.c |  11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diffs (28 lines):

diff -r 41d0de3ad198 -r 275d785ab5bf src/njs_regexp.c
--- a/src/njs_regexp.c  Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_regexp.c  Mon Jan 08 16:40:42 2024 -0800
@@ -1235,6 +1235,7 @@ njs_int_t
 njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 njs_index_t unused, njs_value_t *retval)
 {
+unsigned flags;
 njs_int_tret;
 njs_value_t  *r, *s;
 njs_value_t  string_lvalue;
@@ -1253,8 +1254,14 @@ njs_regexp_prototype_exec(njs_vm_t *vm, 
 return ret;
 }
 
-return njs_regexp_builtin_exec(vm, r, s,
-   njs_number(njs_arg(args, nargs, 2)), 
retval);
+if (nargs > 2) {
+flags = njs_number(njs_arg(args, nargs, 2));
+
+} else {
+flags = 0;
+}
+
+return njs_regexp_builtin_exec(vm, r, s, flags, retval);
 }
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed initialization of external prototypes with object entry.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/ee4d396aa418
branches:  
changeset: 2255:ee4d396aa418
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
Fixed initialization of external prototypes with object entry.

When external was NULL (for example, when .u.object.properties is not
declared), an arithmetic operation was performed with NULL pointer which
is undefined behavior.

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_extern.c |  4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diffs (14 lines):

diff -r c43745da92cd -r ee4d396aa418 src/njs_extern.c
--- a/src/njs_extern.c  Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_extern.c  Mon Jan 08 16:40:42 2024 -0800
@@ -34,6 +34,10 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
 hash = >external_shared_hash;
 njs_lvlhsh_init(hash);
 
+if (n == 0) {
+return NJS_OK;
+}
+
 lhq.replace = 0;
 lhq.proto = _object_hash_proto;
 lhq.pool = vm->mem_pool;
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Improved array enumeration with length 0.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/41d0de3ad198
branches:  
changeset: 2256:41d0de3ad198
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
Improved array enumeration with length 0.

The fix eliminates an arithmetic operation with NULL pointer.

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_object.c |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r ee4d396aa418 -r 41d0de3ad198 src/njs_object.c
--- a/src/njs_object.c  Mon Jan 08 16:40:42 2024 -0800
+++ b/src/njs_object.c  Mon Jan 08 16:40:42 2024 -0800
@@ -591,7 +591,7 @@ njs_object_enumerate_array(njs_vm_t *vm,
 njs_value_t  *p, *start, *end;
 njs_array_t  *entry;
 
-if (!array->object.fast_array) {
+if (!array->object.fast_array || array->length == 0) {
 return NJS_OK;
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] QueryString: fixed underflow in parse().

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/c43745da92cd
branches:  
changeset: 2254:c43745da92cd
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
QueryString: fixed underflow in parse().

Previously, njs_query_string_append() might be provided with invalid
val_size value when value in a key-value pair was absent.

Found by UndefinedBehaviorSanitizer.

diffstat:

 external/njs_query_string_module.c |  2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diffs (12 lines):

diff -r 9fadb2e9c6ea -r c43745da92cd external/njs_query_string_module.c
--- a/external/njs_query_string_module.cMon Jan 08 16:40:42 2024 -0800
+++ b/external/njs_query_string_module.cMon Jan 08 16:40:42 2024 -0800
@@ -506,7 +506,7 @@ njs_query_string_parser(njs_vm_t *vm, u_
 
 size = val - key;
 
-if (val != end) {
+if (val != part) {
 val += eq->length;
 }
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Fixed external values initialization in unit tests.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/9fadb2e9c6ea
branches:  
changeset: 2253:9fadb2e9c6ea
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
Fixed external values initialization in unit tests.

Since 0.8.0 modules can create their own constructors and prototypes.
A modules has two method: preinit() and init(). A module should
add its constructors and prototypes in preinit() and create its own
values in init(). Creating a value in preinit() results in an error.
The patch fixes the issue by creating an external value in init()
instead of preinit().

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/test/njs_externals_test.c |  136 ++---
 1 files changed, 72 insertions(+), 64 deletions(-)

diffs (176 lines):

diff -r 721475693b80 -r 9fadb2e9c6ea src/test/njs_externals_test.c
--- a/src/test/njs_externals_test.c Mon Jan 08 16:40:42 2024 -0800
+++ b/src/test/njs_externals_test.c Mon Jan 08 16:40:42 2024 -0800
@@ -28,6 +28,7 @@ typedef struct {
 
 static njs_int_t njs_externals_262_init(njs_vm_t *vm);
 static njs_int_t njs_externals_shared_preinit(njs_vm_t *vm);
+static njs_int_t njs_externals_shared_init(njs_vm_t *vm);
 njs_int_t njs_array_buffer_detach(njs_vm_t *vm, njs_value_t *args,
 njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
@@ -47,7 +48,7 @@ njs_module_t  njs_unit_test_262_module =
 njs_module_t  njs_unit_test_external_module = {
 .name = njs_str("external"),
 .preinit = njs_externals_shared_preinit,
-.init = NULL,
+.init = njs_externals_shared_init,
 };
 
 
@@ -1253,77 +1254,15 @@ njs_externals_init_internal(njs_vm_t *vm
 {
 njs_int_t ret;
 njs_uint_ti, j;
-njs_function_t*f;
-njs_opaque_value_tvalue;
 njs_unit_test_req_t   *requests;
 njs_unit_test_prop_t  *prop;
 
-static const njs_str_t  external_ctor = njs_str("ExternalConstructor");
-static const njs_str_t  external_null = njs_str("ExternalNull");
-static const njs_str_t  external_error = njs_str("ExternalError");
-
-if (shared) {
-njs_external_r_proto_id = njs_vm_external_prototype(vm,
- njs_unit_test_r_external,
- njs_nitems(njs_unit_test_r_external));
-if (njs_slow_path(njs_external_r_proto_id < 0)) {
-njs_printf("njs_vm_external_prototype() failed\n");
-return NJS_ERROR;
-}
-
-f = njs_vm_function_alloc(vm, njs_unit_test_constructor, 1, 1);
-if (f == NULL) {
-njs_printf("njs_vm_function_alloc() failed\n");
-return NJS_ERROR;
-}
-
-njs_value_function_set(njs_value_arg(), f);
-
-ret = njs_vm_bind(vm, _ctor, njs_value_arg(), 1);
-if (njs_slow_path(ret != NJS_OK)) {
-njs_printf("njs_vm_bind() failed\n");
-return NJS_ERROR;
-}
-
-njs_external_null_proto_id = njs_vm_external_prototype(vm,
-   njs_unit_test_null_external,
-   
njs_nitems(njs_unit_test_null_external));
-if (njs_slow_path(njs_external_null_proto_id < 0)) {
-njs_printf("njs_vm_external_prototype() failed\n");
-return NJS_ERROR;
-}
-
-ret = njs_vm_external_create(vm, njs_value_arg(),
- njs_external_null_proto_id, NULL, 1);
-if (njs_slow_path(ret != NJS_OK)) {
-return NJS_ERROR;
-}
-
-ret = njs_vm_bind(vm, _null, njs_value_arg(), 1);
-if (njs_slow_path(ret != NJS_OK)) {
-njs_printf("njs_vm_bind() failed\n");
-return NJS_ERROR;
-}
-
-njs_external_error_ctor_id =
-njs_vm_external_constructor(vm, _error,
-  njs_error_constructor, njs_unit_test_ctor_props,
-  njs_nitems(njs_unit_test_ctor_props),
-  njs_unit_test_proto_props,
-  njs_nitems(njs_unit_test_proto_props));
-if (njs_slow_path(njs_external_error_ctor_id < 0)) {
-njs_printf("njs_vm_external_constructor() failed\n");
-return NJS_ERROR;
-}
-}
-
 requests = njs_mp_zalloc(vm->mem_pool, n * sizeof(njs_unit_test_req_t));
 if (njs_slow_path(requests == NULL)) {
 return NJS_ERROR;
 }
 
 for (i = 0; i < n; i++) {
-
 requests[i] = init[i].request;
 
 ret = njs_vm_external_create(vm, njs_value_arg([i].value),
@@ -1396,7 +1335,76 @@ njs_externals_262_init(njs_vm_t *vm)
 static njs_int_t
 njs_externals_shared_preinit(njs_vm_t *vm)
 {
-return njs_externals_init_internal(vm, njs_test_requests, 1, 1);
+static const 

[njs] Unifying hash function prototypes.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/721475693b80
branches:  
changeset: 2252:721475693b80
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:42 2024 -0800
description:
Unifying hash function prototypes.

This fixes UndefinedBehaviorSanitizer warning "call to function through
pointer to incorrect function type".

Found by UndefinedBehaviorSanitizer.

diffstat:

 external/njs_crypto_module.c |  71 +--
 src/njs_hash.h   |  32 +++
 src/njs_main.h   |   4 +-
 src/njs_md5.c|  10 +++---
 src/njs_md5.h|  23 --
 src/njs_sha1.c   |  10 +++---
 src/njs_sha1.h   |  24 --
 src/njs_sha2.c   |  10 +++---
 src/njs_sha2.h   |  24 --
 9 files changed, 77 insertions(+), 131 deletions(-)

diffs (424 lines):

diff -r 57071ecadeb5 -r 721475693b80 external/njs_crypto_module.c
--- a/external/njs_crypto_module.c  Mon Jan 08 16:40:27 2024 -0800
+++ b/external/njs_crypto_module.c  Mon Jan 08 16:40:42 2024 -0800
@@ -6,16 +6,14 @@
 
 
 #include 
-#include 
-#include 
-#include 
+#include 
 #include 
 #include 
 
 
-typedef void (*njs_hash_init)(void *ctx);
-typedef void (*njs_hash_update)(void *ctx, const void *data, size_t size);
-typedef void (*njs_hash_final)(u_char *result, void *ctx);
+typedef void (*njs_hash_init)(njs_hash_t *ctx);
+typedef void (*njs_hash_update)(njs_hash_t *ctx, const void *data, size_t 
size);
+typedef void (*njs_hash_final)(u_char result[32], njs_hash_t *ctx);
 
 typedef njs_int_t (*njs_digest_encode)(njs_vm_t *vm, njs_value_t *value,
 const njs_str_t *src);
@@ -31,24 +29,13 @@ typedef struct {
 } njs_hash_alg_t;
 
 typedef struct {
-union {
-njs_md5_t   md5;
-njs_sha1_t  sha1;
-njs_sha2_t  sha2;
-} u;
-
+njs_hash_t  ctx;
 njs_hash_alg_t  *alg;
 } njs_digest_t;
 
 typedef struct {
 u_char  opad[64];
-
-union {
-njs_md5_t   md5;
-njs_sha1_t  sha1;
-njs_sha2_t  sha2;
-} u;
-
+njs_hash_t  ctx;
 njs_hash_alg_t  *alg;
 } njs_hmac_t;
 
@@ -85,25 +72,25 @@ static njs_hash_alg_t njs_hash_algorithm
{
  njs_str("md5"),
  16,
- (njs_hash_init) njs_md5_init,
- (njs_hash_update) njs_md5_update,
- (njs_hash_final) njs_md5_final
+ njs_md5_init,
+ njs_md5_update,
+ njs_md5_final
},
 
{
  njs_str("sha1"),
  20,
- (njs_hash_init) njs_sha1_init,
- (njs_hash_update) njs_sha1_update,
- (njs_hash_final) njs_sha1_final
+ njs_sha1_init,
+ njs_sha1_update,
+ njs_sha1_final
},
 
{
  njs_str("sha256"),
  32,
- (njs_hash_init) njs_sha2_init,
- (njs_hash_update) njs_sha2_update,
- (njs_hash_final) njs_sha2_final
+ njs_sha2_init,
+ njs_sha2_update,
+ njs_sha2_final
},
 
{
@@ -312,7 +299,7 @@ njs_crypto_create_hash(njs_vm_t *vm, njs
 
 dgst->alg = alg;
 
-alg->init(>u);
+alg->init(>ctx);
 
 return njs_vm_external_create(vm, retval, njs_crypto_hash_proto_id,
   dgst, 0);
@@ -390,10 +377,10 @@ njs_hash_prototype_update(njs_vm_t *vm, 
 }
 
 if (!hmac) {
-dgst->alg->update(>u, data.start, data.length);
+dgst->alg->update(>ctx, data.start, data.length);
 
 } else {
-ctx->alg->update(>u, data.start, data.length);
+ctx->alg->update(>ctx, data.start, data.length);
 }
 
 njs_value_assign(retval, this);
@@ -450,17 +437,17 @@ njs_hash_prototype_digest(njs_vm_t *vm, 
 
 if (!hmac) {
 alg = dgst->alg;
-alg->final(digest, >u);
+alg->final(digest, >ctx);
 dgst->alg = NULL;
 
 } else {
 alg = ctx->alg;
-alg->final(hash1, >u);
+alg->final(hash1, >ctx);
 
-alg->init(>u);
-alg->update(>u, ctx->opad, 64);
-alg->update(>u, hash1, alg->size);
-alg->final(digest, >u);
+alg->init(>ctx);
+alg->update(>ctx, ctx->opad, 64);
+alg->update(>ctx, hash1, alg->size);
+alg->final(digest, >ctx);
 ctx->alg = NULL;
 }
 
@@ -562,9 +549,9 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs
 ctx->alg = alg;
 
 if (key.length > sizeof(key_buf)) {
-alg->init(>u);
-alg->update(>u, key.start, key.length);
-alg->final(digest, >u);
+alg->init(>ctx);
+alg->update(>ctx, key.start, key.length);
+alg->final(digest, >ctx);
 
 memcpy(key_buf, digest, alg->size);
 njs_explicit_memzero(key_buf + alg->size, sizeof(key_buf) - alg->size);
@@ -583,8 +570,8 @@ njs

[njs] Fixed Date constructor for overflows and with NaN values.

2024-01-08 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/57071ecadeb5
branches:  
changeset: 2251:57071ecadeb5
user:  Dmitry Volyntsev 
date:  Mon Jan 08 16:40:27 2024 -0800
description:
Fixed Date constructor for overflows and with NaN values.

Found by UndefinedBehaviorSanitizer.

diffstat:

 src/njs_date.c |  8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diffs (23 lines):

diff -r 4a15613f4e8b -r 57071ecadeb5 src/njs_date.c
--- a/src/njs_date.cTue Dec 19 12:37:05 2023 -0800
+++ b/src/njs_date.cMon Jan 08 16:40:27 2024 -0800
@@ -243,11 +243,19 @@ njs_make_date(int64_t tm[], njs_bool_t l
 days = njs_make_day(tm[NJS_DATE_YR], tm[NJS_DATE_MON],
 tm[NJS_DATE_DAY]);
 
+if (njs_slow_path(isnan(days))) {
+return NAN;
+}
+
 time = ((tm[NJS_DATE_HR] * 60.0 + tm[NJS_DATE_MIN]) * 60.0
 + tm[NJS_DATE_SEC]) * 1000.0 + tm[NJS_DATE_MSEC];
 
 time += days * 8640.0;
 
+if (time < -8.64e15 || time > 8.64e15) {
+return NAN;
+}
+
 if (local) {
 time += njs_tz_offset(time) * 6;
 }
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Moving out logger from njs core.

2023-12-14 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/fc1001f6801b
branches:  
changeset: 2249:fc1001f6801b
user:  Dmitry Volyntsev 
date:  Thu Dec 14 22:32:02 2023 -0800
description:
Moving out logger from njs core.

Logger is not part of the JS runtime according to ECMAScript and should
be implemented by host environment.

diffstat:

 external/njs_fs_module.c |   1 -
 external/njs_shell.c |  70 ---
 nginx/ngx_http_js_module.c   |  11 +-
 nginx/ngx_js.c   |  40 ++--
 nginx/ngx_js.h   |   6 ++-
 nginx/ngx_stream_js_module.c |   6 ---
 src/njs.h|  26 
 src/njs_builtin.c|   9 +-
 src/njs_vm.c |  25 ---
 9 files changed, 82 insertions(+), 112 deletions(-)

diffs (493 lines):

diff -r ad1a7ad3c715 -r fc1001f6801b external/njs_fs_module.c
--- a/external/njs_fs_module.c  Wed Dec 13 18:38:47 2023 -0800
+++ b/external/njs_fs_module.c  Thu Dec 14 22:32:02 2023 -0800
@@ -3668,7 +3668,6 @@ njs_fs_filehandle_cleanup(void *data)
 njs_filehandle_t  *fh = data;
 
 if (fh->vm != NULL && fh->fd != -1) {
-njs_vm_warn(fh->vm, "closing file description %d on cleanup\n", 
fh->fd);
 (void) close(fh->fd);
 }
 }
diff -r ad1a7ad3c715 -r fc1001f6801b external/njs_shell.c
--- a/external/njs_shell.c  Wed Dec 13 18:38:47 2023 -0800
+++ b/external/njs_shell.c  Thu Dec 14 22:32:02 2023 -0800
@@ -53,6 +53,13 @@ typedef struct {
 } njs_opts_t;
 
 
+typedef enum {
+NJS_LOG_ERROR = 4,
+NJS_LOG_WARN = 5,
+NJS_LOG_INFO = 7,
+} njs_log_level_t;
+
+
 typedef struct {
 size_t  index;
 size_t  length;
@@ -137,8 +144,9 @@ static njs_int_t njs_ext_console_time(nj
 static njs_int_t njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args,
 njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
-static void njs_console_log(njs_vm_t *vm, njs_external_ptr_t external,
-njs_log_level_t level, const u_char *start, size_t length);
+static void njs_console_log(njs_log_level_t level, const char *fmt, ...);
+static void njs_console_logger(njs_log_level_t level, const u_char *start,
+size_t length);
 
 static intptr_t njs_event_rbtree_compare(njs_rbtree_node_t *node1,
 njs_rbtree_node_t *node2);
@@ -159,7 +167,7 @@ static njs_external_t  njs_ext_console[]
 .native = njs_ext_console_log,
 #define NJS_LOG_DUMP  16
 #define NJS_LOG_MASK  15
-.magic8 = NJS_LOG_LEVEL_INFO | NJS_LOG_DUMP,
+.magic8 = NJS_LOG_INFO | NJS_LOG_DUMP,
 }
 },
 
@@ -171,7 +179,7 @@ static njs_external_t  njs_ext_console[]
 .enumerable = 1,
 .u.method = {
 .native = njs_ext_console_log,
-.magic8 = NJS_LOG_LEVEL_ERROR,
+.magic8 = NJS_LOG_ERROR,
 }
 },
 
@@ -183,7 +191,7 @@ static njs_external_t  njs_ext_console[]
 .enumerable = 1,
 .u.method = {
 .native = njs_ext_console_log,
-.magic8 = NJS_LOG_LEVEL_INFO,
+.magic8 = NJS_LOG_INFO,
 }
 },
 
@@ -195,7 +203,7 @@ static njs_external_t  njs_ext_console[]
 .enumerable = 1,
 .u.method = {
 .native = njs_ext_console_log,
-.magic8 = NJS_LOG_LEVEL_INFO,
+.magic8 = NJS_LOG_INFO,
 }
 },
 
@@ -237,7 +245,7 @@ static njs_external_t  njs_ext_console[]
 .enumerable = 1,
 .u.method = {
 .native = njs_ext_console_log,
-.magic8 = NJS_LOG_LEVEL_WARN,
+.magic8 = NJS_LOG_WARN,
 }
 },
 
@@ -268,11 +276,6 @@ static njs_external_t  njs_ext_262[] = {
 };
 
 
-static njs_vm_ops_t njs_console_ops = {
-njs_console_log,
-};
-
-
 njs_module_t  njs_console_module = {
 .name = njs_str("console"),
 .preinit = NULL,
@@ -776,7 +779,6 @@ njs_create_vm(njs_opts_t *opts)
 vm_options.opcode_debug = opts->opcode_debug;
 #endif
 
-vm_options.ops = _console_ops;
 vm_options.addons = njs_console_addon_modules;
 vm_options.external = _console;
 vm_options.argv = opts->argv;
@@ -1419,7 +1421,7 @@ njs_ext_console_log(njs_vm_t *vm, njs_va
 return NJS_ERROR;
 }
 
-njs_vm_logger(vm, level, "%*s\n", msg.length, msg.start);
+njs_console_logger(level, msg.start, msg.length);
 
 n++;
 }
@@ -1475,7 +1477,8 @@ njs_ext_console_time(njs_vm_t *vm, njs_v
 label = njs_queue_link_data(link, njs_timelabel_t, link);
 
 if (njs_strstr_eq(, >name)) {
-njs_vm_log(vm, "Timer \"%V\" already exists.\n", );
+njs_console_log(NJS_LOG_INFO, "Timer \"%V\" already exists.",
+);
 njs_value_undefined_set(retval);
 return NJS_OK;
 }
@@ -1546,7 +1549,8 @@ n

[njs] Introduced njs_vm_set_module_loader().

2023-12-14 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/ad1a7ad3c715
branches:  
changeset: 2248:ad1a7ad3c715
user:  Dmitry Volyntsev 
date:  Wed Dec 13 18:38:47 2023 -0800
description:
Introduced njs_vm_set_module_loader().

diffstat:

 external/njs_shell.c |  1 -
 nginx/ngx_http_js_module.c   |  1 -
 nginx/ngx_stream_js_module.c |  1 -
 src/njs.h|  3 ++-
 src/njs_module.c |  6 +++---
 src/njs_vm.c |  9 +
 src/njs_vm.h |  3 +++
 7 files changed, 17 insertions(+), 7 deletions(-)

diffs (101 lines):

diff -r 34df3f0796cf -r ad1a7ad3c715 external/njs_shell.c
--- a/external/njs_shell.c  Mon Dec 11 19:10:38 2023 -0800
+++ b/external/njs_shell.c  Wed Dec 13 18:38:47 2023 -0800
@@ -269,7 +269,6 @@ static njs_external_t  njs_ext_262[] = {
 
 
 static njs_vm_ops_t njs_console_ops = {
-NULL,
 njs_console_log,
 };
 
diff -r 34df3f0796cf -r ad1a7ad3c715 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.cMon Dec 11 19:10:38 2023 -0800
+++ b/nginx/ngx_http_js_module.cWed Dec 13 18:38:47 2023 -0800
@@ -840,7 +840,6 @@ static njs_external_t  ngx_http_js_ext_p
 
 
 static njs_vm_ops_t ngx_http_js_ops = {
-NULL,
 ngx_js_logger,
 };
 
diff -r 34df3f0796cf -r ad1a7ad3c715 nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c  Mon Dec 11 19:10:38 2023 -0800
+++ b/nginx/ngx_stream_js_module.c  Wed Dec 13 18:38:47 2023 -0800
@@ -609,7 +609,6 @@ static njs_external_t  ngx_stream_js_ext
 
 
 static njs_vm_ops_t ngx_stream_js_ops = {
-NULL,
 ngx_js_logger,
 };
 
diff -r 34df3f0796cf -r ad1a7ad3c715 src/njs.h
--- a/src/njs.h Mon Dec 11 19:10:38 2023 -0800
+++ b/src/njs.h Wed Dec 13 18:38:47 2023 -0800
@@ -214,7 +214,6 @@ typedef void (*njs_logger_t)(njs_vm_t *v
 
 
 typedef struct {
-njs_module_loader_t module_loader;
 njs_logger_tlogger;
 } njs_vm_ops_t;
 
@@ -310,6 +309,8 @@ NJS_EXPORT njs_vm_t *njs_vm_create(njs_v
 NJS_EXPORT void njs_vm_destroy(njs_vm_t *vm);
 
 NJS_EXPORT njs_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end);
+NJS_EXPORT void njs_vm_set_module_loader(njs_vm_t *vm,
+njs_module_loader_t module_loader, void *opaque);
 NJS_EXPORT njs_mod_t *njs_vm_add_module(njs_vm_t *vm, njs_str_t *name,
 njs_value_t *value);
 NJS_EXPORT njs_mod_t *njs_vm_compile_module(njs_vm_t *vm, njs_str_t *name,
diff -r 34df3f0796cf -r ad1a7ad3c715 src/njs_module.c
--- a/src/njs_module.c  Mon Dec 11 19:10:38 2023 -0800
+++ b/src/njs_module.c  Wed Dec 13 18:38:47 2023 -0800
@@ -48,9 +48,9 @@ njs_parser_module(njs_parser_t *parser, 
 external = parser;
 loader = njs_default_module_loader;
 
-if (vm->options.ops != NULL && vm->options.ops->module_loader != NULL) {
-loader = vm->options.ops->module_loader;
-external = vm->external;
+if (vm->module_loader != NULL) {
+loader = vm->module_loader;
+external = vm->module_loader_opaque;
 }
 
 module = loader(vm, external, name);
diff -r 34df3f0796cf -r ad1a7ad3c715 src/njs_vm.c
--- a/src/njs_vm.c  Mon Dec 11 19:10:38 2023 -0800
+++ b/src/njs_vm.c  Wed Dec 13 18:38:47 2023 -0800
@@ -730,6 +730,15 @@ njs_vm_execute_pending_job(njs_vm_t *vm)
 }
 
 
+void
+njs_vm_set_module_loader(njs_vm_t *vm, njs_module_loader_t module_loader,
+void *opaque)
+{
+vm->module_loader = module_loader;
+vm->module_loader_opaque = opaque;
+}
+
+
 njs_int_t
 njs_vm_add_path(njs_vm_t *vm, const njs_str_t *path)
 {
diff -r 34df3f0796cf -r ad1a7ad3c715 src/njs_vm.h
--- a/src/njs_vm.h  Mon Dec 11 19:10:38 2023 -0800
+++ b/src/njs_vm.h  Wed Dec 13 18:38:47 2023 -0800
@@ -182,6 +182,9 @@ struct njs_vm_s {
 
 njs_rbtree_t global_symbols;
 uint64_t symbol_generator;
+
+njs_module_loader_t  module_loader;
+void *module_loader_opaque;
 };
 
 
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


[njs] Refactored asynchronous events.

2023-12-05 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/bc80bcb3102c
branches:  
changeset: 2245:bc80bcb3102c
user:  Dmitry Volyntsev 
date:  Tue Dec 05 08:54:18 2023 -0800
description:
Refactored asynchronous events.

To align njs with other JS engines, async events are removed from njs
core. The following functions were removed: njs_vm_add_event(),
njs_vm_del_event(), njs_vm_waiting(). Instead the host is expected
to manage async events by itself.

In addition, the posted events are renamed to jobs, to better align with
the ECMA specs. The following methods are removed: njs_vm_run().
Instead, the host is expected to call njs_vm_execute_pending_job() in a
loop to execute pending jobs. The following functions were added:
njs_vm_enqueue_job().

diffstat:

 auto/sources|1 -
 external/njs_fs_module.c|   17 +--
 external/njs_shell.c|   16 ++-
 external/njs_webcrypto_module.c |8 +-
 nginx/ngx_http_js_module.c  |   99 +++---
 nginx/ngx_js.c  |  107 
 nginx/ngx_js.h  |   33 -
 nginx/ngx_js_fetch.c|   59 ++
 nginx/ngx_stream_js_module.c|  133 +
 src/njs.h   |   59 +--
 src/njs_event.c |   95 --
 src/njs_event.h |   24 
 src/njs_promise.c   |   39 +--
 src/njs_vm.c|  208 ++-
 src/njs_vm.h|4 +-
 src/test/njs_externals_test.c   |   35 --
 src/test/njs_externals_test.h   |2 +-
 src/test/njs_unit_test.c|   24 ++-
 18 files changed, 329 insertions(+), 634 deletions(-)

diffs (truncated from 1774 to 1000 lines):

diff -r 439ea33e531c -r bc80bcb3102c auto/sources
--- a/auto/sources  Wed Nov 29 20:46:36 2023 -0800
+++ b/auto/sources  Tue Dec 05 08:54:18 2023 -0800
@@ -34,7 +34,6 @@ NJS_LIB_SRCS=" \
src/njs_generator.c \
src/njs_disassembler.c \
src/njs_module.c \
-   src/njs_event.c \
src/njs_extern.c \
src/njs_boolean.c \
src/njs_number.c \
diff -r 439ea33e531c -r bc80bcb3102c external/njs_fs_module.c
--- a/external/njs_fs_module.c  Wed Nov 29 20:46:36 2023 -0800
+++ b/external/njs_fs_module.c  Tue Dec 05 08:54:18 2023 -0800
@@ -3264,7 +3264,6 @@ njs_fs_result(njs_vm_t *vm, njs_opaque_v
 const njs_value_t *callback, njs_uint_t nargs, njs_value_t *retval)
 {
 njs_int_t   ret;
-njs_vm_event_t  vm_event;
 njs_function_t  *cb;
 njs_opaque_value_t  promise, callbacks[2], arguments[2];
 
@@ -3290,16 +3289,11 @@ njs_fs_result(njs_vm_t *vm, njs_opaque_v
 return NJS_ERROR;
 }
 
-vm_event = njs_vm_add_event(vm, cb, 1, NULL, NULL);
-if (njs_slow_path(vm_event == NULL)) {
-return NJS_ERROR;
-}
-
 njs_value_assign([0],
  
[njs_value_is_error(njs_value_arg(result))]);
 njs_value_assign([1], result);
 
-ret = njs_vm_post_event(vm, vm_event, njs_value_arg(), 2);
+ret = njs_vm_enqueue_job(vm, cb, njs_value_arg(), 2);
 if (njs_slow_path(ret == NJS_ERROR)) {
 return NJS_ERROR;
 }
@@ -3318,13 +3312,8 @@ njs_fs_result(njs_vm_t *vm, njs_opaque_v
 njs_value_assign([1], result);
 }
 
-vm_event = njs_vm_add_event(vm, njs_value_function(callback), 1, NULL,
-NULL);
-if (njs_slow_path(vm_event == NULL)) {
-return NJS_ERROR;
-}
-
-ret = njs_vm_post_event(vm, vm_event, njs_value_arg(), 2);
+ret = njs_vm_enqueue_job(vm, njs_value_function(callback),
+ njs_value_arg(), 2);
 if (njs_slow_path(ret == NJS_ERROR)) {
 return NJS_ERROR;
 }
diff -r 439ea33e531c -r bc80bcb3102c external/njs_shell.c
--- a/external/njs_shell.c  Wed Nov 29 20:46:36 2023 -0800
+++ b/external/njs_shell.c  Tue Dec 05 08:54:18 2023 -0800
@@ -1096,12 +1096,18 @@ njs_process_script(njs_vm_t *vm, void *r
 }
 
 for ( ;; ) {
-ret = njs_vm_run(vm);
-if (ret == NJS_ERROR) {
-njs_process_output(vm, njs_value_arg(), ret);
+for ( ;; ) {
+ret = njs_vm_execute_pending_job(vm);
+if (ret <= NJS_OK) {
+if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+njs_process_output(vm, NULL, ret);
 
-if (!njs_vm_options(vm)->interactive) {
-return NJS_ERROR;
+if (!njs_vm_options(vm)->interactive) {
+return NJS_ERROR;
+}
+}
+
+break;
 }
 }
 
diff -r 439ea33e531c -r bc80bcb3102c external/njs_webcrypto_module.c
--- a/external/njs_webcrypto_module.c   Wed Nov 29 20:46:36 2023 -0800
+++ b/external/njs_webcrypto_module.c   Tue D

[njs] Modules: simplified setTimeout() timer callback.

2023-11-29 Thread Dmitry Volyntsev
details:   https://hg.nginx.org/njs/rev/f64d1f9f19e5
branches:  
changeset: 2242:f64d1f9f19e5
user:  Dmitry Volyntsev 
date:  Wed Nov 29 18:43:45 2023 -0800
description:
Modules: simplified setTimeout() timer callback.

diffstat:

 nginx/ngx_js.c |  4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diffs (19 lines):

diff -r 9a6a79e21822 -r f64d1f9f19e5 nginx/ngx_js.c
--- a/nginx/ngx_js.cWed Nov 29 18:43:37 2023 -0800
+++ b/nginx/ngx_js.cWed Nov 29 18:43:45 2023 -0800
@@ -973,14 +973,12 @@ ngx_js_timer_handler(ngx_event_t *ev)
 ngx_js_event_t  *event;
 ngx_connection_t*c;
 njs_external_ptr_t   external;
-njs_opaque_value_t   retval;
 
 event = (ngx_js_event_t *) ((u_char *) ev - offsetof(ngx_js_event_t, ev));
 
 vm = event->vm;
 
-ret = njs_vm_invoke(vm, event->function, event->args, event->nargs,
-njs_value_arg());
+ret = njs_vm_call(vm, event->function, event->args, event->nargs);
 
 external = njs_vm_external_ptr(vm);
 ctx = ngx_external_ctx(vm, external);
___
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel


  1   2   3   4   5   6   7   8   9   10   >