details: https://hg.nginx.org/njs/rev/fd956d2a25a3 branches: changeset: 2101:fd956d2a25a3 user: Dmitry Volyntsev <xei...@nginx.com> date: Tue May 02 20:50:55 2023 -0700 description: QueryString: module is rewritten using public API.
diffstat: external/njs_query_string_module.c | 561 +++++++++++++++--------------------- src/njs.h | 8 + src/njs_value.c | 17 + src/njs_value_conversion.h | 25 - src/njs_vm.c | 25 + src/test/njs_unit_test.c | 10 +- 6 files changed, 289 insertions(+), 357 deletions(-) diffs (truncated from 1114 to 1000 lines): diff -r b2cbf06ba017 -r fd956d2a25a3 external/njs_query_string_module.c --- a/external/njs_query_string_module.c Tue May 02 20:50:52 2023 -0700 +++ b/external/njs_query_string_module.c Tue May 02 20:50:55 2023 -0700 @@ -6,7 +6,8 @@ */ -#include <njs_main.h> +#include <njs.h> +#include <njs_string.h> static njs_int_t njs_query_string_parser(njs_vm_t *vm, u_char *query, @@ -108,48 +109,15 @@ njs_module_t njs_query_string_module = }; -static const njs_value_t njs_escape_str = njs_string("escape"); -static const njs_value_t njs_unescape_str = njs_string("unescape"); -static const njs_value_t njs_encode_uri_str = - njs_long_string("encodeURIComponent"); -static const njs_value_t njs_decode_uri_str = - njs_long_string("decodeURIComponent"); -static const njs_value_t njs_max_keys_str = njs_string("maxKeys"); +static const njs_str_t njs_escape_str = njs_str("escape"); +static const njs_str_t njs_unescape_str = njs_str("unescape"); +static const njs_str_t njs_encode_uri_str = njs_str("encodeURIComponent"); +static const njs_str_t njs_decode_uri_str = njs_str("decodeURIComponent"); +static const njs_str_t njs_max_keys_str = njs_str("maxKeys"); static const njs_str_t njs_sep_default = njs_str("&"); static const njs_str_t njs_eq_default = njs_str("="); -static const njs_value_t njs_unescape_default = - njs_native_function(njs_query_string_unescape, 1); - - -static njs_object_t * -njs_query_string_object_alloc(njs_vm_t *vm) -{ - njs_object_t *obj; - - obj = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_t)); - - if (njs_fast_path(obj != NULL)) { - njs_lvlhsh_init(&obj->hash); - njs_lvlhsh_init(&obj->shared_hash); - obj->type = NJS_OBJECT; - obj->shared = 0; - obj->extensible = 1; - obj->error_data = 0; - obj->fast_array = 0; - - obj->__proto__ = NULL; - obj->slots = NULL; - - return obj; - } - - njs_memory_error(vm); - - return NULL; -} - static njs_int_t njs_query_string_decode(njs_vm_t *vm, njs_value_t *value, const u_char *start, @@ -157,7 +125,6 @@ njs_query_string_decode(njs_vm_t *vm, nj { u_char *dst; size_t length; - ssize_t str_size; uint32_t cp; njs_int_t ret; njs_chb_t chain; @@ -185,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(&chain, vm->mem_pool); + njs_chb_init(&chain, njs_vm_memory_pool(vm)); njs_utf8_decode_init(&ctx); cp = 0; @@ -240,21 +207,7 @@ njs_query_string_decode(njs_vm_t *vm, nj length++; } - str_size = njs_chb_size(&chain); - if (njs_slow_path(str_size < 0)) { - goto failed; - } - - dst = njs_string_alloc(vm, value, str_size, length); - if (njs_slow_path(dst == NULL)) { - goto failed; - } - - njs_chb_join_to(&chain, dst); - - ret = NJS_OK; - -failed: + ret = njs_vm_value_string_create_chb(vm, value, &chain); njs_chb_destroy(&chain); @@ -265,7 +218,18 @@ failed: njs_inline njs_bool_t njs_query_string_is_native_decoder(njs_function_t *decoder) { - return decoder->native && decoder->u.native == njs_query_string_unescape; + njs_opaque_value_t function; + njs_function_native_t native; + + if (decoder == NULL) { + return 1; + } + + njs_value_function_set(njs_value_arg(&function), decoder); + + native = njs_value_native_function(njs_value_arg(&function)); + + return native == njs_query_string_unescape; } @@ -274,80 +238,107 @@ njs_query_string_append(njs_vm_t *vm, nj size_t key_size, const u_char *val, size_t val_size, njs_function_t *decoder) { - uint32_t key_length, val_length; - njs_int_t ret; - njs_array_t *array; - njs_value_t name, value, retval; + njs_int_t ret; + njs_value_t *push; + njs_opaque_value_t array, name, value, retval; if (njs_query_string_is_native_decoder(decoder)) { - ret = njs_query_string_decode(vm, &name, key, key_size); + ret = njs_query_string_decode(vm, njs_value_arg(&name), key, key_size); if (njs_slow_path(ret != NJS_OK)) { return ret; } - ret = njs_query_string_decode(vm, &value, val, val_size); + ret = njs_query_string_decode(vm, njs_value_arg(&value), val, val_size); if (njs_slow_path(ret != NJS_OK)) { return ret; } } else { - key_length = njs_max(njs_utf8_length(key, key_size), 0); - ret = njs_string_new(vm, &name, key, key_size, key_length); + ret = njs_vm_value_string_create(vm, njs_value_arg(&name), key, + key_size); if (njs_slow_path(ret != NJS_OK)) { return ret; } if (key_size > 0) { - ret = njs_function_call(vm, decoder, &njs_value_undefined, &name, 1, - &name); + ret = njs_vm_invoke(vm, decoder, njs_value_arg(&name), 1, + njs_value_arg(&name)); if (njs_slow_path(ret != NJS_OK)) { return ret; } - if (!njs_is_string(&name)) { - njs_value_to_string(vm, &name, &name); + if (!njs_value_is_string(njs_value_arg(&name))) { + ret = njs_value_to_string(vm, njs_value_arg(&name), + njs_value_arg(&name)); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } } } - val_length = njs_max(njs_utf8_length(val, val_size), 0); - ret = njs_string_new(vm, &value, val, val_size, val_length); + ret = njs_vm_value_string_create(vm, njs_value_arg(&value), val, + val_size); if (njs_slow_path(ret != NJS_OK)) { return ret; } if (val_size > 0) { - ret = njs_function_call(vm, decoder, &njs_value_undefined, &value, - 1, &value); + ret = njs_vm_invoke(vm, decoder, njs_value_arg(&value), 1, + njs_value_arg(&value)); if (njs_slow_path(ret != NJS_OK)) { return ret; } - if (!njs_is_string(&value)) { - njs_value_to_string(vm, &value, &value); + if (!njs_value_is_string(njs_value_arg(&value))) { + ret = njs_value_to_string(vm, njs_value_arg(&value), + njs_value_arg(&value)); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } } } } - ret = njs_value_property(vm, object, &name, &retval); + ret = njs_value_property(vm, object, njs_value_arg(&name), + njs_value_arg(&retval)); if (ret == NJS_OK) { - if (njs_is_array(&retval)) { - return njs_array_add(vm, njs_array(&retval), &value); + if (njs_value_is_array(njs_value_arg(&retval))) { + push = njs_vm_array_push(vm, njs_value_arg(&retval)); + if (njs_slow_path(push == NULL)) { + return NJS_ERROR; + } + + njs_value_assign(push, njs_value_arg(&value)); + + return NJS_OK; } - array = njs_array_alloc(vm, 1, 2, 0); - if (njs_slow_path(array == NULL)) { + ret = njs_vm_array_alloc(vm, njs_value_arg(&array), 2); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + push = njs_vm_array_push(vm, njs_value_arg(&array)); + if (njs_slow_path(push == NULL)) { return NJS_ERROR; } - array->start[0] = retval; - array->start[1] = value; + njs_value_assign(push, njs_value_arg(&retval)); - njs_set_array(&value, array); + push = njs_vm_array_push(vm, njs_value_arg(&array)); + if (njs_slow_path(push == NULL)) { + return NJS_ERROR; + } + + njs_value_assign(push, njs_value_arg(&value)); + + njs_value_assign(&value, &array); } - return njs_value_property_set(vm, object, &name, &value); + return njs_value_property_set(vm, object, njs_value_arg(&name), + njs_value_arg(&value)); } @@ -384,12 +375,12 @@ static njs_int_t njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - int64_t max_keys; - njs_int_t ret; - njs_str_t str, sep, eq; - njs_value_t value, *this, *string, *options, *arg; - njs_value_t val_sep, val_eq; - njs_function_t *decode; + int64_t max_keys; + njs_int_t ret; + njs_str_t str, sep, eq; + njs_value_t *this, *string, *options, *arg, *val; + njs_function_t *decode; + njs_opaque_value_t value, val_sep, val_eq; decode = NULL; max_keys = 1000; @@ -397,8 +388,8 @@ njs_query_string_parse(njs_vm_t *vm, njs this = njs_argument(args, 0); string = njs_arg(args, nargs, 1); - if (njs_is_string(string)) { - njs_string_get(string, &str); + if (njs_value_is_string(string)) { + njs_value_string_get(string, &str); } else { str = njs_str_value(""); @@ -408,71 +399,68 @@ njs_query_string_parse(njs_vm_t *vm, njs eq = njs_eq_default; arg = njs_arg(args, nargs, 2); - if (!njs_is_null_or_undefined(arg)) { - ret = njs_value_to_string(vm, &val_sep, arg); + if (!njs_value_is_null_or_undefined(arg)) { + ret = njs_value_to_string(vm, njs_value_arg(&val_sep), arg); if (njs_slow_path(ret != NJS_OK)) { return ret; } - if (njs_string_length(&val_sep) != 0) { - njs_string_get(&val_sep, &sep); + if (njs_string_length(njs_value_arg(&val_sep)) != 0) { + njs_value_string_get(njs_value_arg(&val_sep), &sep); } } arg = njs_arg(args, nargs, 3); - if (!njs_is_null_or_undefined(arg)) { - ret = njs_value_to_string(vm, &val_eq, arg); + if (!njs_value_is_null_or_undefined(arg)) { + ret = njs_value_to_string(vm, njs_value_arg(&val_eq), arg); if (njs_slow_path(ret != NJS_OK)) { return ret; } - if (njs_string_length(&val_eq) != 0) { - njs_string_get(&val_eq, &eq); + if (njs_string_length(njs_value_arg(&val_eq)) != 0) { + njs_value_string_get(njs_value_arg(&val_eq), &eq); } } options = njs_arg(args, nargs, 4); - if (njs_is_object(options)) { - ret = njs_value_property(vm, options, njs_value_arg(&njs_max_keys_str), - &value); - if (njs_slow_path(ret == NJS_ERROR)) { - return ret; - } - - ret = njs_value_to_integer(vm, &value, &max_keys); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } + if (njs_value_is_object(options)) { + val = njs_vm_object_prop(vm, options, &njs_max_keys_str, &value); - if (max_keys == 0) { - max_keys = INT64_MAX; - } - - ret = njs_value_property(vm, options, - njs_value_arg(&njs_decode_uri_str), &value); - - if (ret == NJS_OK) { - if (njs_slow_path(!njs_is_function(&value))) { - njs_type_error(vm, - "option decodeURIComponent is not a function"); + if (val != NULL) { + if (!njs_value_is_valid_number(val)) { + njs_vm_error(vm, "is not a number"); return NJS_ERROR; } - decode = njs_function(&value); + max_keys = njs_value_number(val); + + if (max_keys == 0) { + max_keys = INT64_MAX; + } + } + + val = njs_vm_object_prop(vm, options, &njs_decode_uri_str, &value); + + if (val != NULL) { + if (njs_slow_path(!njs_value_is_function(val))) { + njs_vm_error(vm, "option decodeURIComponent is not a function"); + return NJS_ERROR; + } + + decode = njs_value_function(val); } } if (decode == NULL) { - ret = njs_value_property(vm, this, njs_value_arg(&njs_unescape_str), - &value); + val = njs_vm_object_prop(vm, this, &njs_unescape_str, &value); - if (ret != NJS_OK || !njs_is_function(&value)) { - njs_type_error(vm, "QueryString.unescape is not a function"); + if (val == NULL || !njs_value_is_function(val)) { + njs_vm_error(vm, "QueryString.unescape is not a function"); return NJS_ERROR; } - decode = njs_function(&value); + decode = njs_value_function(val); } return njs_query_string_parser(vm, str.start, str.start + str.length, @@ -485,9 +473,7 @@ njs_vm_query_string_parse(njs_vm_t *vm, njs_value_t *retval) { return njs_query_string_parser(vm, start, end, &njs_sep_default, - &njs_eq_default, - njs_function(&njs_unescape_default), - 1000, retval); + &njs_eq_default, NULL, 1000, retval); } @@ -496,20 +482,16 @@ njs_query_string_parser(njs_vm_t *vm, u_ const njs_str_t *sep, const njs_str_t *eq, njs_function_t *decode, njs_uint_t max_keys, njs_value_t *retval) { - size_t size; - u_char *part, *key, *val; - njs_int_t ret; - njs_uint_t count; - njs_value_t obj; - njs_object_t *object; + size_t size; + u_char *part, *key, *val; + njs_int_t ret; + njs_uint_t count; - object = njs_query_string_object_alloc(vm); - if (njs_slow_path(object == NULL)) { + ret = njs_vm_object_alloc(vm, retval, NULL); + if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - njs_set_object(&obj, object); - count = 0; key = query; @@ -533,7 +515,7 @@ njs_query_string_parser(njs_vm_t *vm, u_ val += eq->length; } - ret = njs_query_string_append(vm, &obj, key, size, val, part - val, + ret = njs_query_string_append(vm, retval, key, size, val, part - val, decode); if (njs_slow_path(ret != NJS_OK)) { return ret; @@ -545,8 +527,6 @@ njs_query_string_parser(njs_vm_t *vm, u_ } while (key < end); - njs_set_object(retval, object); - return NJS_OK; } @@ -580,7 +560,7 @@ njs_query_string_encode(njs_chb_t *chain } if (str->length == 0) { - return 0; + return NJS_OK; } p = str->start; @@ -601,21 +581,26 @@ njs_query_string_encode(njs_chb_t *chain if (size == str->length) { memcpy(start, str->start, str->length); njs_chb_written(chain, str->length); - return str->length; + return NJS_OK; } (void) njs_string_encode(escape, str->length, str->start, start); njs_chb_written(chain, size); - return size; + return NJS_OK; } njs_inline njs_bool_t njs_query_string_is_native_encoder(njs_function_t *encoder) { - return encoder->native && encoder->u.native == njs_query_string_escape; + njs_opaque_value_t function; + + njs_value_function_set(njs_value_arg(&function), encoder); + + return njs_value_native_function(njs_value_arg(&function)) + == njs_query_string_escape; } @@ -623,11 +608,11 @@ njs_inline njs_int_t njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain, njs_function_t *encoder, njs_value_t *string) { - njs_str_t str; - njs_int_t ret; - njs_value_t retval; + njs_str_t str; + njs_int_t ret; + njs_opaque_value_t retval; - if (njs_slow_path(!njs_is_string(string))) { + if (njs_slow_path(!njs_value_is_string(string))) { ret = njs_value_to_string(vm, string, string); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; @@ -635,87 +620,62 @@ njs_query_string_encoder_call(njs_vm_t * } if (njs_fast_path(njs_query_string_is_native_encoder(encoder))) { - njs_string_get(string, &str); + njs_value_string_get(string, &str); return njs_query_string_encode(chain, &str); } - ret = njs_function_call(vm, encoder, &njs_value_undefined, string, 1, - &retval); + ret = njs_vm_invoke(vm, encoder, string, 1, njs_value_arg(&retval)); if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; + return ret; } - if (njs_slow_path(!njs_is_string(&retval))) { - ret = njs_value_to_string(vm, &retval, &retval); + if (njs_slow_path(!njs_value_is_string(njs_value_arg(&retval)))) { + ret = njs_value_to_string(vm, njs_value_arg(&retval), + njs_value_arg(&retval)); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } } - njs_string_get(&retval, &str); - - ret = njs_utf8_length(str.start, str.length); - if (ret < 0) { - njs_type_error(vm, "got non-UTF8 string from encoder"); - return NJS_ERROR; - } + njs_value_string_get(njs_value_arg(&retval), &str); njs_chb_append_str(chain, &str); - return ret; + return NJS_OK; } njs_inline njs_int_t njs_query_string_push(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *key, - njs_value_t *value, njs_string_prop_t *eq, njs_function_t *encoder) + njs_value_t *value, njs_str_t *eq, njs_function_t *encoder) { - double num; - njs_int_t ret, length; - - length = 0; + njs_int_t ret; ret = njs_query_string_encoder_call(vm, chain, encoder, key); - if (njs_slow_path(ret < 0)) { + if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - length += ret; - - njs_chb_append(chain, eq->start, eq->size); - length += eq->length; + njs_chb_append(chain, eq->start, eq->length); - switch (value->type) { - case NJS_NUMBER: - num = njs_number(value); - if (njs_slow_path(isnan(num) || isinf(num))) { - break; + if (njs_value_is_valid_number(value) + || njs_value_is_boolean(value) + || njs_value_is_string(value)) + { + if (!njs_value_is_string(value)) { + ret = njs_value_to_string(vm, value, value); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } - /* Fall through. */ - - case NJS_BOOLEAN: - ret = njs_primitive_value_to_string(vm, value, value); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - - /* Fall through. */ - - case NJS_STRING: ret = njs_query_string_encoder_call(vm, chain, encoder, value); if (njs_slow_path(ret < 0)) { return NJS_ERROR; } - - length += ret; - break; - - default: - break; } - return length; + return NJS_OK; } @@ -723,183 +683,137 @@ static njs_int_t njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - u_char *p; - int64_t len; - ssize_t size; - uint32_t n, i; - uint64_t length; - njs_int_t ret; - njs_chb_t chain; - njs_value_t value, result, *string, *this, *object, *arg, *options; - njs_array_t *keys, *array; - njs_function_t *encode; - njs_string_prop_t sep, eq; - - njs_value_t val_sep = njs_string("&"); - njs_value_t val_eq = njs_string("="); - - (void) njs_string_prop(&sep, &val_sep); - (void) njs_string_prop(&eq, &val_eq); + int64_t len, keys_length; + uint32_t n, i; + njs_int_t ret; + njs_str_t sep, eq; + njs_chb_t chain; + njs_value_t *this, *object, *arg, *options, *val, *keys; + njs_function_t *encode; + njs_opaque_value_t value, result, key, *string; encode = NULL; + sep = njs_sep_default; + eq = njs_eq_default; + this = njs_argument(args, 0); object = njs_arg(args, nargs, 1); - if (njs_slow_path(!njs_is_object(object))) { - njs_value_assign(retval, &njs_string_empty); + if (njs_slow_path(!njs_value_is_object(object))) { + njs_vm_value_string_set(vm, retval, (u_char *) "", 0); return NJS_OK; } arg = njs_arg(args, nargs, 2); - if (!njs_is_null_or_undefined(arg)) { + if (!njs_value_is_null_or_undefined(arg)) { ret = njs_value_to_string(vm, arg, arg); if (njs_slow_path(ret != NJS_OK)) { return ret; } if (njs_string_length(arg) > 0) { - (void) njs_string_prop(&sep, arg); + njs_value_string_get(arg, &sep); } } arg = njs_arg(args, nargs, 3); - if (!njs_is_null_or_undefined(arg)) { + if (!njs_value_is_null_or_undefined(arg)) { ret = njs_value_to_string(vm, arg, arg); if (njs_slow_path(ret != NJS_OK)) { return ret; } if (njs_string_length(arg) > 0) { - (void) njs_string_prop(&eq, arg); + njs_value_string_get(arg, &eq); } } options = njs_arg(args, nargs, 4); - if (njs_is_object(options)) { - ret = njs_value_property(vm, options, - njs_value_arg(&njs_encode_uri_str), &value); + if (njs_value_is_object(options)) { + val = njs_vm_object_prop(vm, options, &njs_encode_uri_str, &value); - if (ret == NJS_OK) { - if (njs_slow_path(!njs_is_function(&value))) { - njs_type_error(vm, - "option encodeURIComponent is not a function"); + if (val != NULL) { + if (njs_slow_path(!njs_value_is_function(val))) { + njs_vm_error(vm, "option encodeURIComponent is not a function"); return NJS_ERROR; } - encode = njs_function(&value); + encode = njs_value_function(val); } } if (encode == NULL) { - ret = njs_value_property(vm, this, njs_value_arg(&njs_escape_str), - &value); + val = njs_vm_object_prop(vm, this, &njs_escape_str, &value); - if (ret != NJS_OK || !njs_is_function(&value)) { - njs_type_error(vm, "QueryString.escape is not a function"); + if (val == NULL || !njs_value_is_function(val)) { + njs_vm_error(vm, "QueryString.escape is not a function"); return NJS_ERROR; } - encode = njs_function(&value); + encode = njs_value_function(val); } - njs_chb_init(&chain, vm->mem_pool); + njs_chb_init(&chain, njs_vm_memory_pool(vm)); - keys = njs_value_own_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING, - 0); + keys = njs_vm_object_keys(vm, object, njs_value_arg(&value)); if (njs_slow_path(keys == NULL)) { return NJS_ERROR; } - for (n = 0, length = 0; n < keys->length; n++) { - string = &keys->start[n]; + (void) njs_vm_array_length(vm, keys, &keys_length); - ret = njs_value_property(vm, object, string, &value); + string = (njs_opaque_value_t *) njs_vm_array_start(vm, keys); + if (njs_slow_path(string == NULL)) { + return NJS_ERROR; + } + + for (n = 0; n < keys_length; n++, string++) { + ret = njs_value_property(vm, object, njs_value_arg(string), + njs_value_arg(&value)); if (njs_slow_path(ret == NJS_ERROR)) { goto failed; } - if (njs_is_array(&value)) { - - if (njs_is_fast_array(&value)) { - array = njs_array(&value); - - for (i = 0; i < array->length; i++) { - if (chain.last != NULL) { - njs_chb_append(&chain, sep.start, sep.size); - length += sep.length; - } - - ret = njs_query_string_push(vm, &chain, string, - &array->start[i], &eq, encode); - if (njs_slow_path(ret < 0)) { - ret = NJS_ERROR; - goto failed; - } - - length += ret; - } - - continue; - } - - ret = njs_object_length(vm, &value, &len); - if (njs_slow_path(ret == NJS_ERROR)) { - goto failed; - } + if (njs_value_is_array(njs_value_arg(&value))) { + (void) njs_vm_array_length(vm, njs_value_arg(&value), &len); for (i = 0; i < len; i++) { - ret = njs_value_property_i64(vm, &value, i, &result); + njs_value_number_set(njs_value_arg(&key), i); + ret = njs_value_property(vm, njs_value_arg(&value), + njs_value_arg(&key), + njs_value_arg(&result)); if (njs_slow_path(ret == NJS_ERROR)) { goto failed; } if (chain.last != NULL) { - njs_chb_append(&chain, sep.start, sep.size); - length += sep.length; + njs_chb_append(&chain, sep.start, sep.length); } - ret = njs_query_string_push(vm, &chain, string, &result, &eq, + ret = njs_query_string_push(vm, &chain, njs_value_arg(string), + njs_value_arg(&result), &eq, encode); - if (njs_slow_path(ret < 0)) { - ret = NJS_ERROR; + if (njs_slow_path(ret != NJS_OK)) { goto failed; } - - length += ret; } continue; } if (n != 0) { - njs_chb_append(&chain, sep.start, sep.size); - length += sep.length; + njs_chb_append(&chain, sep.start, sep.length); } - ret = njs_query_string_push(vm, &chain, string, &value, &eq, encode); - if (njs_slow_path(ret < 0)) { - ret = NJS_ERROR; + ret = njs_query_string_push(vm, &chain, njs_value_arg(string), + njs_value_arg(&value), &eq, encode); + if (njs_slow_path(ret != NJS_OK)) { goto failed; } - - length += ret; } - size = njs_chb_size(&chain); - if (njs_slow_path(size < 0)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - p = njs_string_alloc(vm, retval, size, length); - if (njs_slow_path(p == NULL)) { - return NJS_ERROR; - } - - njs_chb_join_to(&chain, p); - - ret = NJS_OK; + ret = njs_vm_value_string_create_chb(vm, retval, &chain); failed: @@ -913,45 +827,37 @@ static njs_int_t njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - u_char *p; - ssize_t size, length; - njs_int_t ret; - njs_str_t str; - njs_chb_t chain; - njs_value_t *string, value; + njs_int_t ret; + njs_str_t str; + njs_chb_t chain; + njs_value_t *string; + njs_opaque_value_t value; string = njs_arg(args, nargs, 1); - if (!njs_is_string(string)) { - ret = njs_value_to_string(vm, &value, string); + if (!njs_value_is_string(string)) { + ret = njs_value_to_string(vm, njs_value_arg(&value), string); if (njs_slow_path(ret != NJS_OK)) { return ret; } - string = &value; + string = njs_value_arg(&value); } - njs_string_get(string, &str); + njs_value_string_get(string, &str); - njs_chb_init(&chain, vm->mem_pool); + njs_chb_init(&chain, njs_vm_memory_pool(vm)); - length = njs_query_string_encode(&chain, &str); - if (njs_slow_path(length < 0)) { + ret = njs_query_string_encode(&chain, &str); + if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - size = njs_chb_size(&chain); - - p = njs_string_alloc(vm, retval, size, length); - if (njs_slow_path(p == NULL)) { - return NJS_ERROR; - } - - njs_chb_join_to(&chain, p); + ret = njs_vm_value_string_create_chb(vm, retval, &chain); njs_chb_destroy(&chain); - return NJS_OK; + return ret; } @@ -959,22 +865,23 @@ static njs_int_t njs_query_string_unescape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - njs_int_t ret; - njs_str_t str; - njs_value_t *string, value; + njs_int_t ret; + njs_str_t str; + njs_value_t *string; + njs_opaque_value_t value; string = njs_arg(args, nargs, 1); - if (!njs_is_string(string)) { - ret = njs_value_to_string(vm, &value, string); + if (!njs_value_is_string(string)) { + ret = njs_value_to_string(vm, njs_value_arg(&value), string); if (njs_slow_path(ret != NJS_OK)) { return ret; } - string = &value; + string = njs_value_arg(&value); } - njs_string_get(string, &str); + njs_value_string_get(string, &str); return njs_query_string_decode(vm, retval, str.start, str.length); } diff -r b2cbf06ba017 -r fd956d2a25a3 src/njs.h --- a/src/njs.h Tue May 02 20:50:52 2023 -0700 +++ b/src/njs.h Tue May 02 20:50:55 2023 -0700 @@ -382,6 +382,10 @@ NJS_EXPORT njs_external_ptr_t njs_vm_ext NJS_EXPORT njs_int_t njs_external_property(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); +NJS_EXPORT njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value, + njs_value_t *key, njs_value_t *retval); +NJS_EXPORT njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value, + njs_value_t *key, njs_value_t *setval); NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index); NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm, @@ -432,6 +436,8 @@ NJS_EXPORT njs_int_t njs_value_buffer_ge 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); +NJS_EXPORT njs_int_t njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, + njs_value_t *value); /* * Converts a value to bytes. */ @@ -477,6 +483,8 @@ NJS_EXPORT void njs_value_function_set(n NJS_EXPORT uint8_t njs_value_bool(const njs_value_t *value); NJS_EXPORT double njs_value_number(const njs_value_t *value); NJS_EXPORT njs_function_t *njs_value_function(const njs_value_t *value); +NJS_EXPORT njs_function_native_t njs_value_native_function( + const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_external_tag(const njs_value_t *value); NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop); diff -r b2cbf06ba017 -r fd956d2a25a3 src/njs_value.c --- a/src/njs_value.c Tue May 02 20:50:52 2023 -0700 +++ b/src/njs_value.c Tue May 02 20:50:55 2023 -0700 @@ -487,6 +487,23 @@ njs_value_function(const njs_value_t *va } +njs_function_native_t +njs_value_native_function(const njs_value_t *value) +{ + njs_function_t *function; + + if (njs_is_function(value)) { + function = njs_function(value); + + if (function->native) { + return function->u.native; + } + } + + return NULL; +} _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel