[njs] Improved working with the path argument in "fs" module.

Dmitry Volyntsev xeioex at nginx.com
Fri Oct 2 12:20:32 UTC 2020


details:   https://hg.nginx.org/njs/rev/f6bf6357ab6b
branches:  
changeset: 1534:f6bf6357ab6b
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Oct 02 12:18:44 2020 +0000
description:
Improved working with the path argument in "fs" module.

diffstat:

 src/njs_fs.c             |  318 +++++++++++++++++++++-------------------------
 src/njs_string.c         |   13 +
 src/njs_string.h         |    2 +
 src/njs_unix.h           |    6 +
 test/njs_expect_test.exp |    6 +
 5 files changed, 170 insertions(+), 175 deletions(-)

diffs (720 lines):

diff -r 2065b127bd90 -r f6bf6357ab6b src/njs_fs.c
--- a/src/njs_fs.c	Fri Oct 02 12:18:41 2020 +0000
+++ b/src/njs_fs.c	Fri Oct 02 12:18:44 2020 +0000
@@ -81,20 +81,20 @@ typedef njs_int_t (*njs_file_tree_walk_c
 static njs_int_t njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data);
 
 static njs_int_t njs_fs_error(njs_vm_t *vm, const char *syscall,
-    const char *desc, njs_value_t *path, int errn, njs_value_t *retval);
+    const char *desc, const char *path, int errn, njs_value_t *retval);
 static njs_int_t njs_fs_result(njs_vm_t *vm, njs_value_t *result,
     njs_index_t calltype, const njs_value_t* callback, njs_uint_t nargs);
 
 static njs_int_t njs_file_tree_walk(const char *path,
     njs_file_tree_walk_cb_t cb, int fd_limit, njs_ftw_flags_t flags);
 
-static njs_int_t njs_fs_make_path(njs_vm_t *vm, const char *path, mode_t md,
+static njs_int_t njs_fs_make_path(njs_vm_t *vm, char *path, mode_t md,
     njs_bool_t recursive, njs_value_t *retval);
 static njs_int_t njs_fs_rmtree(njs_vm_t *vm, const char *path,
     njs_bool_t recursive, njs_value_t *retval);
 
-static njs_int_t njs_fs_path(njs_vm_t *vm, const char **dst,
-    const njs_value_t* src, const njs_str_t *prop_name);
+static const char *njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1],
+    const njs_value_t *src, const char *prop_name);
 static int njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags);
 static mode_t njs_fs_mode(njs_vm_t *vm, njs_value_t *value,
     mode_t default_mode);
@@ -142,16 +142,15 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
     int                          fd, flags;
     njs_str_t                    data;
     njs_int_t                    ret;
-    const char                   *file_path;
-    njs_value_t                  flag, encode, retval, *callback, *options,
-                                 *path;
+    const char                   *path;
+    njs_value_t                  flag, encode, retval, *callback, *options;
     struct stat                  sb;
     const njs_buffer_encoding_t  *encoding;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    char                         path_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -215,7 +214,7 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
         }
     }
 
-    fd = open(file_path, flags);
+    fd = open(path, flags);
     if (njs_slow_path(fd < 0)) {
         ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &retval);
         goto done;
@@ -277,18 +276,18 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
     ssize_t                      n;
     njs_str_t                    content;
     njs_int_t                    ret;
-    const char                   *file_path;
-    njs_value_t                  flag, mode, encode, retval, *path, *data,
-                                 *callback, *options;
+    const char                   *path;
+    njs_value_t                  flag, mode, encode, retval, *data, *callback,
+                                 *options;
     njs_typed_array_t            *array;
     njs_fs_calltype_t            calltype;
     njs_array_buffer_t           *buffer;
     const njs_buffer_encoding_t  *encoding;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    char                         path_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -395,7 +394,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
         return NJS_ERROR;
     }
 
-    fd = open(file_path, flags, md);
+    fd = open(path, flags, md);
     if (njs_slow_path(fd < 0)) {
         ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &retval);
         goto done;
