From 035c2c76f16790b0d9e30baaba81dff3e9c039be Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 16 Dec 2018 14:18:16 -0500 Subject: [PATCH] deps: upgrade to libuv 1.24.1 PR-URL: https://github.com/nodejs/node/pull/25078 Fixes: https://github.com/nodejs/node/issues/24521 Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius --- deps/uv/.gitignore | 2 +- deps/uv/AUTHORS | 6 ++ deps/uv/CMakeLists.txt | 8 ++- deps/uv/ChangeLog | 33 +++++++++++ deps/uv/Makefile.am | 3 + deps/uv/README.md | 3 +- deps/uv/configure.ac | 2 +- deps/uv/docs/src/handle.rst | 2 + deps/uv/include/uv/version.h | 2 +- deps/uv/include/uv/win.h | 1 + deps/uv/src/inet.c | 11 +--- deps/uv/src/strscpy.c | 17 ++++++ deps/uv/src/strscpy.h | 18 ++++++ deps/uv/src/timer.c | 2 +- deps/uv/src/unix/aix.c | 32 +++++------ deps/uv/src/unix/darwin-proctitle.c | 3 +- deps/uv/src/unix/fs.c | 42 ++++++++++---- deps/uv/src/unix/linux-core.c | 3 + deps/uv/src/unix/linux-inotify.c | 6 +- deps/uv/src/unix/netbsd.c | 3 +- deps/uv/src/unix/os390.c | 6 +- deps/uv/src/unix/pipe.c | 6 +- deps/uv/src/unix/sunos.c | 3 +- deps/uv/src/uv-common.c | 2 +- deps/uv/src/uv-common.h | 1 + deps/uv/src/uv-data-getter-setters.c | 16 +++--- deps/uv/src/win/dl.c | 8 ++- deps/uv/src/win/fs-event.c | 8 +-- deps/uv/src/win/fs.c | 49 ++++++++++++---- deps/uv/src/win/pipe.c | 6 +- deps/uv/src/win/poll.c | 4 +- deps/uv/src/win/process.c | 6 +- deps/uv/src/win/tty.c | 5 +- deps/uv/src/win/winapi.h | 3 + deps/uv/test/run-tests.c | 8 +-- deps/uv/test/runner-win.c | 7 ++- deps/uv/test/runner-win.h | 2 + deps/uv/test/test-close-fd.c | 6 +- deps/uv/test/test-condvar.c | 2 +- deps/uv/test/test-emfile.c | 16 ++++-- deps/uv/test/test-fork.c | 3 + deps/uv/test/test-fs.c | 56 +++++++++++++++++-- deps/uv/test/test-ip4-addr.c | 7 ++- deps/uv/test/test-ip6-addr.c | 2 +- deps/uv/test/test-list.h | 4 ++ .../test/test-pipe-close-stdout-read-stdin.c | 4 ++ deps/uv/test/test-platform-output.c | 2 +- .../test-poll-close-doesnt-corrupt-stack.c | 2 +- deps/uv/test/test-poll-oob.c | 5 ++ deps/uv/test/test-process-title-threadsafe.c | 3 +- deps/uv/test/test-process-title.c | 4 +- deps/uv/test/test-signal-multiple-loops.c | 6 +- deps/uv/test/test-spawn.c | 8 ++- deps/uv/test/test-strscpy.c | 53 ++++++++++++++++++ deps/uv/test/test-tcp-close-accept.c | 6 +- deps/uv/test/test-tcp-oob.c | 7 ++- deps/uv/test/test-tcp-write-after-connect.c | 6 +- deps/uv/test/test-tty.c | 2 - deps/uv/test/test.gyp | 3 +- deps/uv/uv.gyp | 2 + 60 files changed, 421 insertions(+), 127 deletions(-) create mode 100644 deps/uv/src/strscpy.c create mode 100644 deps/uv/src/strscpy.h create mode 100644 deps/uv/test/test-strscpy.c diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore index 7536abd54970a2..c132987917623e 100644 --- a/deps/uv/.gitignore +++ b/deps/uv/.gitignore @@ -42,7 +42,7 @@ Makefile.in /android-toolchain /out/ -/build/gyp +/build/ /test/.libs/ /test/run-tests diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 2f93bd8dffefa4..a8b50f6209d7a0 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -356,3 +356,9 @@ hitesh Svante Signell Samuel Thibault Jeremy Studer +damon-kwok <563066990@qq.com> +Damon Kwok +Ashe Connor +Rick +Ivan Krylov +Michael Meier diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index 8cd862715aef9d..9f1c0587a98060 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -15,6 +15,7 @@ set(uv_sources src/fs-poll.c src/idna.c src/inet.c + src/strscpy.c src/threadpool.c src/timer.c src/uv-common.c @@ -116,6 +117,7 @@ set(uv_test_sources test/test-socket-buffer-size.c test/test-spawn.c test/test-stdio-over-pipes.c + test/test-strscpy.c test/test-tcp-alloc-cb-fail.c test/test-tcp-bind-error.c test/test-tcp-bind6-error.c @@ -208,7 +210,11 @@ if(WIN32) list(APPEND uv_test_sources src/win/snprintf.c test/runner-win.c) else() list(APPEND uv_defines _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE) - list(APPEND uv_libraries pthread) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android") + # Android has pthread as part of its c library, not as a separate + # libpthread.so. + list(APPEND uv_libraries pthread) + endif() list(APPEND uv_sources src/unix/async.c src/unix/core.c diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 3376481d62d1f0..f7881e6bbc4f92 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,36 @@ +2018.12.17, Version 1.24.1 (Stable), 274f2bd3b70847cadd9a3965577a87e666ab9ac3 + +Changes since version 1.24.0: + +* test: fix platform_output test on cygwin (damon-kwok) + +* gitignore: ignore build/ directory (Damon Kwok) + +* unix: zero epoll_event before use (Ashe Connor) + +* darwin: use runtime check for file cloning (Ben Noordhuis) + +* doc: replace deprecated build command on macOS (Rick) + +* warnings: fix code that emits compiler warnings (Jameson Nash) + +* doc: clarify expected memory management strategy (Ivan Krylov) + +* test: add uv_inet_ntop(AF_INET) coverage (Ben Noordhuis) + +* unix: harden string copying, introduce strscpy() (Ben Noordhuis) + +* linux: get rid of strncpy() call (Ben Noordhuis) + +* aix: get rid of strcat() calls (Ben Noordhuis) + +* aix: fix data race in uv_fs_event_start() (Ben Noordhuis) + +* win: fs: fix `FILE_FLAG_NO_BUFFERING` for writes (Joran Dirk Greef) + +* build: don't link against -lpthread on Android (Michael Meier) + + 2018.11.14, Version 1.24.0 (Stable), 2d427ee0083d1baf995df4ebf79a3f8890e9a3e1 Changes since version 1.23.2: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 098d2f57931d18..f9c9c9a05d14f3 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -32,6 +32,8 @@ libuv_la_SOURCES = src/fs-poll.c \ src/idna.c \ src/inet.c \ src/queue.h \ + src/strscpy.c \ + src/strscpy.h \ src/threadpool.c \ src/timer.c \ src/uv-data-getter-setters.c \ @@ -241,6 +243,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-socket-buffer-size.c \ test/test-spawn.c \ test/test-stdio-over-pipes.c \ + test/test-strscpy.c \ test/test-tcp-alloc-cb-fail.c \ test/test-tcp-bind-error.c \ test/test-tcp-bind6-error.c \ diff --git a/deps/uv/README.md b/deps/uv/README.md index b24b722612edf3..fb5971d3e35425 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -262,8 +262,7 @@ Run: ```bash $ ./gyp_uv.py -f xcode -$ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \ - -configuration Release -target All +$ xcodebuild -ARCHS="x86_64" -project out/uv.xcodeproj -configuration Release -alltargets ``` Using Homebrew: diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 68939c699e4a32..35e7c1b7493acd 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.24.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.24.1], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index 86fa811d3f7eed..544794db06c956 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -140,6 +140,8 @@ API Request handle to be closed. `close_cb` will be called asynchronously after this call. This MUST be called on each handle before memory is released. + Moreover, the memory can only be released in `close_cb` or after it has + returned. Handles that wrap file descriptors are closed immediately but `close_cb` will still be deferred to the next iteration of the event loop. diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index 105e9a2615f4a6..3bc023700ef002 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -32,7 +32,7 @@ #define UV_VERSION_MAJOR 1 #define UV_VERSION_MINOR 24 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv/win.h b/deps/uv/include/uv/win.h index bb9477c8346bdc..edd2cc6eb9cd3f 100644 --- a/deps/uv/include/uv/win.h +++ b/deps/uv/include/uv/win.h @@ -25,6 +25,7 @@ #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) typedef intptr_t ssize_t; +# define SSIZE_MAX INTPTR_MAX # define _SSIZE_T_ # define _SSIZE_T_DEFINED #endif diff --git a/deps/uv/src/inet.c b/deps/uv/src/inet.c index 4598ca1e9f9670..698ab232e53714 100644 --- a/deps/uv/src/inet.c +++ b/deps/uv/src/inet.c @@ -59,8 +59,7 @@ static int inet_ntop4(const unsigned char *src, char *dst, size_t size) { if (l <= 0 || (size_t) l >= size) { return UV_ENOSPC; } - strncpy(dst, tmp, size); - dst[size - 1] = '\0'; + uv__strscpy(dst, tmp, size); return 0; } @@ -142,14 +141,8 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) { if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words)) *tp++ = ':'; *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { + if (UV_E2BIG == uv__strscpy(dst, tmp, size)) return UV_ENOSPC; - } - strcpy(dst, tmp); return 0; } diff --git a/deps/uv/src/strscpy.c b/deps/uv/src/strscpy.c new file mode 100644 index 00000000000000..2a2bdce7450113 --- /dev/null +++ b/deps/uv/src/strscpy.c @@ -0,0 +1,17 @@ +#include "strscpy.h" +#include /* SSIZE_MAX */ + +ssize_t uv__strscpy(char* d, const char* s, size_t n) { + size_t i; + + for (i = 0; i < n; i++) + if ('\0' == (d[i] = s[i])) + return i > SSIZE_MAX ? UV_E2BIG : (ssize_t) i; + + if (i == 0) + return 0; + + d[--i] = '\0'; + + return UV_E2BIG; +} diff --git a/deps/uv/src/strscpy.h b/deps/uv/src/strscpy.h new file mode 100644 index 00000000000000..fbe0a393f20542 --- /dev/null +++ b/deps/uv/src/strscpy.h @@ -0,0 +1,18 @@ +#ifndef UV_STRSCPY_H_ +#define UV_STRSCPY_H_ + +/* Include uv.h for its definitions of size_t and ssize_t. + * size_t can be obtained directly from but ssize_t requires + * some hoop jumping on Windows that I didn't want to duplicate here. + */ +#include "uv.h" + +/* Copies up to |n-1| bytes from |d| to |s| and always zero-terminates + * the result, except when |n==0|. Returns the number of bytes copied + * or UV_E2BIG if |d| is too small. + * + * See https://www.kernel.org/doc/htmldocs/kernel-api/API-strscpy.html + */ +ssize_t uv__strscpy(char* d, const char* s, size_t n); + +#endif /* UV_STRSCPY_H_ */ diff --git a/deps/uv/src/timer.c b/deps/uv/src/timer.c index 2bf449a736c2bb..dd78bcbad9a986 100644 --- a/deps/uv/src/timer.c +++ b/deps/uv/src/timer.c @@ -152,7 +152,7 @@ int uv__next_timeout(const uv_loop_t* loop) { if (diff > INT_MAX) diff = INT_MAX; - return diff; + return (int) diff; } diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index baac8e6c0067d7..44c9cf5b639c31 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -358,19 +358,15 @@ void uv_loadavg(double avg[3]) { #ifdef HAVE_SYS_AHAFS_EVPRODS_H -static char *uv__rawname(char *cp) { - static char rawbuf[FILENAME_MAX+1]; - char *dp = rindex(cp, '/'); +static char* uv__rawname(const char* cp, char (*dst)[FILENAME_MAX+1]) { + char* dp; + dp = rindex(cp, '/'); if (dp == 0) return 0; - *dp = 0; - strcpy(rawbuf, cp); - *dp = '/'; - strcat(rawbuf, "/r"); - strcat(rawbuf, dp+1); - return rawbuf; + snprintf(*dst, sizeof(*dst), "%.*s/r%s", (int) (dp - cp), cp, dp + 1); + return *dst; } @@ -399,6 +395,7 @@ static int uv__path_is_a_directory(char* filename) { * Returns 0 if AHAFS is mounted, or an error code < 0 on failure */ static int uv__is_ahafs_mounted(void){ + char rawbuf[FILENAME_MAX+1]; int rv, i = 2; struct vmount *p; int size_multiplier = 10; @@ -432,7 +429,7 @@ static int uv__is_ahafs_mounted(void){ obj = vmt2dataptr(vmt, VMT_OBJECT); /* device */ stub = vmt2dataptr(vmt, VMT_STUB); /* mount point */ - if (EQ(obj, dev) || EQ(uv__rawname(obj), dev) || EQ(stub, dev)) { + if (EQ(obj, dev) || EQ(uv__rawname(obj, &rawbuf), dev) || EQ(stub, dev)) { uv__free(p); /* Found a match */ return 0; } @@ -453,7 +450,8 @@ static int uv__makedir_p(const char *dir) { size_t len; int err; - snprintf(tmp, sizeof(tmp),"%s",dir); + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(tmp, dir, sizeof(tmp)); len = strlen(tmp); if (tmp[len - 1] == '/') tmp[len - 1] = 0; @@ -702,9 +700,9 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int else p++; } - strncpy(fname, p, sizeof(fname) - 1); - /* Just in case */ - fname[sizeof(fname) - 1] = '\0'; + + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(fname, p, sizeof(fname)); handle->cb(handle, fname, events, 0); } @@ -735,7 +733,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, /* Figure out whether filename is absolute or not */ if (filename[0] == '/') { /* We have absolute pathname */ - snprintf(absolute_path, sizeof(absolute_path), "%s", filename); + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(absolute_path, filename, sizeof(absolute_path)); } else { /* We have a relative pathname, compose the absolute pathname */ snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid()); @@ -986,7 +985,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return UV_ENOMEM; } - strcpy(cpu_id.name, FIRST_CPU); + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name)); result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); if (result == -1) { uv__free(ps_cpus); diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c index 92d46b7466d43b..e505bdd23f8636 100644 --- a/deps/uv/src/unix/darwin-proctitle.c +++ b/deps/uv/src/unix/darwin-proctitle.c @@ -192,8 +192,7 @@ void uv__set_process_title(const char* title) { if (dynamic_pthread_setname_np != NULL) { char namebuf[64]; /* MAXTHREADNAMESIZE */ - strncpy(namebuf, title, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; + uv__strscpy(namebuf, title, sizeof(namebuf)); dynamic_pthread_setname_np(namebuf); } } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 9068d4b115b646..d22c70f0c293d4 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -61,6 +61,7 @@ #if defined(__APPLE__) # include +# include #elif defined(__linux__) && !defined(FICLONE) # include # define FICLONE _IOW(0x94, 9, int) @@ -70,6 +71,10 @@ # include #endif +#if defined(_AIX) && _XOPEN_SOURCE <= 600 +extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ +#endif + #define INIT(subtype) \ do { \ if (req == NULL) \ @@ -722,7 +727,7 @@ static ssize_t uv__fs_utime(uv_fs_t* req) { atr.att_atimechg = 1; atr.att_mtime = req->mtime; atr.att_atime = req->atime; - return __lchattr(req->path, &atr, sizeof(atr)); + return __lchattr((char*) req->path, &atr, sizeof(atr)); #else errno = ENOSYS; return -1; @@ -793,26 +798,41 @@ static ssize_t uv__fs_write(uv_fs_t* req) { static ssize_t uv__fs_copyfile(uv_fs_t* req) { #if defined(__APPLE__) && !TARGET_OS_IPHONE /* On macOS, use the native copyfile(3). */ + static int can_clone; copyfile_flags_t flags; + char buf[64]; + size_t len; + int major; flags = COPYFILE_ALL; if (req->flags & UV_FS_COPYFILE_EXCL) flags |= COPYFILE_EXCL; -#ifdef COPYFILE_CLONE - if (req->flags & UV_FS_COPYFILE_FICLONE) - flags |= COPYFILE_CLONE; -#endif - + /* Check OS version. Cloning is only supported on macOS >= 10.12. */ if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { -#ifdef COPYFILE_CLONE_FORCE - flags |= COPYFILE_CLONE_FORCE; -#else - return UV_ENOSYS; -#endif + if (can_clone == 0) { + len = sizeof(buf); + if (sysctlbyname("kern.osrelease", buf, &len, NULL, 0)) + return UV__ERR(errno); + + if (1 != sscanf(buf, "%d", &major)) + abort(); + + can_clone = -1 + 2 * (major >= 16); /* macOS >= 10.12 */ + } + + if (can_clone < 0) + return UV_ENOSYS; } + /* copyfile() simply ignores COPYFILE_CLONE if it's not supported. */ + if (req->flags & UV_FS_COPYFILE_FICLONE) + flags |= 1 << 24; /* COPYFILE_CLONE */ + + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) + flags |= 1 << 25; /* COPYFILE_CLONE_FORCE */ + return copyfile(req->path, req->new_path, NULL, flags); #else uv_fs_t fs_req; diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 991d1c60aee3dc..3341b94e1f26fd 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -170,6 +170,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { struct epoll_event e; int rc; + memset(&e, 0, sizeof(e)); e.events = POLLIN; e.data.fd = -1; @@ -218,6 +219,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { return; } + memset(&e, 0, sizeof(e)); + while (!QUEUE_EMPTY(&loop->watcher_queue)) { q = QUEUE_HEAD(&loop->watcher_queue); QUEUE_REMOVE(q); diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c index 7797f842524ed3..9b26202fb3366d 100644 --- a/deps/uv/src/unix/linux-inotify.c +++ b/deps/uv/src/unix/linux-inotify.c @@ -278,6 +278,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, const char* path, unsigned int flags) { struct watcher_list* w; + size_t len; int events; int err; int wd; @@ -306,12 +307,13 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (w) goto no_insert; - w = uv__malloc(sizeof(*w) + strlen(path) + 1); + len = strlen(path) + 1; + w = uv__malloc(sizeof(*w) + len); if (w == NULL) return UV_ENOMEM; w->wd = wd; - w->path = strcpy((char*)(w + 1), path); + w->path = memcpy(w + 1, path, len); QUEUE_INIT(&w->watchers); w->iterating = 0; RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w); diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 4cfde1a586444c..a2a4e521542af3 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -87,7 +87,8 @@ int uv_exepath(char* buffer, size_t* size) { /* Copy string from the intermediate buffer to outer one with appropriate * length. */ - strlcpy(buffer, int_buf, *size); + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(buffer, int_buf, *size); /* Set new size. */ *size = strlen(buffer); diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index b43aebfc926940..dc146e31108108 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -229,15 +229,15 @@ static int getexe(const int pid, char* buf, size_t len) { assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A'); /* Get the offset from the lowest 3 bytes */ - Output_path = (char*)(&Output_buf) + - (Output_buf.Output_data.offsetPath & 0x00FFFFFF); + Output_path = (struct Output_path_type*) ((char*) (&Output_buf) + + (Output_buf.Output_data.offsetPath & 0x00FFFFFF)); if (Output_path->len >= len) { errno = ENOBUFS; return -1; } - strncpy(buf, Output_path->path, len); + uv__strscpy(buf, Output_path->path, len); return 0; } diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index e450a30e9c7e0c..d3b554cfc3d896 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -66,8 +66,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { sockfd = err; memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; + uv__strscpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path)); saddr.sun_family = AF_UNIX; if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { @@ -186,8 +185,7 @@ void uv_pipe_connect(uv_connect_t* req, } memset(&saddr, 0, sizeof saddr); - strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1); - saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; + uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path)); saddr.sun_family = AF_UNIX; do { diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index ec5ecd7d3ce6b9..2552a019eb474d 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -707,13 +707,14 @@ static int uv__set_phys_addr(uv_interface_address_t* address, struct sockaddr_dl* sa_addr; int sockfd; - int i; + size_t i; struct arpreq arpreq; /* This appears to only work as root */ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); for (i = 0; i < sizeof(address->phys_addr); i++) { + /* Check that all bytes of phys_addr are zero. */ if (address->phys_addr[i] != 0) return 0; } diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index 71d100a162f4ca..952bde080c2864 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -162,7 +162,7 @@ static const char* uv__unknown_err_code(int err) { #define UV_ERR_NAME_GEN_R(name, _) \ case UV_## name: \ - snprintf(buf, buflen, "%s", #name); break; + uv__strscpy(buf, #name, buflen); break; char* uv_err_name_r(int err, char* buf, size_t buflen) { switch (err) { UV_ERRNO_MAP(UV_ERR_NAME_GEN_R) diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 5555f83aee4864..15ac4d02c1332b 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -40,6 +40,7 @@ #include "uv.h" #include "uv/tree.h" #include "queue.h" +#include "strscpy.h" #if EDOM > 0 # define UV__ERR(x) (-(x)) diff --git a/deps/uv/src/uv-data-getter-setters.c b/deps/uv/src/uv-data-getter-setters.c index 533e4a2fe12bb3..b7fcd4a7fd0ae4 100644 --- a/deps/uv/src/uv-data-getter-setters.c +++ b/deps/uv/src/uv-data-getter-setters.c @@ -3,11 +3,11 @@ const char* uv_handle_type_name(uv_handle_type type) { switch (type) { #define XX(uc,lc) case UV_##uc: return #lc; - UV_HANDLE_TYPE_MAP(XX) + UV_HANDLE_TYPE_MAP(XX) #undef XX - case UV_FILE: return "file"; - case UV_HANDLE_TYPE_MAX: - case UV_UNKNOWN_HANDLE: return NULL; + case UV_FILE: return "file"; + case UV_HANDLE_TYPE_MAX: + case UV_UNKNOWN_HANDLE: return NULL; } return NULL; } @@ -31,10 +31,12 @@ void uv_handle_set_data(uv_handle_t* handle, void* data) { const char* uv_req_type_name(uv_req_type type) { switch (type) { #define XX(uc,lc) case UV_##uc: return #lc; - UV_REQ_TYPE_MAP(XX) + UV_REQ_TYPE_MAP(XX) #undef XX - case UV_REQ_TYPE_MAX: - case UV_UNKNOWN_REQ: return NULL; + case UV_REQ_TYPE_MAX: + case UV_UNKNOWN_REQ: + default: /* UV_REQ_TYPE_PRIVATE */ + return NULL; } return NULL; } diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c index 5b84555ca4d57f..676be4dc7b5b8a 100644 --- a/deps/uv/src/win/dl.c +++ b/deps/uv/src/win/dl.c @@ -64,7 +64,8 @@ void uv_dlclose(uv_lib_t* lib) { int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - *ptr = (void*) GetProcAddress(lib->handle, name); + /* Cast though integer to suppress pedantic warning about forbidden cast. */ + *ptr = (void*)(uintptr_t) GetProcAddress(lib->handle, name); return uv__dlerror(lib, "", *ptr ? 0 : GetLastError()); } @@ -75,8 +76,9 @@ const char* uv_dlerror(const uv_lib_t* lib) { static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ - DWORD_PTR args[1] = { (DWORD_PTR) errorno }; - LPSTR fallback_error = "error: %1!d!"; + static const CHAR fallback_error[] = "error: %1!d!"; + DWORD_PTR args[1]; + args[0] = (DWORD_PTR) errorno; FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 25809ea4f2f605..1244967a78dacb 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -215,11 +215,11 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv__free(long_path); long_path = NULL; } - } - if (long_path) { - uv__free(pathw); - pathw = long_path; + if (long_path) { + uv__free(pathw); + pathw = long_path; + } } dir_to_watch = pathw; diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 7ad0d077a6440b..0716ecca1221e6 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -98,14 +98,17 @@ return; \ } +#define MILLIONu (1000U * 1000U) +#define BILLIONu (1000U * 1000U * 1000U) + #define FILETIME_TO_UINT(filetime) \ - (*((uint64_t*) &(filetime)) - 116444736000000000ULL) + (*((uint64_t*) &(filetime)) - (uint64_t) 116444736 * BILLIONu) #define FILETIME_TO_TIME_T(filetime) \ - (FILETIME_TO_UINT(filetime) / 10000000ULL) + (FILETIME_TO_UINT(filetime) / (10u * MILLIONu)) #define FILETIME_TO_TIME_NS(filetime, secs) \ - ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100) + ((FILETIME_TO_UINT(filetime) - (secs * (uint64_t) 10 * MILLIONu)) * 100U) #define FILETIME_TO_TIMESPEC(ts, filetime) \ do { \ @@ -115,8 +118,8 @@ #define TIME_T_TO_FILETIME(time, filetime_ptr) \ do { \ - uint64_t bigtime = ((uint64_t) ((time) * 10000000ULL)) + \ - 116444736000000000ULL; \ + uint64_t bigtime = ((uint64_t) ((time) * (uint64_t) 10 * MILLIONu)) + \ + (uint64_t) 116444736 * BILLIONu; \ (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \ (filetime_ptr)->dwHighDateTime = bigtime >> 32; \ } while(0) @@ -507,6 +510,33 @@ void fs__open(uv_fs_t* req) { } if (flags & UV_FS_O_DIRECT) { + /* + * FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive. + * Windows returns 87, ERROR_INVALID_PARAMETER if these are combined. + * + * FILE_APPEND_DATA is included in FILE_GENERIC_WRITE: + * + * FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | + * FILE_WRITE_DATA | + * FILE_WRITE_ATTRIBUTES | + * FILE_WRITE_EA | + * FILE_APPEND_DATA | + * SYNCHRONIZE + * + * Note: Appends are also permitted by FILE_WRITE_DATA. + * + * In order for direct writes and direct appends to succeed, we therefore + * exclude FILE_APPEND_DATA if FILE_WRITE_DATA is specified, and otherwise + * fail if the user's sole permission is a direct append, since this + * particular combination is invalid. + */ + if (access & FILE_APPEND_DATA) { + if (access & FILE_WRITE_DATA) { + access &= ~FILE_APPEND_DATA; + } else { + goto einval; + } + } attributes |= FILE_FLAG_NO_BUFFERING; } @@ -788,9 +818,8 @@ void fs__unlink(uv_fs_t* req) { /* Remove read-only attribute */ FILE_BASIC_INFORMATION basic = { 0 }; - basic.FileAttributes = info.dwFileAttributes - & ~(FILE_ATTRIBUTE_READONLY) - | FILE_ATTRIBUTE_ARCHIVE; + basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) | + FILE_ATTRIBUTE_ARCHIVE; status = pNtSetInformationFile(handle, &iosb, @@ -1201,7 +1230,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, /* st_blocks contains the on-disk allocation size in 512-byte units. */ statbuf->st_blocks = - file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL; + (uint64_t) file_info.StandardInformation.AllocationSize.QuadPart >> 9; statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; @@ -1958,7 +1987,7 @@ static void fs__readlink(uv_fs_t* req) { } -static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { +static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { int r; DWORD w_realpath_len; WCHAR* w_realpath_ptr = NULL; diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 9a3cbc8a1e26e1..e303cc8a2331e7 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -1541,7 +1541,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop, frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER; break; default: - assert(0); // Unreachable. + assert(0); /* Unreachable. */ } /* Add xfer info buffer. */ bufs[buf_index++] = uv_buf_init((char*) &xfer_info, sizeof xfer_info); @@ -2141,7 +2141,7 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { if (pipe->ipc) { assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); pipe->pipe.conn.ipc_remote_pid = uv_os_getppid(); - assert(pipe->pipe.conn.ipc_remote_pid != -1); + assert(pipe->pipe.conn.ipc_remote_pid != (DWORD) -1); } return 0; } @@ -2312,7 +2312,7 @@ uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { } int uv_pipe_chmod(uv_pipe_t* handle, int mode) { - SID_IDENTIFIER_AUTHORITY sid_world = SECURITY_WORLD_SID_AUTHORITY; + SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY }; PACL old_dacl, new_dacl; PSECURITY_DESCRIPTOR sd; EXPLICIT_ACCESS ea; diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c index 77eb071c85a338..3c6678600e40cc 100644 --- a/deps/uv/src/win/poll.c +++ b/deps/uv/src/win/poll.c @@ -75,7 +75,7 @@ static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) { static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { uv_req_t* req; AFD_POLL_INFO* afd_poll_info; - DWORD result; + int result; /* Find a yet unsubmitted req to submit. */ if (handle->submitted_events_1 == 0) { @@ -136,7 +136,7 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) { AFD_POLL_INFO afd_poll_info; - DWORD result; + int result; afd_poll_info.Exclusive = TRUE; afd_poll_info.NumberOfHandles = 1; diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index e7cccd9c80123f..f9c53de0af0079 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -739,7 +739,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } } *ptr_copy = NULL; - assert(env_len == ptr - dst_copy); + assert(env_len == (size_t) (ptr - dst_copy)); /* sort our (UTF-16) copy */ qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp); @@ -799,7 +799,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, (int) (env_len - (ptr - dst))); - if (var_size != len-1) { /* race condition? */ + if (var_size != (DWORD) (len - 1)) { /* TODO: handle race condition? */ uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); } } @@ -815,7 +815,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } /* Terminate with an extra NULL. */ - assert(env_len == (ptr - dst)); + assert(env_len == (size_t) (ptr - dst)); *ptr = L'\0'; uv__free(dst_copy); diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 398288ec1de53b..45bbe9689aea1d 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -791,8 +791,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, if (KEV.uChar.UnicodeChar >= 0xDC00 && KEV.uChar.UnicodeChar < 0xE000) { /* UTF-16 surrogate pair */ - WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate, - KEV.uChar.UnicodeChar}; + WCHAR utf16_buffer[2]; + utf16_buffer[0] = handle->tty.rd.last_utf16_high_surrogate; + utf16_buffer[1] = KEV.uChar.UnicodeChar; char_len = WideCharToMultiByte(CP_UTF8, 0, utf16_buffer, diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index cfbac52eb1d6f4..2a8adf6b262463 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4109,6 +4109,9 @@ #endif /* from winternl.h */ +#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32_) +#define __UNICODE_STRING_DEFINED +#endif typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index 42bde0bb96476d..2a699f46dcb0ff 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -142,11 +142,11 @@ static int maybe_run_test(int argc, char **argv) { if (strcmp(argv[1], "spawn_helper5") == 0) { const char out[] = "fourth stdio!\n"; notify_parent_process(); + { #ifdef _WIN32 - DWORD bytes; - WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL); + DWORD bytes; + WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL); #else - { ssize_t r; do @@ -154,8 +154,8 @@ static int maybe_run_test(int argc, char **argv) { while (r == -1 && errno == EINTR); fsync(3); - } #endif + } return 1; } diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index e3e91a7b69ca62..f60c23df3ebf1e 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -194,7 +194,7 @@ int process_wait(process_info_t *vec, int n, int timeout) { result = WaitForMultipleObjects(n, handles, TRUE, timeout_api); - if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n) { + if (result < WAIT_OBJECT_0 + n) { /* All processes are terminated. */ return 0; } @@ -268,7 +268,8 @@ int process_read_last_line(process_info_t *p, if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped)) return -1; - for (start = read - 1; start >= 0; start--) { + start = read; + while (start-- > 0) { if (buffer[start] == '\n' || buffer[start] == '\r') break; } @@ -308,7 +309,7 @@ void process_cleanup(process_info_t *p) { } -static int clear_line() { +static int clear_line(void) { HANDLE handle; CONSOLE_SCREEN_BUFFER_INFO info; COORD coord; diff --git a/deps/uv/test/runner-win.h b/deps/uv/test/runner-win.h index 8cc4c16eb22eac..975eed793104c2 100644 --- a/deps/uv/test/runner-win.h +++ b/deps/uv/test/runner-win.h @@ -20,7 +20,9 @@ */ /* Don't complain about write(), fileno() etc. being deprecated. */ +#ifdef _MSC_VER #pragma warning(disable : 4996) +#endif #include diff --git a/deps/uv/test/test-close-fd.c b/deps/uv/test/test-close-fd.c index 93a7bd7c021026..2ed9a10032dfe6 100644 --- a/deps/uv/test/test-close-fd.c +++ b/deps/uv/test/test-close-fd.c @@ -73,4 +73,8 @@ TEST_IMPL(close_fd) { return 0; } -#endif /* !defined(_WIN32) */ +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-condvar.c b/deps/uv/test/test-condvar.c index 50f3c047c00cd2..32abccc2e7602e 100644 --- a/deps/uv/test/test-condvar.c +++ b/deps/uv/test/test-condvar.c @@ -235,7 +235,7 @@ TEST_IMPL(condvar_5) { uint64_t elapsed; uint64_t timeout; - timeout = 100 * 1e6; /* 100 ms in ns */ + timeout = 100 * 1000 * 1000; /* 100 ms in ns */ /* Mostly irrelevant. We need cond and mutex initialized. */ worker_config_init(&wc, 0, NULL, NULL); diff --git a/deps/uv/test/test-emfile.c b/deps/uv/test/test-emfile.c index 8e44ac5c77877d..bc1fce5f5591f0 100644 --- a/deps/uv/test/test-emfile.c +++ b/deps/uv/test/test-emfile.c @@ -38,6 +38,11 @@ static uv_tcp_t client_handle; TEST_IMPL(emfile) { + struct sockaddr_in addr; + struct rlimit limits; + uv_connect_t connect_req; + uv_loop_t* loop; + int first_fd; #if defined(_AIX) || defined(__MVS__) /* On AIX, if a 'accept' call fails ECONNRESET is set on the socket * which causes uv__emfile_trick to not work as intended and this test @@ -45,11 +50,6 @@ TEST_IMPL(emfile) { */ RETURN_SKIP("uv__emfile_trick does not work on this OS"); #endif - struct sockaddr_in addr; - struct rlimit limits; - uv_connect_t connect_req; - uv_loop_t* loop; - int first_fd; /* Lower the file descriptor limit and use up all fds save one. */ limits.rlim_cur = limits.rlim_max = maxfd + 1; @@ -114,4 +114,8 @@ static void connect_cb(uv_connect_t* req, int status) { uv_close((uv_handle_t*) &client_handle, NULL); } -#endif /* !defined(_WIN32) */ +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-fork.c b/deps/uv/test/test-fork.c index f47ae3e656299e..9e4684f0e15376 100644 --- a/deps/uv/test/test-fork.c +++ b/deps/uv/test/test-fork.c @@ -676,5 +676,8 @@ TEST_IMPL(fork_threadpool_queue_work_simple) { } #endif /* !__MVS__ */ +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ #endif /* !_WIN32 */ diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 038d2dd6159245..5eed160de2e64b 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -154,7 +154,7 @@ int uv_test_getiovmax(void) { static unsigned REPARSE_TAG = 0x9913; static GUID REPARSE_GUID = { 0x1bf6205f, 0x46ae, 0x4527, - 0xb1, 0x0c, 0xc5, 0x09, 0xb7, 0x55, 0x22, 0x80 }; + { 0xb1, 0x0c, 0xc5, 0x09, 0xb7, 0x55, 0x22, 0x80 }}; #endif static void check_permission(const char* filename, unsigned int mode) { @@ -2331,9 +2331,6 @@ TEST_IMPL(fs_stat_root) { TEST_IMPL(fs_futime) { -#if defined(_AIX) && !defined(_AIX71) - RETURN_SKIP("futime is not implemented for AIX versions below 7.1"); -#else utime_check_t checkme; const char* path = "test_file"; double atime; @@ -2341,6 +2338,9 @@ TEST_IMPL(fs_futime) { uv_file file; uv_fs_t req; int r; +#if defined(_AIX) && !defined(_AIX71) + RETURN_SKIP("futime is not implemented for AIX versions below 7.1"); +#endif /* Setup. */ loop = uv_default_loop(); @@ -2402,7 +2402,6 @@ TEST_IMPL(fs_futime) { MAKE_VALGRIND_HAPPY(); return 0; -#endif } @@ -3601,6 +3600,53 @@ TEST_IMPL(fs_exclusive_sharing_mode) { } #endif +#ifdef _WIN32 +TEST_IMPL(fs_file_flag_no_buffering) { + int r; + + /* Setup. */ + unlink("test_file"); + + ASSERT(UV_FS_O_APPEND > 0); + ASSERT(UV_FS_O_CREAT > 0); + ASSERT(UV_FS_O_DIRECT > 0); + ASSERT(UV_FS_O_RDWR > 0); + + /* FILE_APPEND_DATA must be excluded from FILE_GENERIC_WRITE: */ + r = uv_fs_open(NULL, + &open_req1, + "test_file", + UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_DIRECT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive: */ + r = uv_fs_open(NULL, + &open_req2, + "test_file", + UV_FS_O_APPEND | UV_FS_O_DIRECT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r == UV_EINVAL); + ASSERT(open_req2.result == UV_EINVAL); + uv_fs_req_cleanup(&open_req2); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + #ifdef _WIN32 int call_icacls(const char* command, ...) { char icacls_command[1024]; diff --git a/deps/uv/test/test-ip4-addr.c b/deps/uv/test/test-ip4-addr.c index 3d6e0cf286ac90..c72f36a694455d 100644 --- a/deps/uv/test/test-ip4-addr.c +++ b/deps/uv/test/test-ip4-addr.c @@ -27,8 +27,13 @@ TEST_IMPL(ip4_addr) { - struct sockaddr_in addr; + char dst[16]; + + ASSERT(0 == uv_inet_ntop(AF_INET, "\xFF\xFF\xFF\xFF", dst, sizeof(dst))); + ASSERT(0 == strcmp(dst, "255.255.255.255")); + ASSERT(UV_ENOSPC == uv_inet_ntop(AF_INET, "\xFF\xFF\xFF\xFF", + dst, sizeof(dst) - 1)); ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr)); diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index 25570dcacde1e3..bbf33a4854ed23 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -83,7 +83,7 @@ TEST_IMPL(ip6_addr_link_local) { ASSERT(0 == r); #ifdef _WIN32 /* On Windows, the interface identifier is the numeric string of the index. */ - ASSERT(strtol(interface_id, NULL, 10) == iface_index); + ASSERT(strtoul(interface_id, NULL, 10) == iface_index); #else /* On Unix/Linux, the interface identifier is the interface device name. */ ASSERT(0 == strcmp(device_name, interface_id)); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 46db4b2710138f..cc37bc039b15ba 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -349,9 +349,11 @@ TEST_DECLARE (fs_null_req) TEST_DECLARE (fs_read_dir) #ifdef _WIN32 TEST_DECLARE (fs_exclusive_sharing_mode) +TEST_DECLARE (fs_file_flag_no_buffering) TEST_DECLARE (fs_open_readonly_acl) TEST_DECLARE (fs_fchmod_archive_readonly) #endif +TEST_DECLARE (strscpy) TEST_DECLARE (threadpool_queue_work_simple) TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) @@ -904,11 +906,13 @@ TASK_LIST_START TEST_ENTRY (fs_read_dir) #ifdef _WIN32 TEST_ENTRY (fs_exclusive_sharing_mode) + TEST_ENTRY (fs_file_flag_no_buffering) TEST_ENTRY (fs_open_readonly_acl) TEST_ENTRY (fs_fchmod_archive_readonly) #endif TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (open_osfhandle_valid_handle) + TEST_ENTRY (strscpy) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) TEST_ENTRY (threadpool_multiple_event_loops) diff --git a/deps/uv/test/test-pipe-close-stdout-read-stdin.c b/deps/uv/test/test-pipe-close-stdout-read-stdin.c index c8804b0e189249..126be2cc46f0e3 100644 --- a/deps/uv/test/test-pipe-close-stdout-read-stdin.c +++ b/deps/uv/test/test-pipe-close-stdout-read-stdin.c @@ -105,4 +105,8 @@ TEST_IMPL(pipe_close_stdout_read_stdin) { return 0; } +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + #endif /* ifndef _WIN32 */ diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index 4025fba540e61e..43ed119debfe69 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -49,7 +49,7 @@ TEST_IMPL(platform_output) { printf("uv_cwd: %s\n", buffer); err = uv_resident_set_memory(&rss); -#if defined(__CYGWIN__) || defined(__MSYS__) +#if defined(__MSYS__) ASSERT(err == UV_ENOSYS); #else ASSERT(err == 0); diff --git a/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c b/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c index 1dfc80e352b5cc..3393820fc40d77 100644 --- a/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c +++ b/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c @@ -49,7 +49,7 @@ static void poll_cb(uv_poll_t* h, int status, int events) { } -static void NO_INLINE close_socket_and_verify_stack() { +static void NO_INLINE close_socket_and_verify_stack(void) { const uint32_t MARKER = 0xDEADBEEF; const int VERIFY_AFTER = 10; /* ms */ int r; diff --git a/deps/uv/test/test-poll-oob.c b/deps/uv/test/test-poll-oob.c index 2a6da843c616ad..77ffe31e962f10 100644 --- a/deps/uv/test/test-poll-oob.c +++ b/deps/uv/test/test-poll-oob.c @@ -202,4 +202,9 @@ TEST_IMPL(poll_oob) { MAKE_VALGRIND_HAPPY(); return 0; } + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + #endif diff --git a/deps/uv/test/test-process-title-threadsafe.c b/deps/uv/test/test-process-title-threadsafe.c index c0dee48a79f22f..19098eda0c4019 100644 --- a/deps/uv/test/test-process-title-threadsafe.c +++ b/deps/uv/test/test-process-title-threadsafe.c @@ -70,7 +70,7 @@ TEST_IMPL(process_title_threadsafe) { #if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \ defined(__MVS__) RETURN_SKIP("uv_(get|set)_process_title is not implemented."); -#else +#endif ASSERT(0 == uv_set_process_title(titles[0])); ASSERT(0 == uv_thread_create(&getter_thread, getter_thread_body, NULL)); @@ -82,5 +82,4 @@ TEST_IMPL(process_title_threadsafe) { ASSERT(0 == uv_thread_join(&setter_threads[i])); return 0; -#endif } diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c index 886f83a7d30fe1..efd48142b707bf 100644 --- a/deps/uv/test/test-process-title.c +++ b/deps/uv/test/test-process-title.c @@ -62,7 +62,8 @@ static void uv_get_process_title_edge_cases(void) { TEST_IMPL(process_title) { #if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) RETURN_SKIP("uv_(get|set)_process_title is not implemented."); -#else +#endif + /* Check for format string vulnerabilities. */ set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); set_title("new title"); @@ -71,5 +72,4 @@ TEST_IMPL(process_title) { uv_get_process_title_edge_cases(); return 0; -#endif } diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c index 79242fc9fa99e7..4281d23d7223ab 100644 --- a/deps/uv/test/test-signal-multiple-loops.c +++ b/deps/uv/test/test-signal-multiple-loops.c @@ -295,4 +295,8 @@ TEST_IMPL(signal_multiple_loops) { return 0; } -#endif /* !_WIN32 */ +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 594a64c60b8d5a..05c76f61452400 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -49,7 +49,9 @@ static char exepath[1024]; static size_t exepath_size = 1024; static char* args[5]; static int no_term_signal; +#ifndef _WIN32 static int timer_counter; +#endif static uv_tcp_t tcp_server; #define OUTPUT_SIZE 1024 @@ -138,10 +140,12 @@ static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { } +#ifndef _WIN32 static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { uv_read_stop(tcp); on_read(tcp, nread, buf); } +#endif static void write_cb(uv_write_t* req, int status) { @@ -173,9 +177,11 @@ static void timer_cb(uv_timer_t* handle) { } +#ifndef _WIN32 static void timer_counter_cb(uv_timer_t* handle) { ++timer_counter; } +#endif TEST_IMPL(spawn_fails) { @@ -1198,7 +1204,7 @@ TEST_IMPL(argument_escaping) { int make_program_env(char** env_block, WCHAR** dst_ptr); TEST_IMPL(environment_creation) { - int i; + size_t i; char* environment[] = { "FOO=BAR", "SYSTEM=ROOT", /* substring of a supplied var name */ diff --git a/deps/uv/test/test-strscpy.c b/deps/uv/test/test-strscpy.c new file mode 100644 index 00000000000000..4e7db6ffec8ef2 --- /dev/null +++ b/deps/uv/test/test-strscpy.c @@ -0,0 +1,53 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include "uv.h" +#include "task.h" +#include + +#include "../src/strscpy.h" +#include "../src/strscpy.c" + +TEST_IMPL(strscpy) { + char d[4]; + + ASSERT(0 == uv__strscpy(d, "", 0)); + ASSERT(0 == uv__strscpy(d, "x", 0)); + + memset(d, 0, sizeof(d)); + ASSERT(1 == uv__strscpy(d, "x", sizeof(d))); + ASSERT(0 == memcmp(d, "x\0\0", sizeof(d))); + + memset(d, 0, sizeof(d)); + ASSERT(2 == uv__strscpy(d, "xy", sizeof(d))); + ASSERT(0 == memcmp(d, "xy\0", sizeof(d))); + + ASSERT(3 == uv__strscpy(d, "xyz", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + ASSERT(UV_E2BIG == uv__strscpy(d, "xyzz", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + ASSERT(UV_E2BIG == uv__strscpy(d, "xyzzy", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + return 0; +} diff --git a/deps/uv/test/test-tcp-close-accept.c b/deps/uv/test/test-tcp-close-accept.c index e4878398c8b98e..624262bcfe9000 100644 --- a/deps/uv/test/test-tcp-close-accept.c +++ b/deps/uv/test/test-tcp-close-accept.c @@ -191,4 +191,8 @@ TEST_IMPL(tcp_close_accept) { return 0; } -#endif /* !_WIN32 */ +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-tcp-oob.c b/deps/uv/test/test-tcp-oob.c index ca2361f9bb776d..53f8231e83e497 100644 --- a/deps/uv/test/test-tcp-oob.c +++ b/deps/uv/test/test-tcp-oob.c @@ -138,4 +138,9 @@ TEST_IMPL(tcp_oob) { MAKE_VALGRIND_HAPPY(); return 0; } -#endif + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-tcp-write-after-connect.c b/deps/uv/test/test-tcp-write-after-connect.c index aa03228f134c15..8198e7e184d5e4 100644 --- a/deps/uv/test/test-tcp-write-after-connect.c +++ b/deps/uv/test/test-tcp-write-after-connect.c @@ -65,4 +65,8 @@ TEST_IMPL(tcp_write_after_connect) { return 0; } -#endif +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c index 979a6ec38d7fcd..688711e5082116 100644 --- a/deps/uv/test/test-tty.c +++ b/deps/uv/test/test-tty.c @@ -315,10 +315,8 @@ TEST_IMPL(tty_raw_cancel) { int r; int ttyin_fd; uv_tty_t tty_in; - uv_loop_t* loop; HANDLE handle; - loop = uv_default_loop(); /* Make sure we have an FD that refers to a tty */ handle = CreateFileA("conin$", GENERIC_READ | GENERIC_WRITE, diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp index 098512208c3cf8..ae7dc0d628f6e4 100644 --- a/deps/uv/test/test.gyp +++ b/deps/uv/test/test.gyp @@ -34,6 +34,7 @@ 'test-fs.c', 'test-fs-copyfile.c', 'test-fs-event.c', + 'test-fs-poll.c', 'test-getters-setters.c', 'test-get-currentexe.c', 'test-get-memory.c', @@ -96,7 +97,7 @@ 'test-signal-multiple-loops.c', 'test-socket-buffer-size.c', 'test-spawn.c', - 'test-fs-poll.c', + 'test-strscpy.c', 'test-stdio-over-pipes.c', 'test-tcp-alloc-cb-fail.c', 'test-tcp-bind-error.c', diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 746d1ed5416322..0836dd27f2b72a 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -74,6 +74,8 @@ 'src/idna.h', 'src/inet.c', 'src/queue.h', + 'src/strscpy.c', + 'src/strscpy.h', 'src/threadpool.c', 'src/timer.c', 'src/uv-data-getter-setters.c',