]> git.kaiwu.me - njs.git/commitdiff
Modules: added support for Buffer object where string is expected.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 17 Nov 2020 13:22:34 +0000 (13:22 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 17 Nov 2020 13:22:34 +0000 (13:22 +0000)
nginx/ngx_http_js_module.c
nginx/ngx_js.c
nginx/ngx_stream_js_module.c
src/njs.h
src/njs_vm.c
src/test/njs_externals_test.c

index 8685be88022408df6cc2c2d775246a6a7382e6f6..68a4bf80691e5d028113b654d80b348094e69ebb 100644 (file)
@@ -2371,7 +2371,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     arg = njs_arg(args, nargs, 2);
 
     if (njs_value_is_string(arg)) {
-        if (njs_vm_value_to_string(vm, &args_arg, arg) != NJS_OK) {
+        if (ngx_js_string(vm, arg, &args_arg) != NJS_OK) {
             njs_vm_error(vm, "failed to convert args");
             return NJS_ERROR;
         }
index 03c7877725e1dc4775a41ed4256f526350241384..976f3b766894a5f41b7b70b634fb1473693d3697 100644 (file)
@@ -105,7 +105,7 @@ ngx_int_t
 ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
 {
     if (value != NULL && !njs_value_is_null_or_undefined(value)) {
-        if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) {
+        if (njs_vm_value_to_bytes(vm, str, value) == NJS_ERROR) {
             return NGX_ERROR;
         }
 
index 29742dc2b6ff6c5756db47b540f071c773f8ed63..63b0e5d8e0833bd4b79e0e3d2540de7a1cfa73fb 100644 (file)
@@ -942,9 +942,7 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1))
-        == NJS_ERROR)
-    {
+    if (ngx_js_string(vm, njs_arg(args, nargs, 1), &name) == NJS_ERROR) {
         njs_vm_error(vm, "failed to convert event arg");
         return NJS_ERROR;
     }
@@ -991,9 +989,7 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1))
-        == NJS_ERROR)
-    {
+    if (ngx_js_string(vm, njs_arg(args, nargs, 1), &name) == NJS_ERROR) {
         njs_vm_error(vm, "failed to convert event arg");
         return NJS_ERROR;
     }
index 00d4e0e53188e4c50f45a8a2c0800f4d659f0cac..cf63f219cc9b6aa138c3c46685f4c9758437463a 100644 (file)
--- a/src/njs.h
+++ b/src/njs.h
@@ -338,6 +338,12 @@ NJS_EXPORT njs_int_t njs_vm_value_string_copy(njs_vm_t *vm, njs_str_t *retval,
 NJS_EXPORT njs_int_t njs_vm_value_buffer_set(njs_vm_t *vm, njs_value_t *value,
     const u_char *start, uint32_t size);
 
+/*
+ * Converts a value to bytes.
+ */
+NJS_EXPORT njs_int_t njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst,
+    njs_value_t *src);
+
 /*
  * Converts a value to string.
  */
index de85bc926e69a1baa4284ca5110cd89af402d47a..565872773180b0e99ad8b5e7cdc9df94ba3f4adb 100644 (file)
@@ -1115,6 +1115,67 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 }
 
 
+njs_int_t
+njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
+{
+    u_char              *start;
+    size_t              size;
+    njs_int_t           ret;
+    njs_value_t         value;
+    njs_typed_array_t   *array;
+    njs_array_buffer_t  *buffer;
+
+    if (njs_slow_path(src == NULL)) {
+        return NJS_ERROR;
+    }
+
+    ret = NJS_OK;
+    value = *src;
+
+    switch (value.type) {
+    case NJS_TYPED_ARRAY:
+    case NJS_DATA_VIEW:
+        array = njs_typed_array(&value);
+        buffer = njs_typed_array_buffer(array);
+        if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+            njs_type_error(vm, "detached buffer");
+            return NJS_ERROR;
+        }
+
+        dst->start = &buffer->u.u8[array->offset];
+        dst->length = array->byte_length;
+        break;
+
+    default:
+        ret = njs_value_to_string(vm, &value, &value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
+
+        size = value.short_string.size;
+
+        if (size != NJS_STRING_LONG) {
+            start = njs_mp_alloc(vm->mem_pool, size);
+            if (njs_slow_path(start == NULL)) {
+                njs_memory_error(vm);
+                return NJS_ERROR;
+            }
+
+            memcpy(start, value.short_string.start, size);
+
+        } else {
+            size = value.long_string.size;
+            start = value.long_string.data->start;
+        }
+
+        dst->length = size;
+        dst->start = start;
+    }
+
+    return ret;
+}
+
+
 njs_int_t
 njs_vm_value_string_copy(njs_vm_t *vm, njs_str_t *retval,
     njs_value_t *value, uintptr_t *next)
index 9787be32a890bd7b504b7fd759f3b51f71e06f61..cdb89dab948c70a7e0d24988596633a3e8595ef5 100644 (file)
@@ -130,7 +130,7 @@ njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop,
     field = (njs_str_t *) (p + njs_vm_prop_magic32(prop));
 
     if (setval != NULL) {
-        return njs_vm_value_to_string(vm, field, setval);
+        return njs_vm_value_to_bytes(vm, field, setval);
     }
 
     return njs_vm_value_string_set(vm, retval, field->start, field->length);
@@ -358,7 +358,7 @@ njs_unit_test_r_method(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_vm_value_to_string(vm, &s, njs_arg(args, nargs, 1));
+    ret = njs_vm_value_to_bytes(vm, &s, njs_arg(args, nargs, 1));
     if (ret == NJS_OK && s.length == 3 && memcmp(s.start, "YES", 3) == 0) {
         return njs_vm_value_string_set(vm, njs_vm_retval(vm), r->uri.start,
                                        r->uri.length);
@@ -388,7 +388,7 @@ njs_unit_test_r_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto memory_error;
     }
 
-    if (njs_vm_value_to_string(vm, &sr->uri, njs_arg(args, nargs, 1))
+    if (njs_vm_value_to_bytes(vm, &sr->uri, njs_arg(args, nargs, 1))
         != NJS_OK)
     {
         return NJS_ERROR;
@@ -424,7 +424,7 @@ njs_unit_test_r_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1)) != NJS_OK) {
+    if (njs_vm_value_to_bytes(vm, &name, njs_arg(args, nargs, 1)) != NJS_OK) {
         return NJS_ERROR;
     }