[njs] Refactor modules using external prototypes.
Dmitry Volyntsev
xeioex at nginx.com
Tue Dec 21 17:46:06 UTC 2021
details: https://hg.nginx.org/njs/rev/4d4657128baf
branches:
changeset: 1772:4d4657128baf
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Dec 21 17:42:26 2021 +0000
description:
Refactor modules using external prototypes.
diffstat:
auto/init | 3 +
auto/make | 45 +-
auto/module | 6 +
auto/modules | 34 +
auto/options | 2 +
auto/sources | 4 -
configure | 1 +
external/njs_crypto.c | 650 ++++++++
external/njs_fs.c | 3094 +++++++++++++++++++++++++++++++++++++++++
external/njs_query_string.c | 971 ++++++++++++
external/njs_webcrypto.c | 13 +-
external/njs_webcrypto.h | 15 -
nginx/config | 3 +-
nginx/config.make | 2 +-
nginx/ngx_http_js_module.c | 1 +
nginx/ngx_js.c | 16 +-
nginx/ngx_js.h | 3 +
nginx/ngx_stream_js_module.c | 1 +
src/njs.h | 9 +
src/njs_buffer.c | 128 +-
src/njs_buffer.h | 1 -
src/njs_builtin.c | 118 +-
src/njs_crypto.c | 693 ---------
src/njs_crypto.h | 16 -
src/njs_fs.c | 2946 ---------------------------------------
src/njs_fs.h | 16 -
src/njs_main.h | 4 -
src/njs_module.c | 60 +-
src/njs_module.h | 4 +-
src/njs_query_string.c | 924 ------------
src/njs_query_string.h | 12 -
src/njs_shell.c | 41 +-
src/njs_value.h | 2 -
src/njs_vm.c | 25 +-
src/njs_vm.h | 4 -
src/test/njs_externals_test.c | 14 -
src/test/njs_unit_test.c | 12 +-
37 files changed, 5042 insertions(+), 4851 deletions(-)
diffs (truncated from 10539 to 1000 lines):
diff -r bea31b350b5e -r 4d4657128baf auto/init
--- a/auto/init Tue Dec 21 15:49:21 2021 +0000
+++ b/auto/init Tue Dec 21 17:42:26 2021 +0000
@@ -20,6 +20,9 @@ NJS_AUTOCONF_ERR=$NJS_BUILD_DIR/autoconf
NJS_AUTO_CONFIG_H=$NJS_BUILD_DIR/njs_auto_config.h
NJS_MAKEFILE=$NJS_BUILD_DIR/Makefile
+NJS_LIB_MODULES=
+NJS_LIB_INCS="src $NJS_BUILD_DIR"
+
test -d $NJS_BUILD_DIR || mkdir $NJS_BUILD_DIR
> $NJS_AUTOCONF_ERR
diff -r bea31b350b5e -r 4d4657128baf auto/make
--- a/auto/make Tue Dec 21 15:49:21 2021 +0000
+++ b/auto/make Tue Dec 21 17:42:26 2021 +0000
@@ -7,11 +7,44 @@
echo "creating $NJS_MAKEFILE"
mkdir -p $NJS_BUILD_DIR/src
+mkdir -p $NJS_BUILD_DIR/build
+mkdir -p $NJS_BUILD_DIR/external
mkdir -p $NJS_BUILD_DIR/test
+njs_modules_c=$NJS_BUILD_DIR/njs_modules.c
+
+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 <njs_main.h>
+
+END
+
+for mod in $NJS_LIB_MODULES
+do
+ echo "extern njs_module_t $mod;" >> $njs_modules_c
+done
+
+echo >> $njs_modules_c
+echo 'njs_module_t *njs_modules[] = {' >> $njs_modules_c
+
+for mod in $NJS_LIB_MODULES
+do
+ echo " &$mod," >> $njs_modules_c
+done
+
+cat << END >> $njs_modules_c
+ NULL
+};
+
+END
+
cat << END > $NJS_MAKEFILE
# This file is auto-generated by configure
@@ -28,8 +61,7 @@ NPM = npm
default: njs
-NJS_LIB_INCS = -Isrc -I$NJS_BUILD_DIR
-
+NJS_LIB_INCS = $njs_incs
NJS_LIB_OBJS = $njs_objs
libnjs: $NJS_BUILD_DIR/libnjs.a
@@ -46,9 +78,8 @@ END
for njs_src in $NJS_LIB_SRCS
do
- fname=$(basename $njs_src)
- njs_obj="src/${fname%.c}.o"
- njs_dep="src/${fname%.c}.dep"
+ njs_obj="${njs_src%.c}.o"
+ njs_dep="${njs_src%.c}.dep"
njs_dep_flags=`njs_gen_dep_flags $njs_dep $njs_obj`
njs_dep_post=`njs_gen_dep_post $njs_dep $njs_obj`
cat << END >> $NJS_MAKEFILE
@@ -73,7 +104,7 @@ cat << END >> $NJS_MAKEFILE
$NJS_BUILD_DIR/njs: \\
$NJS_BUILD_DIR/libnjs.a \\
- src/njs_shell.c external/njs_webcrypto.h external/njs_webcrypto.c
+ src/njs_shell.c
\$(NJS_LINK) -o $NJS_BUILD_DIR/njs \$(NJS_CFLAGS) \\
$NJS_LIB_AUX_CFLAGS \$(NJS_LIB_INCS) -Injs \\
src/njs_shell.c \\
@@ -143,7 +174,7 @@ njs_dep_post=`njs_gen_dep_post $njs_dep
cat << END >> $NJS_MAKEFILE
$NJS_BUILD_DIR/$njs_externals_obj: \\
- $njs_src external/njs_webcrypto.h external/njs_webcrypto.c
+ $njs_src external/njs_webcrypto.c
\$(NJS_CC) -c \$(NJS_CFLAGS) $NJS_LIB_AUX_CFLAGS \\
\$(NJS_LIB_INCS) -Injs \\
-o $NJS_BUILD_DIR/$njs_externals_obj \\
diff -r bea31b350b5e -r 4d4657128baf auto/module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/auto/module Tue Dec 21 17:42:26 2021 +0000
@@ -0,0 +1,6 @@
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+NJS_LIB_MODULES="$NJS_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 bea31b350b5e -r 4d4657128baf auto/modules
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/auto/modules Tue Dec 21 17:42:26 2021 +0000
@@ -0,0 +1,34 @@
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+njs_module_name=njs_buffer_module
+njs_module_incs=
+njs_module_srcs=src/njs_buffer.c
+
+. auto/module
+
+njs_module_name=njs_crypto_module
+njs_module_incs=
+njs_module_srcs=external/njs_crypto.c
+
+. auto/module
+
+if [ $NJS_WEBCRYPTO = YES -a $NJS_HAVE_OPENSSL = YES ]; then
+ njs_module_name=njs_webcrypto_module
+ njs_module_incs=
+ njs_module_srcs=external/njs_webcrypto.c
+
+ . auto/module
+fi
+
+njs_module_name=njs_fs_module
+njs_module_incs=
+njs_module_srcs=external/njs_fs.c
+
+. auto/module
+
+njs_module_name=njs_query_string_module
+njs_module_incs=
+njs_module_srcs=external/njs_query_string.c
+
+. auto/module
diff -r bea31b350b5e -r 4d4657128baf auto/options
--- a/auto/options Tue Dec 21 15:49:21 2021 +0000
+++ b/auto/options Tue Dec 21 17:42:26 2021 +0000
@@ -11,6 +11,7 @@ NJS_DEBUG_MEMORY=NO
NJS_ADDRESS_SANITIZER=NO
NJS_TEST262=YES
+NJS_WEBCRYPTO=YES
NJS_TRY_PCRE2=YES
NJS_CONFIGURE_OPTIONS=
@@ -33,6 +34,7 @@ do
--debug-memory=*) NJS_DEBUG_MEMORY="$value" ;;
--test262=*) NJS_TEST262="$value" ;;
+ --no-webcrypto) NJS_WEBCRYPTO=NO ;;
--no-pcre2) NJS_TRY_PCRE2=NO ;;
--help)
diff -r bea31b350b5e -r 4d4657128baf auto/sources
--- a/auto/sources Tue Dec 21 15:49:21 2021 +0000
+++ b/auto/sources Tue Dec 21 17:42:26 2021 +0000
@@ -42,8 +42,6 @@ NJS_LIB_SRCS=" \
src/njs_timer.c \
src/njs_module.c \
src/njs_event.c \
- src/njs_fs.c \
- src/njs_crypto.c \
src/njs_extern.c \
src/njs_variable.c \
src/njs_builtin.c \
@@ -55,9 +53,7 @@ NJS_LIB_SRCS=" \
src/njs_array_buffer.c \
src/njs_typed_array.c \
src/njs_promise.c \
- src/njs_query_string.c \
src/njs_encoding.c \
- src/njs_buffer.c \
src/njs_iterator.c \
src/njs_scope.c \
src/njs_async.c \
diff -r bea31b350b5e -r 4d4657128baf configure
--- a/configure Tue Dec 21 15:49:21 2021 +0000
+++ b/configure Tue Dec 21 17:42:26 2021 +0000
@@ -35,6 +35,7 @@ NJS_LIB_AUX_CFLAGS="$NJS_PCRE_CFLAGS"
NJS_LIBS="$NJS_LIBRT"
NJS_LIB_AUX_LIBS="$NJS_PCRE_LIB $NJS_OPENSSL_LIB"
+. auto/modules
. auto/make
. auto/expect
diff -r bea31b350b5e -r 4d4657128baf external/njs_crypto.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/external/njs_crypto.c Tue Dec 21 17:42:26 2021 +0000
@@ -0,0 +1,650 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <njs_main.h>
+
+
+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 njs_int_t (*njs_digest_encode)(njs_vm_t *vm, njs_value_t *value,
+ const njs_str_t *src);
+
+
+typedef struct {
+ njs_str_t name;
+
+ size_t size;
+ njs_hash_init init;
+ njs_hash_update update;
+ njs_hash_final final;
+} njs_hash_alg_t;
+
+typedef struct {
+ union {
+ njs_md5_t md5;
+ njs_sha1_t sha1;
+ njs_sha2_t sha2;
+ } u;
+
+ 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_alg_t *alg;
+} njs_hmac_t;
+
+
+typedef struct {
+ njs_str_t name;
+
+ njs_digest_encode encode;
+} njs_crypto_enc_t;
+
+
+static njs_hash_alg_t *njs_crypto_algorithm(njs_vm_t *vm,
+ const njs_value_t *value);
+static njs_crypto_enc_t *njs_crypto_encoding(njs_vm_t *vm,
+ const njs_value_t *value);
+static njs_int_t njs_buffer_digest(njs_vm_t *vm, njs_value_t *value,
+ const njs_str_t *src);
+static njs_int_t njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t unused);
+static njs_int_t njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t hmac);
+static njs_int_t njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t hmac);
+static njs_int_t njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t unused);
+
+static njs_int_t njs_crypto_init(njs_vm_t *vm);
+
+
+static njs_hash_alg_t njs_hash_algorithms[] = {
+
+ {
+ njs_str("md5"),
+ 16,
+ (njs_hash_init) njs_md5_init,
+ (njs_hash_update) njs_md5_update,
+ (njs_hash_final) 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_str("sha256"),
+ 32,
+ (njs_hash_init) njs_sha2_init,
+ (njs_hash_update) njs_sha2_update,
+ (njs_hash_final) njs_sha2_final
+ },
+
+ {
+ njs_null_str,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ }
+
+};
+
+
+static njs_crypto_enc_t njs_encodings[] = {
+
+ {
+ njs_str("buffer"),
+ njs_buffer_digest
+ },
+
+ {
+ njs_str("hex"),
+ njs_string_hex
+ },
+
+ {
+ njs_str("base64"),
+ njs_string_base64
+ },
+
+ {
+ njs_str("base64url"),
+ njs_string_base64url
+ },
+
+ {
+ njs_null_str,
+ NULL
+ }
+};
+
+
+static njs_external_t njs_ext_crypto_hash[] = {
+
+ {
+ .flags = NJS_EXTERN_PROPERTY | NJS_EXTERN_SYMBOL,
+ .name.symbol = NJS_SYMBOL_TO_STRING_TAG,
+ .u.property = {
+ .value = "Hash",
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("update"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_hash_prototype_update,
+ .magic8 = 0,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("digest"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_hash_prototype_digest,
+ .magic8 = 0,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("constructor"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_crypto_create_hash,
+ }
+ },
+};
+
+
+static njs_external_t njs_ext_crypto_hmac[] = {
+
+ {
+ .flags = NJS_EXTERN_PROPERTY | NJS_EXTERN_SYMBOL,
+ .name.symbol = NJS_SYMBOL_TO_STRING_TAG,
+ .u.property = {
+ .value = "Hmac",
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("update"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_hash_prototype_update,
+ .magic8 = 1,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("digest"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_hash_prototype_digest,
+ .magic8 = 1,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("constructor"),
+ .writable = 1,
+ .configurable = 1,
+ .u.method = {
+ .native = njs_crypto_create_hmac,
+ .magic8 = 0,
+ }
+ },
+};
+
+
+static njs_external_t njs_ext_crypto_crypto[] = {
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("createHash"),
+ .writable = 1,
+ .configurable = 1,
+ .enumerable = 1,
+ .u.method = {
+ .native = njs_crypto_create_hash,
+ .magic8 = 0,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_METHOD,
+ .name.string = njs_str("createHmac"),
+ .writable = 1,
+ .configurable = 1,
+ .enumerable = 1,
+ .u.method = {
+ .native = njs_crypto_create_hmac,
+ .magic8 = 0,
+ }
+ },
+};
+
+
+static njs_int_t njs_crypto_hash_proto_id;
+static njs_int_t njs_crypto_hmac_proto_id;
+
+
+njs_module_t njs_crypto_module = {
+ .name = njs_str("crypto"),
+ .init = njs_crypto_init,
+};
+
+
+static njs_int_t
+njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t unused)
+{
+ njs_digest_t *dgst;
+ njs_hash_alg_t *alg;
+
+ alg = njs_crypto_algorithm(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(alg == NULL)) {
+ return NJS_ERROR;
+ }
+
+ dgst = njs_mp_alloc(vm->mem_pool, sizeof(njs_digest_t));
+ if (njs_slow_path(dgst == NULL)) {
+ njs_memory_error(vm);
+ return NJS_ERROR;
+ }
+
+ dgst->alg = alg;
+
+ alg->init(&dgst->u);
+
+ return njs_vm_external_create(vm, &vm->retval, njs_crypto_hash_proto_id,
+ dgst, 0);
+}
+
+
+static njs_int_t
+njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t hmac)
+{
+ njs_str_t data;
+ njs_int_t ret;
+ njs_hmac_t *ctx;
+ njs_value_t *this, dst;
+ njs_digest_t *dgst;
+ njs_typed_array_t *array;
+ const njs_value_t *value;
+ njs_array_buffer_t *buffer;
+ const njs_buffer_encoding_t *encoding;
+
+ this = njs_argument(args, 0);
+
+ if (!hmac) {
+ dgst = njs_vm_external(vm, njs_crypto_hash_proto_id, this);
+ if (njs_slow_path(dgst == NULL)) {
+ njs_type_error(vm, "\"this\" is not a hash object");
+ return NJS_ERROR;
+ }
+
+ if (njs_slow_path(dgst->alg == NULL)) {
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
+ }
+
+ ctx = NULL;
+
+ } else {
+ ctx = njs_vm_external(vm, njs_crypto_hmac_proto_id, this);
+ if (njs_slow_path(ctx == NULL)) {
+ njs_type_error(vm, "\"this\" is not a hmac object");
+ return NJS_ERROR;
+ }
+
+ if (njs_slow_path(ctx->alg == NULL)) {
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
+ }
+
+ dgst = NULL;
+ }
+
+ value = njs_arg(args, nargs, 1);
+
+ switch (value->type) {
+ case NJS_STRING:
+ encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 2));
+ if (njs_slow_path(encoding == NULL)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_buffer_decode_string(vm, value, &dst, encoding);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ njs_string_get(&dst, &data);
+ break;
+
+ case NJS_TYPED_ARRAY:
+ case NJS_DATA_VIEW:
+ array = njs_typed_array(value);
+ buffer = array->buffer;
+ if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+ njs_type_error(vm, "detached buffer");
+ return NJS_ERROR;
+ }
+
+ data.start = &buffer->u.u8[array->offset];
+ data.length = array->byte_length;
+ break;
+
+ default:
+ njs_type_error(vm, "data argument \"%s\" is not a string "
+ "or Buffer-like object", njs_type_string(value->type));
+
+ return NJS_ERROR;
+ }
+
+ if (!hmac) {
+ dgst->alg->update(&dgst->u, data.start, data.length);
+
+ } else {
+ ctx->alg->update(&ctx->u, data.start, data.length);
+ }
+
+ vm->retval = *this;
+
+ return NJS_OK;
+}
+
+
+static njs_int_t
+njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t hmac)
+{
+ njs_str_t str;
+ njs_hmac_t *ctx;
+ njs_value_t *this;
+ njs_digest_t *dgst;
+ njs_hash_alg_t *alg;
+ njs_crypto_enc_t *enc;
+ u_char hash1[32], digest[32];
+
+ this = njs_argument(args, 0);
+
+ if (!hmac) {
+ dgst = njs_vm_external(vm, njs_crypto_hash_proto_id, this);
+ if (njs_slow_path(dgst == NULL)) {
+ njs_type_error(vm, "\"this\" is not a hash object");
+ return NJS_ERROR;
+ }
+
+ if (njs_slow_path(dgst->alg == NULL)) {
+ goto exception;
+ }
+
+ ctx = NULL;
+
+ } else {
+ ctx = njs_vm_external(vm, njs_crypto_hmac_proto_id, this);
+ if (njs_slow_path(ctx == NULL)) {
+ njs_type_error(vm, "\"this\" is not a hmac object");
+ return NJS_ERROR;
+ }
+
+ if (njs_slow_path(ctx->alg == NULL)) {
+ goto exception;
+ }
+
+ dgst = NULL;
+ }
+
+ enc = njs_crypto_encoding(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(enc == NULL)) {
+ return NJS_ERROR;
+ }
+
+ if (!hmac) {
+ alg = dgst->alg;
+ alg->final(digest, &dgst->u);
+ dgst->alg = NULL;
+
+ } else {
+ alg = ctx->alg;
+ alg->final(hash1, &ctx->u);
+
+ alg->init(&ctx->u);
+ alg->update(&ctx->u, ctx->opad, 64);
+ alg->update(&ctx->u, hash1, alg->size);
+ alg->final(digest, &ctx->u);
+ ctx->alg = NULL;
+ }
+
+ str.start = digest;
+ str.length = alg->size;
+
+ return enc->encode(vm, &vm->retval, &str);
+
+exception:
+
+ njs_error(vm, "Digest already called");
+ return NJS_ERROR;
+}
+
+
+static njs_int_t
+njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t unused)
+{
+ njs_str_t key;
+ njs_uint_t i;
+ njs_hmac_t *ctx;
+ njs_hash_alg_t *alg;
+ njs_typed_array_t *array;
+ const njs_value_t *value;
+ njs_array_buffer_t *buffer;
+ u_char digest[32], key_buf[64];
+
+ alg = njs_crypto_algorithm(vm, njs_arg(args, nargs, 1));
+ if (njs_slow_path(alg == NULL)) {
+ return NJS_ERROR;
+ }
+
+ value = njs_arg(args, nargs, 2);
+
+ switch (value->type) {
+ case NJS_STRING:
+ njs_string_get(value, &key);
+ break;
+
+ case NJS_TYPED_ARRAY:
+ case NJS_DATA_VIEW:
+ array = njs_typed_array(value);
+ buffer = array->buffer;
+ if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+ njs_type_error(vm, "detached buffer");
+ return NJS_ERROR;
+ }
+
+ key.start = &buffer->u.u8[array->offset];
+ key.length = array->byte_length;
+ break;
+
+ default:
+ njs_type_error(vm, "key argument \"%s\" is not a string "
+ "or Buffer-like object", njs_type_string(value->type));
+
+ return NJS_ERROR;
+ }
+
+ ctx = njs_mp_alloc(vm->mem_pool, sizeof(njs_hmac_t));
+ if (njs_slow_path(ctx == NULL)) {
+ njs_memory_error(vm);
+ return NJS_ERROR;
+ }
+
+ ctx->alg = alg;
+
+ if (key.length > sizeof(key_buf)) {
+ alg->init(&ctx->u);
+ alg->update(&ctx->u, key.start, key.length);
+ alg->final(digest, &ctx->u);
+
+ memcpy(key_buf, digest, alg->size);
+ njs_explicit_memzero(key_buf + alg->size, sizeof(key_buf) - alg->size);
+
+ } else {
+ memcpy(key_buf, key.start, key.length);
+ njs_explicit_memzero(key_buf + key.length,
+ sizeof(key_buf) - key.length);
+ }
+
+ for (i = 0; i < 64; i++) {
+ ctx->opad[i] = key_buf[i] ^ 0x5c;
+ }
+
+ for (i = 0; i < 64; i++) {
+ key_buf[i] ^= 0x36;
+ }
+
+ alg->init(&ctx->u);
+ alg->update(&ctx->u, key_buf, 64);
+
+ return njs_vm_external_create(vm, &vm->retval, njs_crypto_hmac_proto_id,
+ ctx, 0);
+}
+
+
+static njs_hash_alg_t *
+njs_crypto_algorithm(njs_vm_t *vm, const njs_value_t *value)
+{
+ njs_str_t name;
+ njs_hash_alg_t *e;
+
+ if (njs_slow_path(!njs_is_string(value))) {
+ njs_type_error(vm, "algorithm must be a string");
+ return NULL;
+ }
+
+ njs_string_get(value, &name);
+
+ for (e = &njs_hash_algorithms[0]; e->name.length != 0; e++) {
+ if (njs_strstr_eq(&name, &e->name)) {
+ return e;
+ }
+ }
+
+ njs_type_error(vm, "not supported algorithm: \"%V\"", &name);
+
+ return NULL;
+}
+
+
+static njs_crypto_enc_t *
+njs_crypto_encoding(njs_vm_t *vm, const njs_value_t *value)
+{
+ njs_str_t name;
+ njs_crypto_enc_t *e;
+
+ if (njs_slow_path(!njs_is_string(value))) {
+ if (njs_is_defined(value)) {
+ njs_type_error(vm, "encoding must be a string");
+ return NULL;
+ }
+
+ return &njs_encodings[0];
+ }
+
+ njs_string_get(value, &name);
+
+ for (e = &njs_encodings[1]; e->name.length != 0; e++) {
+ if (njs_strstr_eq(&name, &e->name)) {
+ return e;
+ }
+ }
+
+ njs_type_error(vm, "Unknown digest encoding: \"%V\"", &name);
+
+ return NULL;
+}
+
+
+static njs_int_t
+njs_buffer_digest(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+{
+ return njs_buffer_new(vm, value, src->start, src->length);
+}
+
+
+static njs_int_t
+njs_crypto_init(njs_vm_t *vm)
+{
+ njs_int_t ret, proto_id;
+ njs_mod_t *module;
+ njs_opaque_value_t value;
+
+ njs_crypto_hash_proto_id =
+ njs_vm_external_prototype(vm, njs_ext_crypto_hash,
+ njs_nitems(njs_ext_crypto_hash));
+ if (njs_slow_path(njs_crypto_hash_proto_id < 0)) {
+ return NJS_ERROR;
+ }
+
+ njs_crypto_hmac_proto_id =
+ njs_vm_external_prototype(vm, njs_ext_crypto_hmac,
+ njs_nitems(njs_ext_crypto_hmac));
+ if (njs_slow_path(njs_crypto_hmac_proto_id < 0)) {
+ return NJS_ERROR;
+ }
+
+ proto_id = njs_vm_external_prototype(vm, njs_ext_crypto_crypto,
+ njs_nitems(njs_ext_crypto_crypto));
+ if (njs_slow_path(proto_id < 0)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_vm_external_create(vm, njs_value_arg(&value), proto_id, NULL, 1);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ module = njs_module_add(vm, &njs_str_value("crypto"), 1);
+ if (njs_slow_path(module == NULL)) {
+ return NJS_ERROR;
+ }
+
+ njs_value_assign(&module->value, &value);
+ module->function.native = 1;
+
+ return NJS_OK;
+}
diff -r bea31b350b5e -r 4d4657128baf external/njs_fs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/external/njs_fs.c Tue Dec 21 17:42:26 2021 +0000
@@ -0,0 +1,3094 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <njs_main.h>
+
+#include <dirent.h>
+
+#if (NJS_SOLARIS)
+
+#define DT_DIR 0
+#define DT_REG 1
+#define DT_CHR 2
+#define DT_LNK 3
+#define DT_BLK 4
+#define DT_FIFO 5
+#define DT_SOCK 6
+#define NJS_DT_INVALID 0xffffffff
+
+#define njs_dentry_type(_dentry) \
+ (NJS_DT_INVALID)
+
+#else
+
+#define NJS_DT_INVALID 0xffffffff
+
+#define njs_dentry_type(_dentry) \
+ ((_dentry)->d_type)
+
+#endif
+
+
+#define njs_fs_magic(calltype, mode) \
+ (((mode) << 2) | calltype)
+
+#define njs_fs_magic2(field, type) \
+ (((type) << 4) | field)
+
+
+typedef enum {
+ NJS_FS_DIRECT,
+ NJS_FS_PROMISE,
+ NJS_FS_CALLBACK,
+} njs_fs_calltype_t;
+
+
+typedef enum {
+ NJS_FS_TRUNC,
+ NJS_FS_APPEND,
+} njs_fs_writemode_t;
+
+
+typedef enum {
+ NJS_FS_STAT,
+ NJS_FS_LSTAT,
+} njs_fs_statmode_t;
+
+
+typedef struct {
+ njs_str_t name;
+ int value;
+} njs_fs_entry_t;
+
+
+typedef enum {
+ NJS_FTW_PHYS = 1,
+ NJS_FTW_MOUNT = 2,
+ NJS_FTW_DEPTH = 8,
+} njs_ftw_flags_t;
+
+
+typedef enum {
+ NJS_FTW_F,
+ NJS_FTW_D,
+ NJS_FTW_DNR,
+ NJS_FTW_NS,
+ NJS_FTW_SL,
+ NJS_FTW_DP,
+ NJS_FTW_SLN,
+} njs_ftw_type_t;
+
+
+typedef struct {
+ long tv_sec;
+ long tv_nsec;
+} njs_timespec_t;
+
+
+typedef struct {
+ uint64_t st_dev;
+ uint64_t st_mode;
+ uint64_t st_nlink;
+ uint64_t st_uid;
+ uint64_t st_gid;
+ uint64_t st_rdev;
+ uint64_t st_ino;
+ uint64_t st_size;
+ uint64_t st_blksize;
+ uint64_t st_blocks;
+ njs_timespec_t st_atim;
+ njs_timespec_t st_mtim;
+ njs_timespec_t st_ctim;
+ njs_timespec_t st_birthtim;
+} njs_stat_t;
+
+
+typedef enum {
+ NJS_FS_STAT_DEV,
+ NJS_FS_STAT_INO,
+ NJS_FS_STAT_MODE,
+ NJS_FS_STAT_NLINK,
+ NJS_FS_STAT_UID,
+ NJS_FS_STAT_GID,
+ NJS_FS_STAT_RDEV,
+ NJS_FS_STAT_SIZE,
+ NJS_FS_STAT_BLKSIZE,
+ NJS_FS_STAT_BLOCKS,
+ NJS_FS_STAT_ATIME,
+ NJS_FS_STAT_BIRTHTIME,
+ NJS_FS_STAT_CTIME,
+ NJS_FS_STAT_MTIME,
+} njs_stat_prop_t;
+
+
+typedef njs_int_t (*njs_file_tree_walk_cb_t)(const char *, const struct stat *,
+ njs_ftw_type_t);
+
+
+static njs_int_t njs_fs_access(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t calltype);
+static njs_int_t njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t calltype);
+static njs_int_t njs_fs_read(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t calltype);
+static njs_int_t njs_fs_readdir(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t calltype);
+static njs_int_t njs_fs_realpath(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t calltype);
More information about the nginx-devel
mailing list