@@ -441,8 +440,9 @@ njs_fs_rename(njs_vm_t *vm, njs_value_t 
     njs_index_t calltype)
 {
     njs_int_t    ret;
-    const char   *old_path, *new_path;
+    const char   *path, *newpath;
     njs_value_t  retval, *callback;
+    char         path_buf[NJS_MAX_PATH + 1], newpath_buf[NJS_MAX_PATH + 1];
 
     callback = NULL;
 
@@ -454,21 +454,19 @@ njs_fs_rename(njs_vm_t *vm, njs_value_t 
         }
     }
 
-    ret = njs_fs_path(vm, &old_path, njs_arg(args, nargs, 1),
-                          &njs_str_value("oldPath"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "oldPath");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
-    ret = njs_fs_path(vm, &new_path, njs_arg(args, nargs, 2),
-                          &njs_str_value("newPath"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    newpath = njs_fs_path(vm, newpath_buf, njs_arg(args, nargs, 2), "newPath");
+    if (njs_slow_path(newpath == NULL)) {
+        return NJS_ERROR;
     }
 
     njs_set_undefined(&retval);
 
-    ret = rename(old_path, new_path);
+    ret = rename(path, newpath);
     if (njs_slow_path(ret != 0)) {
         ret = njs_fs_error(vm, "rename", strerror(errno), NULL, errno, &retval);
     }
@@ -487,13 +485,13 @@ njs_fs_access(njs_vm_t *vm, njs_value_t 
 {
     int          md;
     njs_int_t    ret;
-    const char  *file_path;
-    njs_value_t  retval, *path, *callback, *mode;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    const char  *path;
+    njs_value_t  retval, *callback, *mode;
+    char         path_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -527,7 +525,7 @@ njs_fs_access(njs_vm_t *vm, njs_value_t 
 
     njs_set_undefined(&retval);
 
-    ret = access(file_path, md);
+    ret = access(path, md);
     if (njs_slow_path(ret != 0)) {
         ret = njs_fs_error(vm, "access", strerror(errno), path, errno, &retval);
     }
@@ -545,19 +543,18 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t
     njs_index_t calltype)
 {
     njs_int_t    ret;
-    const char  *target_path, *file_path;
-    njs_value_t  retval, *target, *path, *callback, *type;
-
-    target = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &target_path, target, &njs_str_value("target"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    const char  *target, *path;
+    njs_value_t  retval, *callback, *type;
+    char         target_buf[NJS_MAX_PATH + 1], path_buf[NJS_MAX_PATH + 1];
+
+    target = njs_fs_path(vm, target_buf, njs_arg(args, nargs, 1), "target");
+    if (njs_slow_path(target == NULL)) {
+        return NJS_ERROR;
     }
 
-    path = njs_arg(args, nargs, 2);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 2), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -582,7 +579,7 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t
 
     njs_set_undefined(&retval);
 
-    ret = symlink(target_path, file_path);
+    ret = symlink(target, path);
     if (njs_slow_path(ret != 0)) {
         ret = njs_fs_error(vm, "symlink", strerror(errno), path, errno,
                            &retval);
@@ -601,13 +598,13 @@ njs_fs_unlink(njs_vm_t *vm, njs_value_t 
     njs_index_t calltype)
 {
     njs_int_t    ret;
-    const char   *file_path;
-    njs_value_t  retval, *path, *callback;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    const char   *path;
+    njs_value_t  retval, *callback;
+    char         path_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -622,7 +619,7 @@ njs_fs_unlink(njs_vm_t *vm, njs_value_t 
 
     njs_set_undefined(&retval);
 
-    ret = unlink(file_path);
+    ret = unlink(path);
     if (njs_slow_path(ret != 0)) {
         ret = njs_fs_error(vm, "unlink", strerror(errno), path, errno, &retval);
     }
@@ -641,15 +638,15 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_
 {
     njs_int_t                    ret;
     njs_str_t                    s;
-    const char                   *file_path;
-    njs_value_t                  encode, retval, *path, *callback, *options;
+    const char                   *path;
+    njs_value_t                  encode, retval, *callback, *options;
     const njs_buffer_encoding_t  *encoding;
-    char                         path_buf[MAXPATHLEN];
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    char                         path_buf[NJS_MAX_PATH + 1],
+                                 dst_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -700,7 +697,7 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_
         }
     }
 
-    s.start = (u_char *) realpath(file_path, path_buf);
+    s.start = (u_char *) realpath(path, dst_buf);
     if (njs_slow_path(s.start == NULL)) {
         ret = njs_fs_error(vm, "realpath", strerror(errno), path, errno,
                            &retval);
@@ -730,15 +727,15 @@ static njs_int_t
 njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype)
 {
+    char         *path;
     mode_t       md;
     njs_int_t    ret;
-    const char   *file_path;
-    njs_value_t  mode, recursive, retval, *path, *callback, *options;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    njs_value_t  mode, recursive, retval, *callback, *options;
+    char         path_buf[NJS_MAX_PATH + 1];
+
+    path = (char *) njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -792,8 +789,7 @@ njs_fs_mkdir(njs_vm_t *vm, njs_value_t *
         return NJS_ERROR;
     }
 
-    ret = njs_fs_make_path(vm, file_path, md, njs_is_true(&recursive),
-                           &retval);
+    ret = njs_fs_make_path(vm, path, md, njs_is_true(&recursive), &retval);
 
     if (ret == NJS_OK) {
         return njs_fs_result(vm, &retval, calltype, callback, 1);
@@ -808,13 +804,13 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *
     njs_index_t calltype)
 {
     njs_int_t    ret;
-    const char   *file_path;
-    njs_value_t  recursive, retval, *path, *callback, *options;
-
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &file_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    const char   *path;
+    njs_value_t  recursive, retval, *callback, *options;
+    char         path_buf[NJS_MAX_PATH + 1];
+
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -852,7 +848,7 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *
         }
     }
 
-    ret = njs_fs_rmtree(vm, file_path, njs_is_true(&recursive), &retval);
+    ret = njs_fs_rmtree(vm, path, njs_is_true(&recursive), &retval);
 
     if (ret == NJS_OK) {
         return njs_fs_result(vm, &retval, calltype, callback, 1);
@@ -869,19 +865,19 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t
     DIR                          *dir;
     njs_str_t                    s;
     njs_int_t                    ret;
-    const char                   *dir_path;
-    njs_value_t                  encode, types, ename, etype, retval, *path,
+    const char                   *path;
+    njs_value_t                  encode, types, ename, etype, retval,
                                  *callback, *options, *value;
     njs_array_t                  *results;
     struct dirent                *entry;
     const njs_buffer_encoding_t  *encoding;
+    char                         path_buf[NJS_MAX_PATH + 1];
 
     static const njs_value_t  string_types = njs_string("withFileTypes");
 
-    path = njs_arg(args, nargs, 1);
-    ret = njs_fs_path(vm, &dir_path, path, &njs_str_value("path"));
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
+    path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
+    if (njs_slow_path(path == NULL)) {
+        return NJS_ERROR;
     }
 
     callback = NULL;
@@ -945,13 +941,15 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t
 
     njs_set_array(&retval, results);
 
-    dir = opendir(dir_path);
+    dir = opendir(path);
     if (njs_slow_path(dir == NULL)) {
         ret = njs_fs_error(vm, "opendir", strerror(errno), path, errno,
                            &retval);
         goto done;
     }
 
+    ret = NJS_OK;
+
     for ( ;; ) {
         errno = 0;
         entry = readdir(dir);
@@ -1077,16 +1075,13 @@ njs_fs_fd_read(njs_vm_t *vm, int fd, njs
 
 
 static njs_int_t
-njs_fs_make_path(njs_vm_t *vm, const char *path, mode_t md,
-    njs_bool_t recursive, njs_value_t *retval)
+njs_fs_make_path(njs_vm_t *vm, char *path, mode_t md, njs_bool_t recursive,
+    njs_value_t *retval)
 {
     int          err;
-    ssize_t      length;
     njs_int_t    ret;
     const char   *p, *prev, *end;
-    njs_value_t  value;
     struct stat  sb;
-    char         path_buf[MAXPATHLEN];
 
     njs_set_undefined(retval);
 
@@ -1111,15 +1106,14 @@ njs_fs_make_path(njs_vm_t *vm, const cha
             p = end;
         }
 
-        if (njs_slow_path((p - path) > MAXPATHLEN)) {
+        if (njs_slow_path((p - path) > NJS_MAX_PATH)) {
             njs_internal_error(vm, "too large path");
             return NJS_ERROR;
         }
 
-        memcpy(&path_buf[prev - path], &path[prev - path], p - prev);
-        path_buf[p - path] = '\0';
-
-        ret = mkdir(path_buf, md);
+        path[p - path] = '\0';
+
+        ret = mkdir(path, md);
         err = errno;
 
         switch (ret) {
@@ -1133,7 +1127,7 @@ njs_fs_make_path(njs_vm_t *vm, const cha
 
         case EEXIST:
         default:
-            ret = stat(path_buf, &sb);
+            ret = stat(path, &sb);
             if (ret == 0) {
                 if (!S_ISDIR(sb.st_mode)) {
                     err = ENOTDIR;
@@ -1150,7 +1144,7 @@ njs_fs_make_path(njs_vm_t *vm, const cha
             break;
         }
 
-        path_buf[p - path] = '/';
+        path[p - path] = '/';
         prev = p;
     }
 
@@ -1158,17 +1152,7 @@ njs_fs_make_path(njs_vm_t *vm, const cha
 
 failed:
 
-    length = njs_utf8_length((u_char *) path, end - path);
-    if (njs_slow_path(length < 0)) {
-        length = 0;
-    }
-
-    ret = njs_string_new(vm, &value, (u_char *) path, end - path, length);
-    if (ret != NJS_OK) {
-        return NJS_ERROR;
-    }
-
-    return njs_fs_error(vm, "mkdir", strerror(err), &value, err, retval);
+    return njs_fs_error(vm, "mkdir", strerror(err), path, err, retval);
 }
 
 
@@ -1277,7 +1261,7 @@ njs_ftw(char *path, njs_file_tree_walk_c
                 continue;
             }
 
-            if (njs_slow_path(length >= (PATH_MAX - len))) {
+            if (njs_slow_path(length >= (NJS_MAX_PATH - len))) {
                 errno = ENAMETOOLONG;
                 ret = NJS_ERROR;
                 goto done;
@@ -1329,10 +1313,10 @@ njs_file_tree_walk(const char *path, njs
     njs_ftw_flags_t flags)
 {
     size_t  len;
-    char    pathbuf[PATH_MAX + 1];
+    char    pathbuf[NJS_MAX_PATH + 1];
 
     len = njs_strlen(path);
-    if (njs_slow_path(len > PATH_MAX)) {
+    if (njs_slow_path(len > NJS_MAX_PATH)) {
         errno = ENAMETOOLONG;
         return -1;
     }
@@ -1361,11 +1345,8 @@ static njs_int_t
 njs_fs_rmtree(njs_vm_t *vm, const char *path, njs_bool_t recursive,
     njs_value_t *retval)
 {
-    size_t       size;
-    ssize_t      length;
-    njs_int_t    ret;
-    const char   *description;
-    njs_value_t  value;
+    njs_int_t   ret;
+    const char  *description;
 
     njs_set_undefined(retval);
 
@@ -1387,36 +1368,22 @@ njs_fs_rmtree(njs_vm_t *vm, const char *
         description = strerror(errno);
     }
 
-    size = njs_strlen(path);
-    length = njs_utf8_length((u_char *) path, size);
-    if (njs_slow_path(length < 0)) {
-        length = 0;
-    }
-
-    ret = njs_string_new(vm, &value, (u_char *) path, size, length);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NJS_ERROR;
-    }
-
-    return njs_fs_error(vm, "rmdir", description, &value, errno, retval);
+    return njs_fs_error(vm, "rmdir", description, path, errno, retval);
 }
 
 
-static njs_int_t
-njs_fs_path(njs_vm_t *vm, const char **dst, const njs_value_t* src,
-    const njs_str_t *prop_name)
+static const char *
+njs_fs_path(njs_vm_t *vm, char *storage, const njs_value_t *src,
+    const char *prop_name)
 {
-    u_char              *data, *p, *start;
+    u_char              *p;
+    njs_str_t           str;
     njs_typed_array_t   *array;
     njs_array_buffer_t  *buffer;
 
     switch (src->type) {
     case NJS_STRING:
-        *dst = njs_string_to_c_string(vm, njs_value_arg(src));
-        if (njs_slow_path(*dst == NULL)) {
-            return NJS_ERROR;
-        }
-
+        njs_string_get(src, &str);
         break;
 
     case NJS_TYPED_ARRAY:
@@ -1425,35 +1392,33 @@ njs_fs_path(njs_vm_t *vm, const char **d
         buffer = array->buffer;
         if (njs_slow_path(njs_is_detached_buffer(buffer))) {
             njs_type_error(vm, "detached buffer");
-            return NJS_ERROR;
-        }
-
-        start = &buffer->u.u8[array->offset];
-
-        if (njs_slow_path(memchr(start, '\0', array->byte_length) != 0)) {
-            njs_type_error(vm, "\"%V\" must be a Buffer without null bytes",
-                           prop_name);
-            return NJS_ERROR;
+            return NULL;
         }
 
-        data = njs_mp_alloc(vm->mem_pool, array->byte_length + 1);
-        if (njs_slow_path(data == NULL)) {
-            njs_memory_error(vm);
-            return NJS_ERROR;
-        }
-
-        p = njs_cpymem(data, start, array->byte_length);
-        *p++ = '\0';
-
-        *dst = (char *) data;
+        str.start = &buffer->u.u8[array->offset];
+        str.length = array->byte_length;
         break;
 
     default:
-        njs_type_error(vm, "\"%V\" must be a string or Buffer", prop_name);
-        return NJS_ERROR;
+        njs_type_error(vm, "\"%s\" must be a string or Buffer", prop_name);
+        return NULL;
+    }
+
+    if (njs_slow_path(str.length > NJS_MAX_PATH - 1)) {
+        njs_type_error(vm, "\"%s\" is too long >= %d", prop_name, NJS_MAX_PATH);
+        return NULL;
     }
 
-    return NJS_OK;
+    if (njs_slow_path(memchr(str.start, '\0', str.length) != 0)) {
+        njs_type_error(vm, "\"%s\" must be a Buffer without null bytes",
+                       prop_name);
+        return NULL;
+    }
+
+    p = njs_cpymem(storage, str.start, str.length);
+    *p++ = '\0';
+
+    return storage;
 }
 
 
@@ -1511,7 +1476,7 @@ njs_fs_mode(njs_vm_t *vm, njs_value_t *v
 
 static njs_int_t
 njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
-    njs_value_t *path, int errn, njs_value_t *retval)
+    const char *path, int errn, njs_value_t *retval)
 {
     size_t        size;
     njs_int_t     ret;
@@ -1526,7 +1491,7 @@ njs_fs_error(njs_vm_t *vm, const char *s
 
     size = description != NULL ? njs_strlen(description) : 0;
 
-    ret = njs_string_new(vm, &value, (u_char *) description, size, size);
+    ret = njs_string_create(vm, &value, description, size);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -1547,9 +1512,8 @@ njs_fs_error(njs_vm_t *vm, const char *s
         }
 
         code = njs_errno_string(errn);
-        size = njs_strlen(code);
-
-        ret = njs_string_new(vm, &value, (u_char *) code, size, size);
+
+        ret = njs_string_create(vm, &value, code, njs_strlen(code));
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1562,16 +1526,20 @@ njs_fs_error(njs_vm_t *vm, const char *s
     }
 
     if (path != NULL) {
+        ret = njs_string_create(vm, &value, path, njs_strlen(path));
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
+
         ret = njs_value_property_set(vm, retval, njs_value_arg(&string_path),
-                                     path);
+                                     &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
     }
 
     if (syscall != NULL) {
-        size = njs_strlen(syscall);
-        ret = njs_string_new(vm, &value, (u_char *) syscall, size, size);
+        ret = njs_string_create(vm, &value, syscall, njs_strlen(syscall));
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
diff -r 2065b127bd90 -r f6bf6357ab6b src/njs_string.c
--- a/src/njs_string.c	Fri Oct 02 12:18:41 2020 +0000
+++ b/src/njs_string.c	Fri Oct 02 12:18:44 2020 +0000
@@ -134,6 +134,19 @@ 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,
+    size_t size)
+{
+    njs_str_t  str;
+
+    str.start = (u_char *) src;
+    str.length = size;
+
+    return njs_string_decode_utf8(vm, value, &str);
+}
+
+
+njs_int_t
 njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
     uint32_t size, uint32_t length)
 {
diff -r 2065b127bd90 -r f6bf6357ab6b src/njs_string.h
--- a/src/njs_string.h	Fri Oct 02 12:18:41 2020 +0000
+++ b/src/njs_string.h	Fri Oct 02 12:18:44 2020 +0000
@@ -185,6 +185,8 @@ u_char *njs_string_alloc(njs_vm_t *vm, n
     uint64_t length);
 njs_int_t njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
     uint32_t size, uint32_t length);
+njs_int_t njs_string_create(njs_vm_t *vm, njs_value_t *value, const char *src,
+    size_t size);
 
 void njs_encode_hex(njs_str_t *dst, const njs_str_t *src);
 size_t njs_encode_hex_length(const njs_str_t *src, size_t *out_size);
diff -r 2065b127bd90 -r f6bf6357ab6b src/njs_unix.h
--- a/src/njs_unix.h	Fri Oct 02 12:18:41 2020 +0000
+++ b/src/njs_unix.h	Fri Oct 02 12:18:44 2020 +0000
@@ -47,4 +47,10 @@
 
 #include <unistd.h>
 
+#if defined(PATH_MAX)
+#define NJS_MAX_PATH             PATH_MAX
+#else
+#define NJS_MAX_PATH             4096
+#endif
+
 #endif /* _NJS_UNIX_H_INCLUDED_ */
diff -r 2065b127bd90 -r f6bf6357ab6b test/njs_expect_test.exp
--- a/test/njs_expect_test.exp	Fri Oct 02 12:18:41 2020 +0000
+++ b/test/njs_expect_test.exp	Fri Oct 02 12:18:44 2020 +0000
@@ -477,6 +477,8 @@ njs_test {
      "undefined\r\nx undefined\r\n>> "}
     {"fs.readFile('test/fs/ascii', {encoding:'utf8',flag:'r+'}, function (e, data) {console.log(data[599], data[600])})\r\n"
      "undefined\r\nx undefined\r\n>> "}
+    {"fs.readFile(Buffer.from([0x80,0x80]), function(e) {console.log(e.path.codePointAt())})\r\n"
+     "undefined\r\n65533"}
 }
 
 njs_test {
@@ -504,6 +506,8 @@ njs_test {
      "undefined\r\n>> "}
     {"fs.readFileSync('test/fs/non_utf8', 'utf8').charCodeAt(1)\r\n"
      "65533"}
+    {"fs.readFile('x'.repeat(8192))\r\n"
+     "TypeError: \"path\" is too long >= 4096"}
 }
 
 njs_test {
@@ -540,6 +544,8 @@ njs_test {
      "undefined\r\n>> "}
     {"fs.writeFile('/invalid_path', 'ABC', function (e) { console.log(JSON.stringify(e))})\r\n"
      "undefined\r\n{\"errno\":13,\"code\":\"EACCES\",\"path\":\"/invalid_path\",\"syscall\":\"open\"}\r\n>> "}
+    {"fs.writeFile(Buffer.from('/invalid_path'), 'ABC', function (e) { console.log(typeof e.path)})\r\n"
+     "undefined\r\nstring\r\n>> "}
 }
 
 # require('fs').writeFileSync()


More information about the nginx-devel mailing list