[njs] Fixed external values initialization in unit tests.

Dmitry Volyntsev xeioex at nginx.com
Tue Jan 9 00:57:15 UTC 2024


details:   https://hg.nginx.org/njs/rev/9fadb2e9c6ea
branches:  
changeset: 2253:9fadb2e9c6ea
user:      Dmitry Volyntsev <xeioex at nginx.com>
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_t            i, j;
-    njs_function_t        *f;
-    njs_opaque_value_t    value;
     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(&value), f);
-
-        ret = njs_vm_bind(vm, &external_ctor, njs_value_arg(&value), 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(&value),
-                                     njs_external_null_proto_id, NULL, 1);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NJS_ERROR;
-        }
-
-        ret = njs_vm_bind(vm, &external_null, njs_value_arg(&value), 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, &external_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(&requests[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_str_t  external_error = njs_str("ExternalError");
+
+    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;
+    }
+
+    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;
+    }
+
+    njs_external_error_ctor_id =
+        njs_vm_external_constructor(vm, &external_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;
+    }
+
+    return NJS_OK;
+}
+
+
+static njs_int_t
+njs_externals_shared_init(njs_vm_t *vm)
+{
+    njs_int_t           ret;
+    njs_function_t      *f;
+    njs_opaque_value_t  value;
+
+    static const njs_str_t  external_ctor = njs_str("ExternalConstructor");
+    static const njs_str_t  external_null = njs_str("ExternalNull");
+
+    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(&value), f);
+
+    ret = njs_vm_bind(vm, &external_ctor, njs_value_arg(&value), 1);
+    if (njs_slow_path(ret != NJS_OK)) {
+        njs_printf("njs_vm_bind() failed\n");
+        return NJS_ERROR;
+    }
+
+    ret = njs_vm_external_create(vm, njs_value_arg(&value),
+                                 njs_external_null_proto_id, NULL, 1);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_ERROR;
+    }
+
+    ret = njs_vm_bind(vm, &external_null, njs_value_arg(&value), 1);
+    if (njs_slow_path(ret != NJS_OK)) {
+        njs_printf("njs_vm_bind() failed\n");
+        return NJS_ERROR;
+    }
+
+    return njs_externals_init_internal(vm, &njs_test_requests[0], 1, 1);
 }
 
 


More information about the nginx-devel mailing list