diff --git a/.mailmap b/.mailmap index 127e1782b394a2..6d7e00af1a482f 100644 --- a/.mailmap +++ b/.mailmap @@ -270,7 +270,9 @@ Miguel Angel Asencio Hurtado maasencioh Mike Kaufman Minqi Pan P.S.V.R -Minwoo Jung JungMinu +Minwoo Jung JungMinu +Minwoo Jung +Minwoo Jung Miroslav Bajtoš Mitar Milutinovic Myles Borins diff --git a/.travis.yml b/.travis.yml index 93456573438b1c..8aa321ec1626d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,13 +6,10 @@ x-ccache-setup-steps: &ccache-setup-steps os: linux language: cpp -# Currently this file can only support one PYTHON_VERSION. -# To experiment with Python 3, comment out Python 2.7 and uncomment one of the Python 3 versions. env: global: - - PYTHON_VERSION="2.7.15" - # - PYTHON_VERSION="3.6.7" - # - PYTHON_VERSION="3.7.1" + - PYTHON_VERSION="3.7.1" + - PYTHON=python3 jobs: include: - stage: "Compile" diff --git a/BUILDING.md b/BUILDING.md index aadba46020012d..006c21521df1f5 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -498,9 +498,9 @@ $ backtrace * [Python 2.7](https://www.python.org/downloads/) * The "Desktop development with C++" workload from - [Visual Studio 2017](https://www.visualstudio.com/downloads/) or the - "Visual C++ build tools" workload from the - [Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017), + [Visual Studio 2017 or 2019](https://visualstudio.microsoft.com/downloads/) or + the "Visual C++ build tools" workload from the + [Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019), with the default optional components. * Basic Unix tools required for some tests, [Git for Windows](https://git-scm.com/download/win) includes Git Bash @@ -513,7 +513,8 @@ $ backtrace Optional requirements to build the MSI installer package: * The [WiX Toolset v3.11](https://wixtoolset.org/releases/) and the - [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension). + [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension) + or the [Wix Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension). Optional requirements for compiling for Windows 10 on ARM (ARM64): diff --git a/CHANGELOG.md b/CHANGELOG.md index b9aebbe7dc5602..fca5a1818eb8d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,8 @@ release. - 13.0.0
+13.0.1
+13.0.0
12.12.0
diff --git a/Makefile b/Makefile index 87afe29b46828f..8d4e6bbe6474b9 100644 --- a/Makefile +++ b/Makefile @@ -347,24 +347,6 @@ test-valgrind: all test-check-deopts: all $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --check-deopts parallel sequential -benchmark/napi/function_call/build/$(BUILDTYPE)/binding.node: \ - benchmark/napi/function_call/napi_binding.c \ - benchmark/napi/function_call/binding.cc \ - benchmark/napi/function_call/binding.gyp | all - $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \ - --python="$(PYTHON)" \ - --directory="$(shell pwd)/benchmark/napi/function_call" \ - --nodedir="$(shell pwd)" - -benchmark/napi/function_args/build/$(BUILDTYPE)/binding.node: \ - benchmark/napi/function_args/napi_binding.c \ - benchmark/napi/function_args/binding.cc \ - benchmark/napi/function_args/binding.gyp | all - $(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \ - --python="$(PYTHON)" \ - --directory="$(shell pwd)/benchmark/napi/function_args" \ - --nodedir="$(shell pwd)" - DOCBUILDSTAMP_PREREQS = tools/doc/addon-verify.js doc/api/addons.md ifeq ($(OSTYPE),aix) @@ -470,6 +452,17 @@ test/node-api/.buildstamp: $(ADDONS_PREREQS) \ # TODO(bnoordhuis) Force rebuild after gyp or node-gyp update. build-node-api-tests: | $(NODE_EXE) test/node-api/.buildstamp +BENCHMARK_NAPI_BINDING_GYPS := $(wildcard benchmark/napi/*/binding.gyp) + +BENCHMARK_NAPI_BINDING_SOURCES := \ + $(wildcard benchmark/napi/*/*.c) \ + $(wildcard benchmark/napi/*/*.cc) \ + $(wildcard benchmark/napi/*/*.h) + +benchmark/napi/.buildstamp: $(ADDONS_PREREQS) \ + $(BENCHMARK_NAPI_BINDING_GYPS) $(BENCHMARK_NAPI_BINDING_SOURCES) + @$(call run_build_addons,"$$PWD/benchmark/napi",$@) + .PHONY: clear-stalled clear-stalled: @echo "Clean up any leftover processes but don't error if found." @@ -599,11 +592,10 @@ test-hash-seed: all $(NODE) test/pummel/test-hash-seed.js .PHONY: test-doc -test-doc: doc-only ## Builds, lints, and verifies the docs. +test-doc: doc-only lint ## Builds, lints, and verifies the docs. @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ echo "Skipping test-doc (no crypto)"; \ else \ - $(MAKE) lint; \ $(PYTHON) tools/test.py $(PARALLEL_ARGS) doctool; \ fi @@ -1163,13 +1155,12 @@ bench: bench-addons-build # Build required addons for benchmark before running it. .PHONY: bench-addons-build -bench-addons-build: benchmark/napi/function_call/build/$(BUILDTYPE)/binding.node \ - benchmark/napi/function_args/build/$(BUILDTYPE)/binding.node +bench-addons-build: | $(NODE_EXE) benchmark/napi/.buildstamp .PHONY: bench-addons-clean bench-addons-clean: - $(RM) -r benchmark/napi/function_call/build - $(RM) -r benchmark/napi/function_args/build + $(RM) -r benchmark/napi/*/build + $(RM) benchmark/napi/.buildstamp .PHONY: lint-md-rollup lint-md-rollup: diff --git a/README.md b/README.md index 8bc15d76e1d10c..c46aac2a42cab4 100644 --- a/README.md +++ b/README.md @@ -345,7 +345,7 @@ For information about the governance of the Node.js project, see * [julianduque](https://github.com/julianduque) - **Julian Duque** <julianduquej@gmail.com> (he/him) * [JungMinu](https://github.com/JungMinu) - -**Minwoo Jung** <minwoo@nodesource.com> (he/him) +**Minwoo Jung** <nodecorelab@gmail.com> (he/him) * [kfarnung](https://github.com/kfarnung) - **Kyle Farnung** <kfarnung@microsoft.com> (he/him) * [kunalspathak](https://github.com/kunalspathak) - diff --git a/benchmark/napi/ref/.gitignore b/benchmark/napi/ref/.gitignore new file mode 100644 index 00000000000000..567609b1234a9b --- /dev/null +++ b/benchmark/napi/ref/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/configure.py b/configure.py index dd93d56e552526..bfc50d7fbde6e7 100755 --- a/configure.py +++ b/configure.py @@ -14,6 +14,7 @@ import bz2 from distutils.spawn import find_executable as which +from distutils.version import StrictVersion # If not run from node/, cd to node/. os.chdir(os.path.dirname(__file__) or '.') @@ -506,7 +507,7 @@ parser.add_option('--without-snapshot', action='store_true', - dest='without_snapshot', + dest='unused_without_snapshot', help=optparse.SUPPRESS_HELP) parser.add_option('--without-siphash', @@ -774,7 +775,8 @@ def check_compiler(o): if not ok: warn('failed to autodetect C++ compiler version (CXX=%s)' % CXX) elif clang_version < (8, 0, 0) if is_clang else gcc_version < (6, 3, 0): - warn('C++ compiler too old, need g++ 6.3.0 or clang++ 8.0.0 (CXX=%s)' % CXX) + warn('C++ compiler (CXX=%s, %s) too old, need g++ 6.3.0 or clang++ 8.0.0' % + (CXX, ".".join(map(str, clang_version if is_clang else gcc_version)))) ok, is_clang, clang_version, gcc_version = try_check_compiler(CC, 'c') if not ok: @@ -783,7 +785,8 @@ def check_compiler(o): # clang 3.2 is a little white lie because any clang version will probably # do for the C bits. However, we might as well encourage people to upgrade # to a version that is not completely ancient. - warn('C compiler too old, need gcc 4.2 or clang 3.2 (CC=%s)' % CC) + warn('C compiler (CC=%s, %s) too old, need gcc 4.2 or clang 3.2' % + (CC, ".".join(map(str, gcc_version)))) o['variables']['llvm_version'] = get_llvm_version(CC) if is_clang else '0.0' @@ -966,13 +969,13 @@ def configure_node(o): cross_compiling = (options.cross_compiling if options.cross_compiling is not None else target_arch != host_arch) - want_snapshots = not options.without_snapshot - o['variables']['want_separate_host_toolset'] = int( - cross_compiling and want_snapshots) + if options.unused_without_snapshot: + warn('building --without-snapshot is no longer possible') + + o['variables']['want_separate_host_toolset'] = int(cross_compiling) if not options.without_node_snapshot: - o['variables']['node_use_node_snapshot'] = b( - not cross_compiling and want_snapshots) + o['variables']['node_use_node_snapshot'] = b(not cross_compiling) else: o['variables']['node_use_node_snapshot'] = 'false' @@ -1176,7 +1179,6 @@ def configure_v8(o): o['variables']['v8_random_seed'] = 0 # Use a random seed for hash tables. o['variables']['v8_promise_internal_field_count'] = 1 # Add internal field to promises for async hooks. o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1 - o['variables']['v8_use_snapshot'] = 0 if options.without_snapshot else 1 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) @@ -1231,10 +1233,10 @@ def without_ssl_error(option): # supported asm compiler for AVX2. See https://github.com/openssl/openssl/ # blob/OpenSSL_1_1_0-stable/crypto/modes/asm/aesni-gcm-x86_64.pl#L52-L69 openssl110_asm_supported = \ - ('gas_version' in variables and float(variables['gas_version']) >= 2.23) or \ - ('xcode_version' in variables and float(variables['xcode_version']) >= 5.0) or \ - ('llvm_version' in variables and float(variables['llvm_version']) >= 3.3) or \ - ('nasm_version' in variables and float(variables['nasm_version']) >= 2.10) + ('gas_version' in variables and StrictVersion(variables['gas_version']) >= StrictVersion('2.23')) or \ + ('xcode_version' in variables and StrictVersion(variables['xcode_version']) >= StrictVersion('5.0')) or \ + ('llvm_version' in variables and StrictVersion(variables['llvm_version']) >= StrictVersion('3.3')) or \ + ('nasm_version' in variables and StrictVersion(variables['nasm_version']) >= StrictVersion('2.10')) if is_x86 and not openssl110_asm_supported: error('''Did not find a new enough assembler, install one or build with diff --git a/deps/npm/lib/utils/unsupported.js b/deps/npm/lib/utils/unsupported.js index 20cee157ee4038..aaae8c44266534 100644 --- a/deps/npm/lib/utils/unsupported.js +++ b/deps/npm/lib/utils/unsupported.js @@ -6,7 +6,8 @@ var supportedNode = [ {ver: '9', min: '9.0.0'}, {ver: '10', min: '10.0.0'}, {ver: '11', min: '11.0.0'}, - {ver: '12', min: '12.0.0'} + {ver: '12', min: '12.0.0'}, + {ver: '13', min: '13.0.0'} ] var knownBroken = '<6.0.0' diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 8c3d342d33e6f8..408cfd6541a339 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -403,3 +403,11 @@ Vladimir Karnushin MaYuming Eneas U de Queiroz Daniel Hahler +Yang Yu +David Carlier +Calvin Hill +Isabella Muerte <63051+slurps-mad-rips@users.noreply.github.com> +Ouyang Yadong +ZYSzys +Carl Lei +Stefan Bender diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index 6f18f3397d0129..7da5e688166c04 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -1,6 +1,15 @@ # TODO: determine CMAKE_SYSTEM_NAME on OS/390. Currently assumes "OS/390". -cmake_minimum_required(VERSION 2.8.12) -project(libuv) +cmake_minimum_required(VERSION 3.4) +project(libuv LANGUAGES C) + +include(CMakePackageConfigHelpers) +include(CMakeDependentOption) +include(GNUInstallDirs) +include(CTest) + +cmake_dependent_option(LIBUV_BUILD_TESTS + "Build the unit tests when BUILD_TESTING is enabled and we are the root project" ON + "BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) if(MSVC) list(APPEND uv_cflags /W4) @@ -14,6 +23,7 @@ set(uv_sources src/fs-poll.c src/idna.c src/inet.c + src/random.c src/strscpy.c src/threadpool.c src/timer.c @@ -72,7 +82,6 @@ set(uv_test_sources test/test-idna.c test/test-ip4-addr.c test/test-ip6-addr.c - test/test-ip6-addr.c test/test-ipc-heavy-traffic-deadlock-bug.c test/test-ipc-send-recv.c test/test-ipc.c @@ -108,6 +117,7 @@ set(uv_test_sources test/test-process-title-threadsafe.c test/test-process-title.c test/test-queue-foreach-delete.c + test/test-random.c test/test-ref.c test/test-run-nowait.c test/test-run-once.c @@ -236,6 +246,7 @@ else() src/unix/pipe.c src/unix/poll.c src/unix/process.c + src/unix/random-devurandom.c src/unix/signal.c src/unix/stream.c src/unix/tcp.c @@ -284,6 +295,14 @@ if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") list(APPEND uv_sources src/unix/bsd-ifaddrs.c src/unix/kqueue.c) endif() +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND uv_sources src/unix/random-getrandom.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/random-getentropy.c) +endif() + if(APPLE) list(APPEND uv_defines _DARWIN_UNLIMITED_SELECT=1 _DARWIN_USE_64_BIT_INODE=1) list(APPEND uv_sources @@ -300,6 +319,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-inotify.c src/unix/linux-syscalls.c src/unix/procfs-exepath.c + src/unix/random-getrandom.c + src/unix/random-sysctl.c src/unix/sysinfo-loadavg.c) endif() @@ -356,11 +377,7 @@ target_compile_options(uv_a PRIVATE ${uv_cflags}) target_include_directories(uv_a PUBLIC include PRIVATE src) target_link_libraries(uv_a ${uv_libraries}) -option(libuv_buildtests "Build the unit tests when BUILD_TESTING is enabled." ON) - -include(CTest) -if(BUILD_TESTING AND libuv_buildtests) - enable_testing() +if(LIBUV_BUILD_TESTS) add_executable(uv_run_tests ${uv_test_sources}) target_compile_definitions(uv_run_tests PRIVATE ${uv_defines} USING_UV_SHARED=1) @@ -380,7 +397,6 @@ endif() if(UNIX) # Now for some gibbering horrors from beyond the stars... - include(GNUInstallDirs) foreach(x ${uv_libraries}) set(LIBS "${LIBS} -l${x}") endforeach(x) @@ -402,3 +418,11 @@ if(UNIX) install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() + +if(WIN32) + install(DIRECTORY include/ DESTINATION include) + install(FILES LICENSE DESTINATION .) + install(TARGETS uv uv_a + RUNTIME DESTINATION lib/$ + ARCHIVE DESTINATION lib/$) +endif() diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 093579de8e4985..cd4451ae69c0c1 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,83 @@ +2019.10.20, Version 1.33.1 (Stable), 07ad32138f4d2285ba2226b5e20462b27b091a59 + +Changes since version 1.33.0: + +* linux: fix arm64 SYS__sysctl build breakage (Ben Noordhuis) + + +2019.10.17, Version 1.33.0 (Stable), e56e42e9310e4437e1886dbd6771792c14c0a5f3 + +Changes since version 1.32.0: + +* Revert "linux: drop code path for epoll_pwait-less kernels" (Yang Yu) + +* build: fix build error with __ANDROID_API__ < 21 (Yang Yu) + +* win: fix reading hidden env vars (Anna Henningsen) + +* unix,win: add uv_random() (Ben Noordhuis) + +* win: simplify mkdtemp (Saúl Ibarra Corretgé) + +* docs: fix literal-includes in User Guide (Nhan Khong) + +* win, tty: fix problem of receiving unexpected SIGWINCH (erw7) + +* unix: fix {Net,Open}BSD build (David Carlier) + +* win,mingw: Fix undefined MCAST_* constants (Crunkle) + +* build: Add link for test/fixtures/lorem_ipsum.txt (Andrew Paprocki) + +* fs: use statvfs in uv__fs_statfs() for Haiku (Calvin Hill) + +* fsevents: stop using fsevents to watch files (Jameson Nash) + +* fsevents: regression in watching / (Jameson Nash) + +* build,cmake: don't try to detect a C++ compiler (Isabella Muerte) + +* build: fix build warning on cygwin (MaYuming) + +* unix: set sin_len and sin6_len (Ouyang Yadong) + +* test: fix order of operations in test (cjihrig) + +* doc: improve uv_fs_readdir() cleanup docs (cjihrig) + +* build: remove duplicated test in build files (ZYSzys) + +* android: enable getentropy on Android >= 28 (David Carlier) + +* android: fix build (David Carlier) + +* darwin: speed up uv_set_process_title() (Ben Noordhuis) + +* darwin: assume pthread_setname_np() is available (Ben Noordhuis) + +* unix,udp: ensure addr is non-null (Jameson Nash) + +* win,tty: add uv_tty_{get,set}_vterm_state (erw7) + +* win: fix uv_statfs_t leak in uv_fs_statfs() (Ryan Liptak) + +* build: install files on windows via cmake (Carl Lei) + +* darwin,test: include AvailabilityMacros.h (Saúl Ibarra Corretgé) + +* darwin,test: update loop time after sleeping (Saúl Ibarra Corretgé) + +* doc: remove old FreeBSD 9 related note (Saúl Ibarra Corretgé) + +* doc: improve uv_{send,recv}_buffer_size() docs (Ryan Liptak) + +* build: move -Wno-long-long check to configure time (Ben Noordhuis) + +* unix: update uv_fs_copyfile() fallback logic (Stefan Bender) + +* win: cast setsockopt struct to const char* (Shelley Vohr) + + 2019.09.10, Version 1.32.0 (Stable), 697bea87b3a0b0e9b4e5ff86b39d1dedb70ee46d Changes since version 1.31.0: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 099b0efb084343..ce4ca274b217ee 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -35,6 +35,7 @@ libuv_la_SOURCES = src/fs-poll.c \ src/idna.h \ src/inet.c \ src/queue.h \ + src/random.c \ src/strscpy.c \ src/strscpy.h \ src/threadpool.c \ @@ -105,6 +106,7 @@ libuv_la_SOURCES += src/unix/async.c \ src/unix/pipe.c \ src/unix/poll.c \ src/unix/process.c \ + src/unix/random-devurandom.c \ src/unix/signal.c \ src/unix/spinlock.h \ src/unix/stream.c \ @@ -138,11 +140,7 @@ EXTRA_DIST = test/fixtures/empty_file \ TESTS = test/run-tests check_PROGRAMS = test/run-tests -if OS390 test_run_tests_CFLAGS = -else -test_run_tests_CFLAGS = -Wno-long-long -endif if SUNOS # Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers @@ -240,6 +238,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-process-title.c \ test/test-process-title-threadsafe.c \ test/test-queue-foreach-delete.c \ + test/test-random.c \ test/test-ref.c \ test/test-run-nowait.c \ test/test-run-once.c \ @@ -414,7 +413,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ - src/unix/proctitle.c + src/unix/proctitle.c \ + src/unix/random-getentropy.c test_run_tests_LDFLAGS += -lutil endif @@ -434,7 +434,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/bsd-proctitle.c \ src/unix/freebsd.c \ src/unix/kqueue.c \ - src/unix/posix-hrtime.c + src/unix/posix-hrtime.c \ + src/unix/random-getrandom.c test_run_tests_LDFLAGS += -lutil endif @@ -465,6 +466,8 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/linux-syscalls.h \ src/unix/procfs-exepath.c \ src/unix/proctitle.c \ + src/unix/random-getrandom.c \ + src/unix/random-sysctl.c \ src/unix/sysinfo-loadavg.c test_run_tests_LDFLAGS += -lutil endif @@ -498,7 +501,8 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/bsd-proctitle.c \ src/unix/kqueue.c \ src/unix/openbsd.c \ - src/unix/posix-hrtime.c + src/unix/posix-hrtime.c \ + src/unix/random-getentropy.c test_run_tests_LDFLAGS += -lutil endif diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index 077191086ce524..29e4844ff323d3 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -5,7 +5,7 @@ | GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | | Windows | Tier 1 | >= Windows 7 | MSVC 2008 and later are supported | -| FreeBSD | Tier 1 | >= 9 (see note) | | +| FreeBSD | Tier 1 | >= 10 | | | AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix | | z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos | | Linux with musl | Tier 2 | musl >= 1.0 | | @@ -16,11 +16,6 @@ | SunOS | Tier 3 | Solaris 121 and later | | | Other | Tier 3 | N/A | | -#### Note on FreeBSD 9 - -While FreeBSD is supported as Tier 1, FreeBSD 9 will get Tier 2 support until -it reaches end of life, in December 2016. - ## Support types * **Tier 1**: Officially supported and tested with CI. Any contributed patch diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index b503e538298dd9..07ad0cde81a656 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.32.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.33.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]) @@ -32,6 +32,7 @@ CC_CHECK_CFLAGS_APPEND([-g]) CC_CHECK_CFLAGS_APPEND([-std=gnu89]) CC_CHECK_CFLAGS_APPEND([-Wall]) CC_CHECK_CFLAGS_APPEND([-Wextra]) +CC_CHECK_CFLAGS_APPEND([-Wno-long-long]) CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes]) # AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. @@ -80,4 +81,5 @@ AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CONFIG_FILES([Makefile libuv.pc]) AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file]) AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node]) +AC_CONFIG_LINKS([test/fixtures/lorem_ipsum.txt:test/fixtures/lorem_ipsum.txt]) AC_OUTPUT diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index aabe49b3f3a981..dc16ff08e65a93 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -295,7 +295,8 @@ API .. note:: On success this function allocates memory that must be freed using - `uv_fs_req_cleanup()`. + `uv_fs_req_cleanup()`. `uv_fs_req_cleanup()` must be called before + closing the directory with `uv_fs_closedir()`. .. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) .. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) @@ -358,10 +359,13 @@ API is to overwrite the destination if it exists. - `UV_FS_COPYFILE_FICLONE`: If present, `uv_fs_copyfile()` will attempt to create a copy-on-write reflink. If the underlying platform does not - support copy-on-write, then a fallback copy mechanism is used. + support copy-on-write, or an error occurs while attempting to use + copy-on-write, a fallback copy mechanism based on + :c:func:`uv_fs_sendfile()` is used. - `UV_FS_COPYFILE_FICLONE_FORCE`: If present, `uv_fs_copyfile()` will attempt to create a copy-on-write reflink. If the underlying platform does - not support copy-on-write, then an error is returned. + not support copy-on-write, or an error occurs while attempting to use + copy-on-write, then an error is returned. .. warning:: If the destination path is created, but an error occurs while copying @@ -374,6 +378,10 @@ API .. versionchanged:: 1.20.0 `UV_FS_COPYFILE_FICLONE` and `UV_FS_COPYFILE_FICLONE_FORCE` are supported. + .. versionchanged:: 1.33.0 If an error occurs while using + `UV_FS_COPYFILE_FICLONE_FORCE`, that error is returned. Previously, + all errors were mapped to `UV_ENOTSUP`. + .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) Limited equivalent to :man:`sendfile(2)`. diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index 0a25bfa8b27dd1..943c51d94ba6c4 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -190,8 +190,11 @@ just for some handle types. Gets or sets the size of the send buffer that the operating system uses for the socket. - If `*value` == 0, it will return the current send buffer size, - otherwise it will use `*value` to set the new send buffer size. + If `*value` == 0, then it will set `*value` to the current send buffer size. + If `*value` > 0 then it will use `*value` to set the new send buffer size. + + On success, zero is returned. On error, a negative result is + returned. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. @@ -204,8 +207,11 @@ just for some handle types. Gets or sets the size of the receive buffer that the operating system uses for the socket. - If `*value` == 0, it will return the current receive buffer size, - otherwise it will use `*value` to set the new receive buffer size. + If `*value` == 0, then it will set `*value` to the current receive buffer size. + If `*value` > 0 then it will use `*value` to set the new receive buffer size. + + On success, zero is returned. On error, a negative result is + returned. This function works for TCP, pipe and UDP handles on Unix and for TCP and UDP handles on Windows. diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 3ecfce486c4da2..8e167e3ec4ec1d 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -46,6 +46,12 @@ Data types Replacement function for :man:`free(3)`. See :c:func:`uv_replace_allocator`. +.. c:type:: void (*uv_random_cb)(uv_random_t* req, int status, void* buf, size_t buflen) + + Callback passed to :c:func:`uv_random`. `status` is non-zero in case of + error. The `buf` pointer is the same pointer that was passed to + :c:func:`uv_random`. + .. c:type:: uv_file Cross platform representation of a file handle. @@ -191,6 +197,9 @@ Data types char* value; } uv_env_item_t; +.. c:type:: uv_random_t + + Random data request type. API --- @@ -648,3 +657,39 @@ API argument to `gettimeofday()` is not supported, as it is considered obsolete. .. versionadded:: 1.28.0 + +.. c:function:: int uv_random(uv_loop_t* loop, uv_random_t* req, void* buf, size_t buflen, unsigned int flags, uv_random_cb cb) + + Fill `buf` with exactly `buflen` cryptographically strong random bytes + acquired from the system CSPRNG. `flags` is reserved for future extension + and must currently be 0. + + Short reads are not possible. When less than `buflen` random bytes are + available, a non-zero error value is returned or passed to the callback. + + The synchronous version may block indefinitely when not enough entropy + is available. The asynchronous version may not ever finish when the system + is low on entropy. + + Sources of entropy: + + - Windows: `RtlGenRandom _`. + - Linux, Android: :man:`getrandom(2)` if available, or :man:`urandom(4)` + after reading from `/dev/random` once, or the `KERN_RANDOM` + :man:`sysctl(2)`. + - FreeBSD: `getrandom(2) _`, + or `/dev/urandom` after reading from `/dev/random` once. + - macOS, OpenBSD: `getentropy(2) _` + if available, or `/dev/urandom` after reading from `/dev/random` once. + - AIX: `/dev/random`. + - IBM i: `/dev/urandom`. + - Other UNIX: `/dev/urandom` after reading from `/dev/random` once. + + :returns: 0 on success, or an error code < 0 on failure. The contents of + `buf` is undefined after an error. + + .. note:: + When using the synchronous version, both `loop` and `req` parameters + are not used and can be set to `NULL`. + + .. versionadded:: 1.33.0 diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst index 9889a0a0b6465b..ad379dab0dd001 100644 --- a/deps/uv/docs/src/tty.rst +++ b/deps/uv/docs/src/tty.rst @@ -33,6 +33,23 @@ Data types UV_TTY_MODE_IO } uv_tty_mode_t; +.. c:type:: uv_tty_vtermstate_t + Console virtual terminal mode type: + + :: + + typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process virtual terminal sequences. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED + } uv_tty_vtermstate_t + Public members @@ -98,3 +115,25 @@ API Gets the current Window size. On success it returns 0. .. seealso:: The :c:type:`uv_stream_t` API functions also apply. + +.. c:function:: void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) + + Controls whether console virtual terminal sequences are processed by libuv + or console. + Useful in particular for enabling ConEmu support of ANSI X3.64 and Xterm + 256 colors. Otherwise Windows10 consoles are usually detected automatically. + + This function is only meaningful on Windows systems. On Unix it is silently + ignored. + + .. versionadded:: 1.33.0 + +.. c:function:: int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) + + Get the current state of whether console virtual terminal sequences are + handled by libuv or the console. + + This function is not implemented on Unix, where it returns ``UV_ENOTSUP``. + + .. versionadded:: 1.33.0 + diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index ee45bcaefce1d3..0e8132e4384be0 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -177,6 +177,7 @@ extern "C" { XX(WORK, work) \ XX(GETADDRINFO, getaddrinfo) \ XX(GETNAMEINFO, getnameinfo) \ + XX(RANDOM, random) \ typedef enum { #define XX(code, _) UV_ ## code = UV__ ## code, @@ -234,6 +235,7 @@ typedef struct uv_connect_s uv_connect_t; typedef struct uv_udp_send_s uv_udp_send_t; typedef struct uv_fs_s uv_fs_t; typedef struct uv_work_s uv_work_t; +typedef struct uv_random_s uv_random_t; /* None of the above. */ typedef struct uv_env_item_s uv_env_item_t; @@ -330,6 +332,10 @@ typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service); +typedef void (*uv_random_cb)(uv_random_t* req, + int status, + void* buf, + size_t buflen); typedef struct { long tv_sec; @@ -700,10 +706,25 @@ typedef enum { UV_TTY_MODE_IO } uv_tty_mode_t; +typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process the virtual terminal sequence. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED +} uv_tty_vtermstate_t; + + UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); UV_EXTERN int uv_tty_reset_mode(void); UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); +UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); #ifdef __cplusplus extern "C++" { @@ -1574,6 +1595,26 @@ UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); + +struct uv_random_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* private */ + int status; + void* buf; + size_t buflen; + uv_random_cb cb; + struct uv__work work_req; +}; + +UV_EXTERN int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, /* For future extension; must be 0. */ + uv_random_cb cb); + #if defined(IF_NAMESIZE) # define UV_IF_NAMESIZE (IF_NAMESIZE + 1) #elif defined(IFNAMSIZ) diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index 928647b8200502..ca94be6dd4fba6 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 32 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 33 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/src/random.c b/deps/uv/src/random.c new file mode 100644 index 00000000000000..8c4fe32013dc9a --- /dev/null +++ b/deps/uv/src/random.c @@ -0,0 +1,121 @@ +/* Copyright libuv 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 "uv-common.h" + +#ifdef _WIN32 +# include "win/internal.h" +#else +# include "unix/internal.h" +#endif + +static int uv__random(void* buf, size_t buflen) { + int rc; + +#if defined(__PASE__) + rc = uv__random_readpath("/dev/urandom", buf, buflen); +#elif defined(_AIX) + rc = uv__random_readpath("/dev/random", buf, buflen); +#elif defined(__APPLE__) || defined(__OpenBSD__) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) + rc = uv__random_getentropy(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +#elif defined(__FreeBSD__) || defined(__linux__) + rc = uv__random_getrandom(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +# if defined(__linux__) + switch (rc) { + case UV_EACCES: + case UV_EIO: + case UV_ELOOP: + case UV_EMFILE: + case UV_ENFILE: + case UV_ENOENT: + case UV_EPERM: + rc = uv__random_sysctl(buf, buflen); + break; + } +# endif +#elif defined(_WIN32) + uv__once_init(); + rc = uv__random_rtlgenrandom(buf, buflen); +#else + rc = uv__random_devurandom(buf, buflen); +#endif + + return rc; +} + + +static void uv__random_work(struct uv__work* w) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + req->status = uv__random(req->buf, req->buflen); +} + + +static void uv__random_done(struct uv__work* w, int status) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + uv__req_unregister(req->loop, req); + + if (status == 0) + status = req->status; + + req->cb(req, status, req->buf, req->buflen); +} + + +int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, + uv_random_cb cb) { + if (buflen > 0x7FFFFFFFu) + return UV_E2BIG; + + if (flags != 0) + return UV_EINVAL; + + if (cb == NULL) + return uv__random(buf, buflen); + + uv__req_init(loop, req, UV_RANDOM); + req->loop = loop; + req->status = 0; + req->cb = cb; + req->buf = buf; + req->buflen = buflen; + + uv__work_submit(loop, + &req->work_req, + UV__WORK_CPU, + uv__random_work, + uv__random_done); + + return 0; +} diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 7aa575508fa8c4..a8f433f0510800 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -372,6 +372,10 @@ int uv_cancel(uv_req_t* req) { loop = ((uv_getnameinfo_t*) req)->loop; wreq = &((uv_getnameinfo_t*) req)->work_req; break; + case UV_RANDOM: + loop = ((uv_random_t*) req)->loop; + wreq = &((uv_random_t*) req)->work_req; + break; case UV_WORK: loop = ((uv_work_t*) req)->loop; wreq = &((uv_work_t*) req)->work_req; diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c index 99fb25a43b4279..7d48c6af57ca46 100644 --- a/deps/uv/src/unix/android-ifaddrs.c +++ b/deps/uv/src/unix/android-ifaddrs.c @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include typedef struct NetlinkList { @@ -475,6 +476,7 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); l_addedNetmask = 1; } + break; case IFA_BROADCAST: l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); break; diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c index 0d7bbe662a5c53..a3385af17c889f 100644 --- a/deps/uv/src/unix/bsd-ifaddrs.c +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -69,7 +69,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifaddrs* addrs; struct ifaddrs* ent; uv_interface_address_t* address; +#if !(defined(__CYGWIN__) || defined(__MSYS__)) int i; +#endif *count = 0; *addresses = NULL; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 366c43c2ab0843..ffce948c957403 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -66,7 +66,8 @@ extern char** environ; #if defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || \ + defined(__OpenBSD__) # include # include # include @@ -76,7 +77,8 @@ extern char** environ; # if defined(__NetBSD__) # define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d)) # endif -# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__) +# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \ + defined(__NetBSD__) || defined(__OpenBSD__) # define UV__SOCK_NONBLOCK SOCK_NONBLOCK # define UV__SOCK_CLOEXEC SOCK_CLOEXEC # endif diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c index dabde2239ccab3..eced23c2da7ccf 100644 --- a/deps/uv/src/unix/darwin-proctitle.c +++ b/deps/uv/src/unix/darwin-proctitle.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -33,61 +34,52 @@ # include #endif +#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) -static int uv__pthread_setname_np(const char* name) { - int (*dynamic_pthread_setname_np)(const char* name); - char namebuf[64]; /* MAXTHREADNAMESIZE */ - int err; - - /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */ - *(void **)(&dynamic_pthread_setname_np) = - dlsym(RTLD_DEFAULT, "pthread_setname_np"); - - if (dynamic_pthread_setname_np == NULL) - return UV_ENOSYS; - - strncpy(namebuf, name, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; - err = dynamic_pthread_setname_np(namebuf); - if (err) - return UV__ERR(err); +#if !TARGET_OS_IPHONE +static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, + const char*, + CFStringEncoding); +static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); +static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); +static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); +static CFTypeRef (*pLSGetCurrentApplicationASN)(void); +static OSStatus (*pLSSetApplicationInformationItem)(int, + CFTypeRef, + CFStringRef, + CFStringRef, + CFDictionaryRef*); +static void* application_services_handle; +static void* core_foundation_handle; +static CFBundleRef launch_services_bundle; +static CFStringRef* display_name_key; +static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); +static CFBundleRef (*pCFBundleGetMainBundle)(void); +static CFBundleRef hi_services_bundle; +static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); +static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, + void*); + + +UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) { + if (core_foundation_handle != NULL) { + dlclose(core_foundation_handle); + core_foundation_handle = NULL; + } - return 0; + if (application_services_handle != NULL) { + dlclose(application_services_handle); + application_services_handle = NULL; + } } +#endif /* !TARGET_OS_IPHONE */ -int uv__set_process_title(const char* title) { -#if TARGET_OS_IPHONE - return uv__pthread_setname_np(title); -#else - CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, - const char*, - CFStringEncoding); - CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); - void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); - void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); - CFTypeRef (*pLSGetCurrentApplicationASN)(void); - OSStatus (*pLSSetApplicationInformationItem)(int, - CFTypeRef, - CFStringRef, - CFStringRef, - CFDictionaryRef*); - void* application_services_handle; - void* core_foundation_handle; - CFBundleRef launch_services_bundle; - CFStringRef* display_name_key; - CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); - CFBundleRef (*pCFBundleGetMainBundle)(void); - CFBundleRef hi_services_bundle; +void uv__set_process_title_platform_init(void) { +#if !TARGET_OS_IPHONE OSStatus (*pSetApplicationIsDaemon)(int); - CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); - void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, - void*); - CFTypeRef asn; - int err; - err = UV_ENOENT; application_services_handle = dlopen("/System/Library/Frameworks/" "ApplicationServices.framework/" "Versions/A/ApplicationServices", @@ -116,8 +108,6 @@ int uv__set_process_title(const char* title) { goto out; } -#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) - launch_services_bundle = pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices")); @@ -148,13 +138,14 @@ int uv__set_process_title(const char* title) { "CFBundleGetInfoDictionary"); *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle, "CFBundleGetMainBundle"); + if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) goto out; /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */ hi_services_bundle = pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices")); - err = UV_ENOENT; + if (hi_services_bundle == NULL) goto out; @@ -168,42 +159,38 @@ int uv__set_process_title(const char* title) { pCFBundleGetFunctionPointerForName( launch_services_bundle, S("_LSSetApplicationLaunchServicesServerConnectionStatus")); + if (pSetApplicationIsDaemon == NULL || pLSApplicationCheckIn == NULL || pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) { goto out; } - if (pSetApplicationIsDaemon(1) != noErr) - goto out; + /* Prevent crash when LaunchServices cannot be connected to. */ + pSetApplicationIsDaemon(1); + return; - pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); +out: + uv__set_process_title_platform_fini(); +#endif /* !TARGET_OS_IPHONE */ +} - /* Check into process manager?! */ - pLSApplicationCheckIn(-2, - pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); - asn = pLSGetCurrentApplicationASN(); +void uv__set_process_title(const char* title) { + char namebuf[64 /* MAXTHREADNAMESIZE */]; - err = UV_EINVAL; - if (pLSSetApplicationInformationItem(-2, /* Magic value. */ - asn, - *display_name_key, - S(title), - NULL) != noErr) { - goto out; +#if !TARGET_OS_IPHONE + if (core_foundation_handle != NULL) { + CFTypeRef asn; + pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); + pLSApplicationCheckIn(/* Magic value */ -2, + pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); + asn = pLSGetCurrentApplicationASN(); + pLSSetApplicationInformationItem(/* Magic value */ -2, asn, + *display_name_key, S(title), NULL); } - - uv__pthread_setname_np(title); /* Don't care if it fails. */ - err = 0; - -out: - if (core_foundation_handle != NULL) - dlclose(core_foundation_handle); - - if (application_services_handle != NULL) - dlclose(application_services_handle); - - return err; #endif /* !TARGET_OS_IPHONE */ + + uv__strscpy(namebuf, title, sizeof(namebuf)); + pthread_setname_np(namebuf); } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index fd3dd4c287e9ba..b37cfbbc7a04ee 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -78,7 +78,7 @@ defined(__NetBSD__) # include # include -#elif defined(__sun) || defined(__MVS__) +#elif defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) # include #else # include @@ -216,7 +216,11 @@ static ssize_t uv__fs_futime(uv_fs_t* req) { ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000; ts[1].tv_sec = req->mtime; ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000; +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + return utimensat(req->file, NULL, ts, 0); +#else return futimens(req->file, ts); +#endif #elif defined(__APPLE__) \ || defined(__DragonFly__) \ || defined(__FreeBSD__) \ @@ -528,7 +532,7 @@ static int uv__fs_closedir(uv_fs_t* req) { static int uv__fs_statfs(uv_fs_t* req) { uv_statfs_t* stat_fs; -#if defined(__sun) || defined(__MVS__) +#if defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) struct statvfs buf; if (0 != statvfs(req->path, &buf)) @@ -545,7 +549,7 @@ static int uv__fs_statfs(uv_fs_t* req) { return -1; } -#if defined(__sun) || defined(__MVS__) +#if defined(__sun) || defined(__MVS__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) stat_fs->f_type = 0; /* f_type is not supported. */ #else stat_fs->f_type = buf.f_type; @@ -1051,18 +1055,14 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { #ifdef FICLONE if (req->flags & UV_FS_COPYFILE_FICLONE || req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { - if (ioctl(dstfd, FICLONE, srcfd) == -1) { - /* If an error occurred that the sendfile fallback also won't handle, or - this is a force clone then exit. Otherwise, fall through to try using - sendfile(). */ - if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) { - err = UV__ERR(errno); - goto out; - } else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { - err = UV_ENOTSUP; - goto out; - } - } else { + if (ioctl(dstfd, FICLONE, srcfd) == 0) { + /* ioctl() with FICLONE succeeded. */ + goto out; + } + /* If an error occurred and force was set, return the error to the caller; + * fall back to sendfile() when force was not set. */ + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = UV__ERR(errno); goto out; } } diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index ddacda31fef87e..deeaa63d4730de 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -263,10 +263,12 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, if (len < handle->realpath_len) continue; + /* Make sure that realpath actually named a directory, + * (unless watching root, which alone keeps a trailing slash on the realpath) + * or that we matched the whole string */ if (handle->realpath_len != len && + handle->realpath_len > 1 && path[handle->realpath_len] != '/') - /* Make sure that realpath actually named a directory, - * or that we matched the whole string */ continue; if (memcmp(path, handle->realpath, handle->realpath_len) != 0) diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 260616474ec151..47f220000dcd73 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -270,6 +270,12 @@ uv_handle_type uv__handle_type(int fd); FILE* uv__open_file(const char* path); int uv__getpwuid_r(uv_passwd_t* pwd); +/* random */ +int uv__random_devurandom(void* buf, size_t buflen); +int uv__random_getrandom(void* buf, size_t buflen); +int uv__random_getentropy(void* buf, size_t buflen); +int uv__random_readpath(const char* path, void* buf, size_t buflen); +int uv__random_sysctl(void* buf, size_t buflen); #if defined(__APPLE__) int uv___stream_fd(const uv_stream_t* handle); diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index c04e7a485cf992..ad09f4031318ca 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -454,10 +454,26 @@ int uv_fs_event_start(uv_fs_event_t* handle, const char* path, unsigned int flags) { int fd; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + struct stat statbuf; +#endif if (uv__is_active(handle)) return UV_EINVAL; + handle->cb = cb; + handle->path = uv__strdup(path); + if (handle->path == NULL) + return UV_ENOMEM; + + /* TODO open asynchronously - but how do we report back errors? */ + fd = open(handle->path, O_RDONLY); + if (fd == -1) { + uv__free(handle->path); + handle->path = NULL; + return UV__ERR(errno); + } + #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 /* Nullify field to perform checks later */ handle->cf_cb = NULL; @@ -465,14 +481,17 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->realpath_len = 0; handle->cf_flags = flags; + if (fstat(fd, &statbuf)) + goto fallback; + /* FSEvents works only with directories */ + if (!(statbuf.st_mode & S_IFDIR)) + goto fallback; + if (!uv__has_forked_with_cfrunloop) { int r; - /* The fallback fd is not used */ + /* The fallback fd is no longer needed */ + uv__close_nocheckstdio(fd); handle->event_watcher.fd = -1; - handle->path = uv__strdup(path); - if (handle->path == NULL) - return UV_ENOMEM; - handle->cb = cb; r = uv__fsevents_init(handle); if (r == 0) { uv__handle_start(handle); @@ -482,20 +501,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, } return r; } +fallback: #endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ - /* TODO open asynchronously - but how do we report back errors? */ - fd = open(path, O_RDONLY); - if (fd == -1) - return UV__ERR(errno); - - handle->path = uv__strdup(path); - if (handle->path == NULL) { - uv__close_nocheckstdio(fd); - return UV_ENOMEM; - } - - handle->cb = cb; uv__handle_start(handle); uv__io_init(&handle->event_watcher, uv__fs_event, fd); uv__io_start(handle->loop, &handle->event_watcher, POLLIN); @@ -514,7 +522,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (!uv__has_forked_with_cfrunloop) + if (!uv__has_forked_with_cfrunloop && handle->cf_cb != NULL) r = uv__fsevents_close(handle); #endif diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 433e201fe19dbf..a155a374e76c2d 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -90,7 +90,12 @@ int uv__platform_loop_init(uv_loop_t* loop) { * a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all * architectures, we just use that instead. */ +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + fd = -1; + errno = ENOSYS; +#else fd = epoll_create1(O_CLOEXEC); +#endif /* epoll_create1() can fail either because it's not implemented (old kernel) * or because it doesn't understand the O_CLOEXEC flag. @@ -203,6 +208,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { * that being the largest value I have seen in the wild (and only once.) */ static const int max_safe_timeout = 1789569; + static int no_epoll_pwait; + static int no_epoll_wait; struct epoll_event events[1024]; struct epoll_event* pe; struct epoll_event e; @@ -210,7 +217,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { QUEUE* q; uv__io_t* w; sigset_t sigset; - sigset_t* psigset; + uint64_t sigmask; uint64_t base; int have_signals; int nevents; @@ -262,11 +269,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { w->events = w->pevents; } - psigset = NULL; + sigmask = 0; if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { sigemptyset(&sigset); sigaddset(&sigset, SIGPROF); - psigset = &sigset; + sigmask |= 1 << (SIGPROF - 1); } assert(timeout >= -1); @@ -281,11 +288,35 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) timeout = max_safe_timeout; - nfds = epoll_pwait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout, - psigset); + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) + abort(); + + if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + nfds = -1; + errno = ENOSYS; +#else + nfds = epoll_pwait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout, + &sigset); +#endif + if (nfds == -1 && errno == ENOSYS) + no_epoll_pwait = 1; + } else { + nfds = epoll_wait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + if (nfds == -1 && errno == ENOSYS) + no_epoll_wait = 1; + } + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) + abort(); /* Update loop->time unconditionally. It's tempting to skip the update when * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the @@ -306,6 +337,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } if (nfds == -1) { + if (errno == ENOSYS) { + /* epoll_wait() or epoll_pwait() failed, try the other system call. */ + assert(no_epoll_wait == 0 || no_epoll_pwait == 0); + continue; + } + if (errno != EINTR) abort(); diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c index 5637cf98a7b338..950387860f04cc 100644 --- a/deps/uv/src/unix/linux-syscalls.c +++ b/deps/uv/src/unix/linux-syscalls.c @@ -203,6 +203,22 @@ # endif #endif /* __NR_statx */ +#ifndef __NR_getrandom +# if defined(__x86_64__) +# define __NR_getrandom 318 +# elif defined(__i386__) +# define __NR_getrandom 355 +# elif defined(__aarch64__) +# define __NR_getrandom 384 +# elif defined(__arm__) +# define __NR_getrandom (UV_SYSCALL_BASE + 384) +# elif defined(__ppc__) +# define __NR_getrandom 359 +# elif defined(__s390__) +# define __NR_getrandom 349 +# endif +#endif /* __NR_getrandom */ + int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { #if defined(__i386__) unsigned long args[4]; @@ -367,3 +383,12 @@ int uv__statx(int dirfd, return errno = ENOSYS, -1; #endif } + + +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) { +#if defined(__NR_getrandom) + return syscall(__NR_getrandom, buf, buflen, flags); +#else + return errno = ENOSYS, -1; +#endif +} diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h index 7e58bfa2189692..b7729b82aea9ba 100644 --- a/deps/uv/src/unix/linux-syscalls.h +++ b/deps/uv/src/unix/linux-syscalls.h @@ -148,5 +148,6 @@ int uv__statx(int dirfd, int flags, unsigned int mask, struct uv__statx* statxbuf); +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags); #endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 1f5228dc13fd7a..199a34658a7948 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -186,7 +186,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { int numcpus = 1; int which[] = {CTL_HW,HW_MODEL,0}; size_t size; - int i; + int i, j; uv_cpu_info_t* cpu_info; size = sizeof(model); diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index 834766863220fe..cdf24fa9763cb1 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -261,7 +261,7 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle, addrlen = strlen(sa.sun_path); - if (addrlen >= *size) { + if ((size_t)addrlen >= *size) { *size = addrlen + 1; return UV_ENOBUFS; } diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 1a8c7a7090e8a6..a5ce2030c55be8 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -24,6 +24,7 @@ #include #include +extern void uv__set_process_title_platform_init(void); extern void uv__set_process_title(const char* title); static uv_mutex_t process_title_mutex; @@ -38,6 +39,9 @@ static struct { static void init_process_title_mutex_once(void) { uv_mutex_init(&process_title_mutex); +#ifdef __APPLE__ + uv__set_process_title_platform_init(); +#endif } diff --git a/deps/uv/src/unix/random-devurandom.c b/deps/uv/src/unix/random-devurandom.c new file mode 100644 index 00000000000000..bfc40d20f88cb7 --- /dev/null +++ b/deps/uv/src/unix/random-devurandom.c @@ -0,0 +1,93 @@ +/* Copyright libuv 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 "internal.h" + +#include +#include + +static uv_once_t once = UV_ONCE_INIT; +static int status; + + +int uv__random_readpath(const char* path, void* buf, size_t buflen) { + struct stat s; + size_t pos; + ssize_t n; + int fd; + + fd = uv__open_cloexec(path, O_RDONLY); + + if (fd == -1) + return UV__ERR(errno); + + if (fstat(fd, &s)) { + uv__close(fd); + return UV__ERR(errno); + } + + if (!S_ISCHR(s.st_mode)) { + uv__close(fd); + return UV_EIO; + } + + for (pos = 0; pos != buflen; pos += n) { + do + n = read(fd, (char*) buf + pos, buflen - pos); + while (n == -1 && errno == EINTR); + + if (n == -1) { + uv__close(fd); + return UV__ERR(errno); + } + + if (n == 0) { + uv__close(fd); + return UV_EIO; + } + } + + uv__close(fd); + return 0; +} + + +static void uv__random_devurandom_init(void) { + char c; + + /* Linux's and NetBSD's random(4) man page suggests applications should read + * at least once from /dev/random before switching to /dev/urandom in order + * to seed the system RNG. Reads from /dev/random can of course block + * indefinitely until entropy is available but that's the point. + */ + status = uv__random_readpath("/dev/random", &c, 1); +} + + +int uv__random_devurandom(void* buf, size_t buflen) { + uv_once(&once, uv__random_devurandom_init); + + if (status != 0) + return status; + + return uv__random_readpath("/dev/urandom", buf, buflen); +} diff --git a/deps/uv/src/unix/random-getentropy.c b/deps/uv/src/unix/random-getentropy.c new file mode 100644 index 00000000000000..c45d9fd4a2b7c0 --- /dev/null +++ b/deps/uv/src/unix/random-getentropy.c @@ -0,0 +1,57 @@ +/* Copyright libuv 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 "internal.h" + +#include +#include + +typedef int (*uv__getentropy_cb)(void *, size_t); + +static uv__getentropy_cb uv__getentropy; +static uv_once_t once = UV_ONCE_INIT; + + +static void uv__random_getentropy_init(void) { + uv__getentropy = (uv__getentropy_cb) dlsym(RTLD_DEFAULT, "getentropy"); +} + + +int uv__random_getentropy(void* buf, size_t buflen) { + size_t pos; + size_t stride; + + uv_once(&once, uv__random_getentropy_init); + + if (uv__getentropy == NULL) + return UV_ENOSYS; + + /* getentropy() returns an error for requests > 256 bytes. */ + for (pos = 0, stride = 256; pos + stride < buflen; pos += stride) + if (uv__getentropy((char *) buf + pos, stride)) + return UV__ERR(errno); + + if (uv__getentropy((char *) buf + pos, buflen - pos)) + return UV__ERR(errno); + + return 0; +} diff --git a/deps/uv/src/unix/random-getrandom.c b/deps/uv/src/unix/random-getrandom.c new file mode 100644 index 00000000000000..bcc94089bcb64e --- /dev/null +++ b/deps/uv/src/unix/random-getrandom.c @@ -0,0 +1,88 @@ +/* Copyright libuv 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 "internal.h" + +#ifdef __linux__ + +#include "linux-syscalls.h" + +#define uv__random_getrandom_init() 0 + +#else /* !__linux__ */ + +#include +#include + +typedef ssize_t (*uv__getrandom_cb)(void *, size_t, unsigned); + +static uv__getrandom_cb uv__getrandom; +static uv_once_t once = UV_ONCE_INIT; + +static void uv__random_getrandom_init_once(void) { + uv__getrandom = (uv__getrandom_cb) dlsym(RTLD_DEFAULT, "getrandom"); +} + +static int uv__random_getrandom_init(void) { + uv_once(&once, uv__random_getrandom_init_once); + + if (uv__getrandom == NULL) + return UV_ENOSYS; + + return 0; +} + +#endif /* !__linux__ */ + +int uv__random_getrandom(void* buf, size_t buflen) { + ssize_t n; + size_t pos; + int rc; + + rc = uv__random_getrandom_init(); + if (rc != 0) + return rc; + + for (pos = 0; pos != buflen; pos += n) { + do { + n = buflen - pos; + + /* Most getrandom() implementations promise that reads <= 256 bytes + * will always succeed and won't be interrupted by signals. + * It's therefore useful to split it up in smaller reads because + * one big read may, in theory, continuously fail with EINTR. + */ + if (n > 256) + n = 256; + + n = uv__getrandom((char *) buf + pos, n, 0); + } while (n == -1 && errno == EINTR); + + if (n == -1) + return UV__ERR(errno); + + if (n == 0) + return UV_EIO; + } + + return 0; +} diff --git a/deps/uv/src/unix/random-sysctl.c b/deps/uv/src/unix/random-sysctl.c new file mode 100644 index 00000000000000..fb182ded09296b --- /dev/null +++ b/deps/uv/src/unix/random-sysctl.c @@ -0,0 +1,100 @@ +/* Copyright libuv 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 "internal.h" + +#include +#include + +#include +#include + + +struct uv__sysctl_args { + int* name; + int nlen; + void* oldval; + size_t* oldlenp; + void* newval; + size_t newlen; + unsigned long unused[4]; +}; + + +/* TODO(bnoordhuis) Use {CTL_KERN, KERN_ARND} on FreeBSD (and NetBSD?) */ +int uv__random_sysctl(void* buf, size_t buflen) { + static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/}; + struct uv__sysctl_args args; + char uuid[16]; + char* p; + char* pe; + size_t n; + + p = buf; + pe = p + buflen; + + while (p < pe) { + memset(&args, 0, sizeof(args)); + + args.name = name; + args.nlen = ARRAY_SIZE(name); + args.oldval = uuid; + args.oldlenp = &n; + n = sizeof(uuid); + + /* Emits a deprecation warning with some kernels but that seems like + * an okay trade-off for the fallback of the fallback: this function is + * only called when neither getrandom(2) nor /dev/urandom are available. + * Fails with ENOSYS on kernels configured without CONFIG_SYSCTL_SYSCALL. + * At least arm64 never had a _sysctl system call and therefore doesn't + * have a SYS__sysctl define either. + */ +#ifdef SYS__sysctl + if (syscall(SYS__sysctl, &args) == -1) + return UV__ERR(errno); +#else + { + (void) &args; + return UV_ENOSYS; + } +#endif + + if (n != sizeof(uuid)) + return UV_EIO; /* Can't happen. */ + + /* uuid[] is now a type 4 UUID. Bytes 6 and 8 (counting from zero) contain + * 4 and 5 bits of entropy, respectively. For ease of use, we skip those + * and only use 14 of the 16 bytes. + */ + uuid[6] = uuid[14]; + uuid[8] = uuid[15]; + + n = pe - p; + if (n > 14) + n = 14; + + memcpy(p, uuid, n); + p += n; + } + + return 0; +} diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c index 74d3d75d7615d9..e7c520f77402bc 100644 --- a/deps/uv/src/unix/tty.c +++ b/deps/uv/src/unix/tty.c @@ -365,3 +365,10 @@ int uv_tty_reset_mode(void) { return err; } + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + return UV_ENOTSUP; +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index dba8eff8382edd..98215f7e1d212b 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -165,9 +165,6 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { */ count = 32; - memset(&h, 0, sizeof(h)); - h.msg_name = &peer; - do { buf = uv_buf_init(NULL, 0); handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf); @@ -177,6 +174,9 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { } assert(buf.base != NULL); + memset(&h, 0, sizeof(h)); + memset(&peer, 0, sizeof(peer)); + h.msg_name = &peer; h.msg_namelen = sizeof(peer); h.msg_iov = (void*) &buf; h.msg_iovlen = 1; @@ -193,17 +193,11 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0); } else { - const struct sockaddr *addr; - if (h.msg_namelen == 0) - addr = NULL; - else - addr = (const struct sockaddr*) &peer; - flags = 0; if (h.msg_flags & MSG_TRUNC) flags |= UV_UDP_PARTIAL; - handle->recv_cb(handle, nread, &buf, addr, flags); + handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags); } } /* recv_cb callback may decide to pause or close the handle */ @@ -659,6 +653,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle, } +#if !defined(__OpenBSD__) && !defined(__NetBSD__) static int uv__udp_set_source_membership4(uv_udp_t* handle, const struct sockaddr_in* multicast_addr, const char* interface_addr, @@ -749,6 +744,7 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle, return 0; } +#endif int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { @@ -846,6 +842,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, const char* interface_addr, const char* source_addr, uv_membership membership) { +#if !defined(__OpenBSD__) && !defined(__NetBSD__) int err; struct sockaddr_storage mcast_addr; struct sockaddr_in* mcast_addr4; @@ -873,7 +870,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, src_addr6, membership); } - + err = uv_ip4_addr(source_addr, 0, src_addr4); if (err) return err; @@ -882,6 +879,9 @@ int uv_udp_set_source_membership(uv_udp_t* handle, interface_addr, src_addr4, membership); +#else + return UV_ENOSYS; +#endif } diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index 70db53ab04dacf..cec4ac6281b91b 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -211,6 +211,9 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { memset(addr, 0, sizeof(*addr)); addr->sin_family = AF_INET; addr->sin_port = htons(port); +#ifdef SIN6_LEN + addr->sin_len = sizeof(*addr); +#endif return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 5dccca77999dbd..3ab486080cdfa7 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -36,8 +36,6 @@ #include "handle-inl.h" #include "fs-fd-hash-inl.h" -#include - #define UV_FS_FREE_PATHS 0x0002 #define UV_FS_FREE_PTR 0x0008 @@ -1207,9 +1205,7 @@ void fs__mkdtemp(uv_fs_t* req) { WCHAR *cp, *ep; unsigned int tries, i; size_t len; - HCRYPTPROV h_crypt_prov; uint64_t v; - BOOL released; len = wcslen(req->file.pathw); ep = req->file.pathw + len; @@ -1218,16 +1214,10 @@ void fs__mkdtemp(uv_fs_t* req) { return; } - if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - tries = TMP_MAX; do { - if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); + if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) { + SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE); break; } @@ -1248,8 +1238,6 @@ void fs__mkdtemp(uv_fs_t* req) { } } while (--tries); - released = CryptReleaseContext(h_crypt_prov, 0); - assert(released); if (tries == 0) { SET_REQ_RESULT(req, -1); } @@ -2587,6 +2575,7 @@ static void fs__statfs(uv_fs_t* req) { stat_fs->f_files = 0; stat_fs->f_ffree = 0; req->ptr = stat_fs; + req->flags |= UV_FS_FREE_PTR; SET_REQ_RESULT(req, 0); } diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index 70ddaa533244e2..058ddb8edc6d10 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -280,6 +280,8 @@ int uv__getsockpeername(const uv_handle_t* handle, int* namelen, int delayed_error); +int uv__random_rtlgenrandom(void* buf, size_t buflen); + /* * Process stdio handles. diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 81e48136a3b9ef..fd34c623d8c543 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -556,7 +556,7 @@ int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { if (handle->flags & UV_HANDLE_SHUTTING) return UV_EINVAL; - if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) + if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l))) return uv_translate_sys_error(WSAGetLastError()); uv_close((uv_handle_t*) handle, close_cb); diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 8f84bcd0e45544..5d5b92d0d2d6bd 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -149,13 +149,9 @@ static char uv_tty_default_fg_bright = 0; static char uv_tty_default_bg_bright = 0; static char uv_tty_default_inverse = 0; -typedef enum { - UV_SUPPORTED, - UV_UNCHECKED, - UV_UNSUPPORTED -} uv_vtermstate_t; /* Determine whether or not ANSI support is enabled. */ -static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED; +static BOOL uv__need_check_vterm_state = TRUE; +static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED; static void uv__determine_vterm_state(HANDLE handle); void uv_console_init(void) { @@ -169,10 +165,15 @@ void uv_console_init(void) { 0, 0); if (uv__tty_console_handle != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sb_info; QueueUserWorkItem(uv__tty_console_resize_message_loop_thread, NULL, WT_EXECUTELONGFUNCTION); uv_mutex_init(&uv__tty_console_resize_mutex); + if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) { + uv__tty_console_width = sb_info.dwSize.X; + uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + } } } @@ -218,7 +219,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) { * between all uv_tty_t handles. */ uv_sem_wait(&uv_tty_output_lock); - if (uv__vterm_state == UV_UNCHECKED) + if (uv__need_check_vterm_state) uv__determine_vterm_state(handle); /* Remember the original console text attributes. */ @@ -1670,7 +1671,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle, uv_buf_t buf = bufs[i]; unsigned int j; - if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) { + if (uv__vterm_state == UV_TTY_SUPPORTED && buf.len > 0) { utf16_buf_used = MultiByteToWideChar(CP_UTF8, 0, buf.base, @@ -2275,32 +2276,24 @@ int uv_tty_reset_mode(void) { static void uv__determine_vterm_state(HANDLE handle) { DWORD dwMode = 0; + uv__need_check_vterm_state = FALSE; if (!GetConsoleMode(handle, &dwMode)) { - uv__vterm_state = UV_UNSUPPORTED; return; } dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(handle, dwMode)) { - uv__vterm_state = UV_UNSUPPORTED; return; } - uv__vterm_state = UV_SUPPORTED; + uv__vterm_state = UV_TTY_SUPPORTED; } static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { - CONSOLE_SCREEN_BUFFER_INFO sb_info; NTSTATUS status; ULONG_PTR conhost_pid; MSG msg; - if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) - return 0; - - uv__tty_console_width = sb_info.dwSize.X; - uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; - if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL) return 0; @@ -2375,6 +2368,7 @@ static void uv__tty_console_signal_resize(void) { height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; uv_mutex_lock(&uv__tty_console_resize_mutex); + assert(uv__tty_console_width != -1 && uv__tty_console_height != -1); if (width != uv__tty_console_width || height != uv__tty_console_height) { uv__tty_console_width = width; uv__tty_console_height = height; @@ -2384,3 +2378,17 @@ static void uv__tty_console_signal_resize(void) { uv_mutex_unlock(&uv__tty_console_resize_mutex); } } + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { + uv_sem_wait(&uv_tty_output_lock); + uv__need_check_vterm_state = FALSE; + uv__vterm_state = state; + uv_sem_post(&uv_tty_output_lock); +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + uv_sem_wait(&uv_tty_output_lock); + *state = uv__vterm_state; + uv_sem_post(&uv_tty_output_lock); + return 0; +} diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 39fc34d3bfcd94..3daa55f62db063 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -856,7 +856,7 @@ int uv_udp_set_source_membership(uv_udp_t* handle, src_addr6, membership); } - + err = uv_ip4_addr(source_addr, 0, src_addr4); if (err) return err; diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 8849d041bf0283..4bbeb3154123dd 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -1417,7 +1417,9 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0) goto fail; - ptr = strchr(buf, '='); + /* Using buf + 1 here because we know that `buf` has length at least 1, + * and some special environment variables on Windows start with a = sign. */ + ptr = strchr(buf + 1, '='); if (ptr == NULL) { uv__free(buf); goto do_continue; @@ -1858,3 +1860,16 @@ int uv_gettimeofday(uv_timeval64_t* tv) { tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10); return 0; } + +int uv__random_rtlgenrandom(void* buf, size_t buflen) { + if (pRtlGenRandom == NULL) + return UV_ENOSYS; + + if (buflen == 0) + return 0; + + if (pRtlGenRandom(buf, buflen) == FALSE) + return UV_EIO; + + return 0; +} diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index 19e4377faf5599..85a9de8a2295ec 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -36,6 +36,9 @@ sNtQueryDirectoryFile pNtQueryDirectoryFile; sNtQuerySystemInformation pNtQuerySystemInformation; sNtQueryInformationProcess pNtQueryInformationProcess; +/* Advapi32 function pointers */ +sRtlGenRandom pRtlGenRandom; + /* Kernel32 function pointers */ sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; @@ -51,6 +54,7 @@ void uv_winapi_init(void) { HMODULE powrprof_module; HMODULE user32_module; HMODULE kernel32_module; + HMODULE advapi32_module; ntdll_module = GetModuleHandleA("ntdll.dll"); if (ntdll_module == NULL) { @@ -135,4 +139,11 @@ void uv_winapi_init(void) { GetProcAddress(user32_module, "SetWinEventHook"); } + advapi32_module = GetModuleHandleA("advapi32.dll"); + if (advapi32_module == NULL) { + uv_fatal_error(GetLastError(), "GetModuleHandleA"); + } + + pRtlGenRandom = + (sRtlGenRandom) GetProcAddress(advapi32_module, "SystemFunction036"); } diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index 322a212dd73c19..fcc70652a9aedb 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4589,6 +4589,11 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess) ULONG Length, PULONG ReturnLength); +/* + * Advapi32 headers + */ +typedef BOOLEAN (WINAPI *sRtlGenRandom)(PVOID Buffer, ULONG BufferLength); + /* * Kernel32 headers */ @@ -4731,6 +4736,9 @@ extern sNtQueryDirectoryFile pNtQueryDirectoryFile; extern sNtQuerySystemInformation pNtQuerySystemInformation; extern sNtQueryInformationProcess pNtQueryInformationProcess; +/* Advapi32 function pointers */ +extern sRtlGenRandom pRtlGenRandom; + /* Kernel32 function pointers */ extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; diff --git a/deps/uv/src/win/winsock.h b/deps/uv/src/win/winsock.h index 7ecb755bfb061b..2af958870a7de6 100644 --- a/deps/uv/src/win/winsock.h +++ b/deps/uv/src/win/winsock.h @@ -54,6 +54,14 @@ # define SIO_BASE_HANDLE 0x48000022 #endif +#ifndef MCAST_JOIN_SOURCE_GROUP +# define MCAST_JOIN_SOURCE_GROUP 45 +#endif + +#ifndef MCAST_LEAVE_SOURCE_GROUP +# define MCAST_LEAVE_SOURCE_GROUP 46 +#endif + /* * TDI defines that are only in the DDK. * We only need receive flags so far. diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c index 3814699356db55..3c9de95b102a07 100644 --- a/deps/uv/test/test-env-vars.c +++ b/deps/uv/test/test-env-vars.c @@ -30,7 +30,7 @@ TEST_IMPL(env_vars) { const char* name2 = "UV_TEST_FOO2"; char buf[BUF_SIZE]; size_t size; - int i, r, envcount, found; + int i, r, envcount, found, found_win_special; uv_env_item_t* envitems; /* Reject invalid inputs when setting an environment variable */ @@ -108,6 +108,7 @@ TEST_IMPL(env_vars) { ASSERT(envcount > 0); found = 0; + found_win_special = 0; for (i = 0; i < envcount; i++) { /* printf("Env: %s = %s\n", envitems[i].name, envitems[i].value); */ @@ -117,10 +118,15 @@ TEST_IMPL(env_vars) { } else if (strcmp(envitems[i].name, name2) == 0) { found++; ASSERT(strlen(envitems[i].value) == 0); + } else if (envitems[i].name[0] == '=') { + found_win_special++; } } ASSERT(found == 2); +#ifdef _WIN32 + ASSERT(found_win_special > 0); +#endif uv_os_free_environ(envitems, envcount); diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index def3d967e74f5b..c3e698e5852cba 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -188,7 +188,7 @@ TEST_IMPL(fs_copyfile) { unlink(dst); r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE_FORCE, NULL); - ASSERT(r == 0 || r == UV_ENOSYS || r == UV_ENOTSUP); + ASSERT(r <= 0); if (r == 0) handle_result(&req); diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index ea34bd63a70625..e694d258ea9306 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -25,6 +25,10 @@ #include #include +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +#endif + #ifndef HAVE_KQUEUE # if defined(__APPLE__) || \ defined(__DragonFly__) || \ @@ -47,6 +51,7 @@ static const char file_prefix[] = "fsevent-"; static const int fs_event_file_count = 16; #if defined(__APPLE__) || defined(_WIN32) static const char file_prefix_in_subdir[] = "subdir"; +static int fs_multievent_cb_called; #endif static uv_timer_t timer; static int timer_cb_called; @@ -280,7 +285,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, if (filename && strcmp(filename, file_prefix_in_subdir) == 0) return; #endif - fs_event_cb_called++; + fs_multievent_cb_called++; ASSERT(handle == &fs_event); ASSERT(status == 0); ASSERT(events == UV_CHANGE || events == UV_RENAME); @@ -298,7 +303,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, if (fs_event_created + fs_event_removed == fs_event_file_count) { /* Once we've processed all create events, delete all files */ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); - } else if (fs_event_cb_called == 2 * fs_event_file_count) { + } else if (fs_multievent_cb_called == 2 * fs_event_file_count) { /* Once we've processed all create and delete events, stop watching */ uv_close((uv_handle_t*) &timer, close_cb); uv_close((uv_handle_t*) handle, close_cb); @@ -393,6 +398,21 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { uv_close((uv_handle_t*) handle, NULL); } +static void fs_event_cb_close(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(status == 0); + + ASSERT(fs_event_cb_called < 3); + ++fs_event_cb_called; + + if (fs_event_cb_called == 3) { + uv_close((uv_handle_t*) handle, close_cb); + } +} + + TEST_IMPL(fs_event_watch_dir) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); @@ -434,10 +454,12 @@ TEST_IMPL(fs_event_watch_dir) { return 0; } + TEST_IMPL(fs_event_watch_dir_recursive) { #if defined(__APPLE__) || defined(_WIN32) uv_loop_t* loop; int r; + uv_fs_event_t fs_event_root; /* Setup */ loop = uv_default_loop(); @@ -451,17 +473,37 @@ TEST_IMPL(fs_event_watch_dir_recursive) { r = uv_fs_event_init(loop, &fs_event); ASSERT(r == 0); - r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE); + r = uv_fs_event_start(&fs_event, + fs_event_cb_dir_multi_file_in_subdir, + "watch_dir", + UV_FS_EVENT_RECURSIVE); ASSERT(r == 0); r = uv_timer_init(loop, &timer); ASSERT(r == 0); r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0); ASSERT(r == 0); +#ifndef _WIN32 + /* Also try to watch the root directory. + * This will be noisier, so we're just checking for any couple events to happen. */ + r = uv_fs_event_init(loop, &fs_event_root); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event_root, + fs_event_cb_close, + "/", + UV_FS_EVENT_RECURSIVE); + ASSERT(r == 0); +#else + fs_event_cb_called += 3; + close_cb_called += 1; + (void)fs_event_root; +#endif + uv_run(loop, UV_RUN_DEFAULT); - ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); - ASSERT(close_cb_called == 2); + ASSERT(fs_multievent_cb_called == fs_event_created + fs_event_removed); + ASSERT(fs_event_cb_called == 3); + ASSERT(close_cb_called == 3); /* Cleanup */ fs_event_unlink_files_in_subdir(NULL); @@ -596,6 +638,7 @@ TEST_IMPL(fs_event_watch_file_exact_path) { * versions. Give a long delay here to let the system settle before running * the test. */ uv_sleep(1100); + uv_update_time(loop); #endif r = uv_fs_event_init(loop, &fs_event); @@ -656,6 +699,13 @@ TEST_IMPL(fs_event_watch_file_current_dir) { /* Setup */ remove("watch_file"); create_file("watch_file"); +#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12) + /* Empirically, kevent seems to (sometimes) report the preceeding + * create_file events prior to macOS 10.11.6 in the subsequent fs_event_start + * So let the system settle before running the test. */ + uv_sleep(1100); + uv_update_time(loop); +#endif r = uv_fs_event_init(loop, &fs_event); ASSERT(r == 0); @@ -864,18 +914,6 @@ TEST_IMPL(fs_event_close_with_pending_event) { return 0; } -static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, - int events, int status) { - ASSERT(status == 0); - - ASSERT(fs_event_cb_called < 3); - ++fs_event_cb_called; - - if (fs_event_cb_called == 3) { - uv_close((uv_handle_t*) handle, close_cb); - } -} - TEST_IMPL(fs_event_close_in_callback) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); diff --git a/deps/uv/test/test-fs-readdir.c b/deps/uv/test/test-fs-readdir.c index a767f1fb885dcd..5efc853cc67f0f 100644 --- a/deps/uv/test/test-fs-readdir.c +++ b/deps/uv/test/test-fs-readdir.c @@ -62,12 +62,12 @@ static void empty_readdir_cb(uv_fs_t* req) { ASSERT(req->fs_type == UV_FS_READDIR); ASSERT(req->result == 0); dir = req->ptr; + uv_fs_req_cleanup(req); r = uv_fs_closedir(uv_default_loop(), &closedir_req, dir, empty_closedir_cb); ASSERT(r == 0); - uv_fs_req_cleanup(req); } static void empty_opendir_cb(uv_fs_t* req) { diff --git a/deps/uv/test/test-ip4-addr.c b/deps/uv/test/test-ip4-addr.c index c72f36a694455d..dfefb0f914a6ef 100644 --- a/deps/uv/test/test-ip4-addr.c +++ b/deps/uv/test/test-ip4-addr.c @@ -42,6 +42,10 @@ TEST_IMPL(ip4_addr) { ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr)); ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr)); +#ifdef SIN6_LEN + ASSERT(addr.sin_len == sizeof(addr)); +#endif + /* for broken address family */ ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1", &addr.sin_addr.s_addr)); diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index bbf33a4854ed23..39d570659daafe 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -160,3 +160,12 @@ TEST_IMPL(ip6_pton) { #undef GOOD_ADDR_LIST #undef BAD_ADDR_LIST + +#ifdef SIN6_LEN +TEST_IMPL(ip6_sin6_len) { + struct sockaddr_in6 s; + ASSERT(uv_ip6_addr("::", 0, &s) < 0); + ASSERT(s.sin6_len == sizeof(s)); + return 0; +} +#endif diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index b6066f27276dc6..ad94c52d0c5866 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -395,6 +395,7 @@ TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) TEST_DECLARE (threadpool_cancel_getaddrinfo) TEST_DECLARE (threadpool_cancel_getnameinfo) +TEST_DECLARE (threadpool_cancel_random) TEST_DECLARE (threadpool_cancel_work) TEST_DECLARE (threadpool_cancel_fs) TEST_DECLARE (threadpool_cancel_single) @@ -464,6 +465,9 @@ HELPER_DECLARE (pipe_echo_server) TEST_DECLARE (queue_foreach_delete) +TEST_DECLARE (random_async) +TEST_DECLARE (random_sync) + TEST_DECLARE (handle_type_name) TEST_DECLARE (req_type_name) TEST_DECLARE (getters_setters) @@ -1000,6 +1004,7 @@ TASK_LIST_START TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 60000) TEST_ENTRY (threadpool_cancel_getaddrinfo) TEST_ENTRY (threadpool_cancel_getnameinfo) + TEST_ENTRY (threadpool_cancel_random) TEST_ENTRY (threadpool_cancel_work) TEST_ENTRY (threadpool_cancel_fs) TEST_ENTRY (threadpool_cancel_single) @@ -1018,6 +1023,9 @@ TASK_LIST_START TEST_ENTRY (queue_foreach_delete) + TEST_ENTRY (random_async) + TEST_ENTRY (random_sync) + TEST_ENTRY (handle_type_name) TEST_ENTRY (req_type_name) TEST_ENTRY (getters_setters) diff --git a/deps/uv/test/test-process-title-threadsafe.c b/deps/uv/test/test-process-title-threadsafe.c index 5b30f17f44d529..19098eda0c4019 100644 --- a/deps/uv/test/test-process-title-threadsafe.c +++ b/deps/uv/test/test-process-title-threadsafe.c @@ -25,11 +25,7 @@ #include -#ifdef __APPLE__ -# define NUM_ITERATIONS 10 -#else -# define NUM_ITERATIONS 50 -#endif +#define NUM_ITERATIONS 50 static const char* titles[] = { "8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled", diff --git a/deps/uv/test/test-random.c b/deps/uv/test/test-random.c new file mode 100644 index 00000000000000..2e3ce4424d29eb --- /dev/null +++ b/deps/uv/test/test-random.c @@ -0,0 +1,94 @@ +/* Copyright libuv 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 + +static char scratch[256]; +static int random_cb_called; + + +static void random_cb(uv_random_t* req, int status, void* buf, size_t buflen) { + char zero[sizeof(scratch)]; + + memset(zero, 0, sizeof(zero)); + + ASSERT(0 == status); + ASSERT(buf == (void*) scratch); + + if (random_cb_called == 0) { + ASSERT(buflen == 0); + ASSERT(0 == memcmp(scratch, zero, sizeof(zero))); + } else { + ASSERT(buflen == sizeof(scratch)); + /* Buy a lottery ticket if you manage to trip this assertion. */ + ASSERT(0 != memcmp(scratch, zero, sizeof(zero))); + } + + random_cb_called++; +} + + +TEST_IMPL(random_async) { + uv_random_t req; + uv_loop_t* loop; + + loop = uv_default_loop(); + ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1, + random_cb)); + ASSERT(UV_E2BIG == uv_random(loop, &req, scratch, -1, -1, random_cb)); + + ASSERT(0 == uv_random(loop, &req, scratch, 0, 0, random_cb)); + ASSERT(0 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_random(loop, &req, scratch, sizeof(scratch), 0, random_cb)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(2 == random_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(random_sync) { + char zero[256]; + char buf[256]; + + ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL)); + ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL)); + + memset(buf, 0, sizeof(buf)); + ASSERT(0 == uv_random(NULL, NULL, buf, sizeof(buf), 0, NULL)); + + /* Buy a lottery ticket if you manage to trip this assertion. */ + memset(zero, 0, sizeof(zero)); + ASSERT(0 != memcmp(buf, zero, sizeof(zero))); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c index dd13d8ae4bf1fa..be252c6f723451 100644 --- a/deps/uv/test/test-threadpool-cancel.c +++ b/deps/uv/test/test-threadpool-cancel.c @@ -37,6 +37,11 @@ struct cancel_info { uv_timer_t timer_handle; }; +struct random_info { + uv_random_t random_req; + char buf[1]; +}; + static unsigned fs_cb_called; static unsigned done_cb_called; static unsigned done2_cb_called; @@ -143,6 +148,19 @@ static void nop_done_cb(uv_work_t* req, int status) { } +static void nop_random_cb(uv_random_t* req, int status, void* buf, size_t len) { + struct random_info* ri; + + ri = container_of(req, struct random_info, random_req); + + ASSERT(status == UV_ECANCELED); + ASSERT(buf == (void*) ri->buf); + ASSERT(len == sizeof(ri->buf)); + + done_cb_called++; +} + + TEST_IMPL(threadpool_cancel_getaddrinfo) { uv_getaddrinfo_t reqs[4]; struct cancel_info ci; @@ -212,6 +230,29 @@ TEST_IMPL(threadpool_cancel_getnameinfo) { } +TEST_IMPL(threadpool_cancel_random) { + struct random_info req; + uv_loop_t* loop; + + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_random(loop, + &req.random_req, + &req.buf, + sizeof(req.buf), + 0, + nop_random_cb)); + ASSERT(0 == uv_cancel((uv_req_t*) &req)); + ASSERT(0 == done_cb_called); + unblock_threadpool(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == done_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + TEST_IMPL(threadpool_cancel_work) { struct cancel_info ci; uv_work_t reqs[16]; diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c index 9ee80e44e7c24a..6bac072db09631 100644 --- a/deps/uv/test/test-udp-multicast-join.c +++ b/deps/uv/test/test-udp-multicast-join.c @@ -74,7 +74,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static int do_send(uv_udp_send_t* send_req) { uv_buf_t buf; struct sockaddr_in addr; - + buf = uv_buf_init("PING", 4); ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr)); diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c index edcd371b2c22c0..5de27a7fb292db 100644 --- a/deps/uv/test/test-udp-multicast-join6.c +++ b/deps/uv/test/test-udp-multicast-join6.c @@ -86,7 +86,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static int do_send(uv_udp_send_t* send_req) { uv_buf_t buf; struct sockaddr_in6 addr; - + buf = uv_buf_init("PING", 4); ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr)); @@ -195,7 +195,7 @@ TEST_IMPL(udp_multicast_join6) { r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); ASSERT(r == 0); - + r = do_send(&req); ASSERT(r == 0); diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp index 60792ad6ebbb57..73ff42c56e431c 100644 --- a/deps/uv/test/test.gyp +++ b/deps/uv/test/test.gyp @@ -52,6 +52,7 @@ 'test-hrtime.c', 'test-idle.c', 'test-idna.c', + 'test-ip4-addr.c', 'test-ip6-addr.c', 'test-ipc-heavy-traffic-deadlock-bug.c', 'test-ipc-send-recv.c', @@ -90,6 +91,7 @@ 'test-process-title.c', 'test-process-title-threadsafe.c', 'test-queue-foreach-delete.c', + 'test-random.c', 'test-ref.c', 'test-run-nowait.c', 'test-run-once.c', @@ -158,8 +160,6 @@ 'test-udp-multicast-join6.c', 'test-dlerror.c', 'test-udp-multicast-ttl.c', - 'test-ip4-addr.c', - 'test-ip6-addr.c', 'test-udp-multicast-interface.c', 'test-udp-multicast-interface6.c', 'test-udp-try-send.c', diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 75a6d9781995ae..051bdc937c9fd3 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -75,6 +75,7 @@ 'src/idna.h', 'src/inet.c', 'src/queue.h', + 'src/random.c', 'src/strscpy.c', 'src/strscpy.h', 'src/threadpool.c', @@ -167,6 +168,7 @@ 'src/unix/pipe.c', 'src/unix/poll.c', 'src/unix/process.c', + 'src/unix/random-devurandom.c', 'src/unix/signal.c', 'src/unix/spinlock.h', 'src/unix/stream.c', @@ -226,7 +228,8 @@ 'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.c' + 'src/unix/darwin-proctitle.c', + 'src/unix/random-getentropy.c', ], 'defines': [ '_DARWIN_USE_64_BIT_INODE=1', @@ -241,6 +244,8 @@ 'src/unix/linux-syscalls.c', 'src/unix/linux-syscalls.h', 'src/unix/procfs-exepath.c', + 'src/unix/random-getrandom.c', + 'src/unix/random-sysctl.c', 'src/unix/sysinfo-loadavg.c', ], 'link_settings': { @@ -320,8 +325,14 @@ [ 'OS=="freebsd" or OS=="dragonflybsd"', { 'sources': [ 'src/unix/freebsd.c' ], }], + [ 'OS=="freebsd"', { + 'sources': [ 'src/unix/random-getrandom.c' ], + }], [ 'OS=="openbsd"', { - 'sources': [ 'src/unix/openbsd.c' ], + 'sources': [ + 'src/unix/openbsd.c', + 'src/unix/random-getentropy.c', + ], }], [ 'OS=="netbsd"', { 'link_settings': { diff --git a/doc/api/cli.md b/doc/api/cli.md index 13c0b102837af3..e47d315019c87b 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -144,6 +144,9 @@ added: v12.12.0 Enable experimental Source Map V3 support for stack traces. +Currently, overriding `Error.prepareStackTrace` is ignored when the +`--enable-source-maps` flag is set. + ### `--es-module-specifier-resolution=mode` Enables a signal handler that causes the Node.js process to write a heap dump -when the specified signal is received. +when the specified signal is received. `signal` must be a valid signal name. +Disabled by default. ```console $ node --heapsnapshot-signal=SIGUSR2 index.js & @@ -300,9 +304,6 @@ added: v12.4.0 Specify the file name of the heap profile generated by `--heap-prof`. -Generates a heap snapshot each time the process receives the specified signal. -`signal` must be a valid signal name. Disabled by default. - ### `--icu-data-dir=file` + @@ -3204,7 +3204,6 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
Constant
### OpenSSL Engine Constants - diff --git a/doc/api/esm.md b/doc/api/esm.md index e585ae4db63646..e1002f11fb3054 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -886,13 +886,13 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. Throw a _Module Not Found_ error. > 1. If _pjson.exports_ is not **null** or **undefined**, then > 1. If _pjson.exports_ is a String or Array, then -> 1. Return _PACKAGE_EXPORTS_TARGET_RESOLVE(packageURL, pjson.exports, -> "")_. +> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, +> _pjson.exports_, "")_. > 1. If _pjson.exports is an Object, then > 1. If _pjson.exports_ contains a _"."_ property, then > 1. Let _mainExport_ be the _"."_ property in _pjson.exports_. -> 1. Return _PACKAGE_EXPORTS_TARGET_RESOLVE(packageURL, mainExport, -> "")_. +> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, +> _mainExport_, "")_. > 1. If _pjson.main_ is a String, then > 1. Let _resolvedMain_ be the URL resolution of _packageURL_, "/", and > _pjson.main_. diff --git a/doc/api/http.md b/doc/api/http.md index e52da24779bdcf..0807cc09d08b58 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1765,7 +1765,7 @@ header name: * Duplicates of `age`, `authorization`, `content-length`, `content-type`, `etag`, `expires`, `from`, `host`, `if-modified-since`, `if-unmodified-since`, `last-modified`, `location`, `max-forwards`, `proxy-authorization`, `referer`, -`retry-after`, or `user-agent` are discarded. +`retry-after`, `server`, or `user-agent` are discarded. * `set-cookie` is always an array. Duplicates are added to the array. * For duplicate `cookie` headers, the values are joined together with '; '. * For all other headers, the values are joined together with ', '. diff --git a/doc/api/n-api.md b/doc/api/n-api.md index cefb66b614808a..40145674671433 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -4657,8 +4657,6 @@ that points to its own memory allocated by a native module). Registering externally allocated memory will trigger global garbage collections more often than it would otherwise. - - ## Promises N-API provides facilities for creating `Promise` objects as described in @@ -4846,8 +4844,6 @@ NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[out] loop`: The current libuv loop instance. - - ## Asynchronous Thread-safe Function Calls JavaScript functions can normally only be called from a native addon's main @@ -5175,10 +5171,7 @@ This API may only be called from the main thread. [Section 25.4]: https://tc39.github.io/ecma262/#sec-promise-objects [`Number.MIN_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.min_safe_integer [`Number.MAX_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.max_safe_integer -[Working with JavaScript Functions]: #n_api_working_with_javascript_functions [Working with JavaScript Properties]: #n_api_working_with_javascript_properties -[Working with JavaScript Values - Abstract Operations]: #n_api_working_with_javascript_values_abstract_operations -[Working with JavaScript Values]: #n_api_working_with_javascript_values [`init` hooks]: async_hooks.html#async_hooks_init_asyncid_type_triggerasyncid_resource [`napi_add_finalizer`]: #n_api_napi_add_finalizer [`napi_async_init`]: #n_api_napi_async_init @@ -5194,8 +5187,6 @@ This API may only be called from the main thread. [`napi_create_type_error`]: #n_api_napi_create_type_error [`napi_define_class`]: #n_api_napi_define_class [`napi_delete_async_work`]: #n_api_napi_delete_async_work -[`napi_delete_element`]: #n_api_napi_delete_element -[`napi_delete_property`]: #n_api_napi_delete_property [`napi_delete_reference`]: #n_api_napi_delete_reference [`napi_escape_handle`]: #n_api_napi_escape_handle [`napi_get_and_clear_last_exception`]: #n_api_napi_get_and_clear_last_exception @@ -5205,7 +5196,6 @@ This API may only be called from the main thread. [`napi_get_property`]: #n_api_napi_get_property [`napi_get_reference_value`]: #n_api_napi_get_reference_value [`napi_get_value_external`]: #n_api_napi_get_value_external -[`napi_has_own_property`]: #n_api_napi_has_own_property [`napi_has_property`]: #n_api_napi_has_property [`napi_is_error`]: #n_api_napi_is_error [`napi_is_exception_pending`]: #n_api_napi_is_exception_pending diff --git a/doc/api/stream.md b/doc/api/stream.md index 52d8183d8ddbc1..ef0bbb502735d3 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1288,8 +1288,10 @@ changes: * `encoding` {string} Encoding of string chunks. Must be a valid `Buffer` encoding, such as `'utf8'` or `'ascii'`. -Passing `chunk` as `null` signals the end of the stream (EOF), after which no -more data can be written. +Passing `chunk` as `null` signals the end of the stream (EOF) and behaves the +same as `readable.push(null)`, after which no more data can be written. The EOF +signal is put at the end of the buffer and any buffered data will still be +flushed. The `readable.unshift()` method pushes a chunk of data back into the internal buffer. This is useful in certain situations where a stream is being consumed by diff --git a/doc/api/tls.md b/doc/api/tls.md index c2e169af3257f8..5529bd3529aecc 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1677,7 +1677,7 @@ added: v11.4.0 [`tls.createSecureContext()`][]. It can be assigned any of the supported TLS protocol versions, `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. **Default:** `'TLSv1.3'`, unless changed using CLI options. Using - `--tls-max-v1.2` sets the default to `'TLSv1.2`'. Using `--tls-max-v1.3` sets + `--tls-max-v1.2` sets the default to `'TLSv1.2'`. Using `--tls-max-v1.3` sets the default to `'TLSv1.3'`. If multiple of the options are provided, the highest maximum is used. @@ -1688,7 +1688,7 @@ added: v11.4.0 * {string} The default value of the `minVersion` option of [`tls.createSecureContext()`][]. It can be assigned any of the supported TLS - protocol versions, `'TLSv1.3'`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. + protocol versions, `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. **Default:** `'TLSv1.2'`, unless changed using CLI options. Using `--tls-min-v1.0` sets the default to `'TLSv1'`. Using `--tls-min-v1.1` sets the default to `'TLSv1.1'`. Using `--tls-min-v1.3` sets the default to diff --git a/doc/changelogs/CHANGELOG_V13.md b/doc/changelogs/CHANGELOG_V13.md index 19ea2ad2e7de7e..67c3a3528c0c79 100644 --- a/doc/changelogs/CHANGELOG_V13.md +++ b/doc/changelogs/CHANGELOG_V13.md @@ -29,6 +29,52 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2019-10-23, Version 13.0.1 (Current), @targos + +### Notable Changes + +* **deps**: + * Fixed a bug in npm 6.12.0 where warnings are emitted on Node.js 13.x (Jordan Harband) [#30079](https://github.com/nodejs/node/pull/30079). +* **esm**: + * Changed file extension resolution order of `--es-module-specifier-resolution=node` + to match that of the CommonJS loader (Myles Borins) [#29974](https://github.com/nodejs/node/pull/29974). + +### Commits + +* [[`19a983c615`](https://github.com/nodejs/node/commit/19a983c615)] - **build**: make linter failures fail `test-doc` target (Richard Lau) [#30012](https://github.com/nodejs/node/pull/30012) +* [[`13f3d6c680`](https://github.com/nodejs/node/commit/13f3d6c680)] - **build**: log the found compiler version if too old (Richard Lau) [#30028](https://github.com/nodejs/node/pull/30028) +* [[`a25d2fcf8b`](https://github.com/nodejs/node/commit/a25d2fcf8b)] - **build**: make configure --without-snapshot a no-op (Michaël Zasso) [#30021](https://github.com/nodejs/node/pull/30021) +* [[`e04d0584a5`](https://github.com/nodejs/node/commit/e04d0584a5)] - **build**: default Windows build to Visual Studio 2019 (Michaël Zasso) [#30022](https://github.com/nodejs/node/pull/30022) +* [[`ccf58835c7`](https://github.com/nodejs/node/commit/ccf58835c7)] - **build**: use python3 to build and test on Travis (Christian Clauss) [#29451](https://github.com/nodejs/node/pull/29451) +* [[`b92afcd90c`](https://github.com/nodejs/node/commit/b92afcd90c)] - **build**: fix version checks in configure.py (Michaël Zasso) [#29965](https://github.com/nodejs/node/pull/29965) +* [[`2dc4da0d8b`](https://github.com/nodejs/node/commit/2dc4da0d8b)] - **build**: build benchmark addons like test addons (Richard Lau) [#29995](https://github.com/nodejs/node/pull/29995) +* [[`2f36976594`](https://github.com/nodejs/node/commit/2f36976594)] - **deps**: npm: patch support for 13.x (Jordan Harband) [#30079](https://github.com/nodejs/node/pull/30079) +* [[`9d332ab4ce`](https://github.com/nodejs/node/commit/9d332ab4ce)] - **deps**: upgrade to libuv 1.33.1 (Colin Ihrig) [#29996](https://github.com/nodejs/node/pull/29996) +* [[`89b9115c4d`](https://github.com/nodejs/node/commit/89b9115c4d)] - **doc**: --enable-source-maps and prepareStackTrace are incompatible (Benjamin Coe) [#30046](https://github.com/nodejs/node/pull/30046) +* [[`35bffcdd9d`](https://github.com/nodejs/node/commit/35bffcdd9d)] - **doc**: join parts of disrupt section in cli.md (vsemozhetbyt) [#30038](https://github.com/nodejs/node/pull/30038) +* [[`0299767508`](https://github.com/nodejs/node/commit/0299767508)] - **doc**: update collaborator email address (Minwoo Jung) [#30007](https://github.com/nodejs/node/pull/30007) +* [[`ff4f2999e6`](https://github.com/nodejs/node/commit/ff4f2999e6)] - **doc**: fix tls version typo (akitsu-sanae) [#29984](https://github.com/nodejs/node/pull/29984) +* [[`62b4ca6e32`](https://github.com/nodejs/node/commit/62b4ca6e32)] - **doc**: clarify readable.unshift null/EOF (Robert Nagy) [#29950](https://github.com/nodejs/node/pull/29950) +* [[`dc83ff9056`](https://github.com/nodejs/node/commit/dc83ff9056)] - **doc**: remove unused Markdown reference links (Nick Schonning) [#29961](https://github.com/nodejs/node/pull/29961) +* [[`d80ece68ac`](https://github.com/nodejs/node/commit/d80ece68ac)] - **doc**: re-enable passing remark-lint rule (Nick Schonning) [#29961](https://github.com/nodejs/node/pull/29961) +* [[`828e171107`](https://github.com/nodejs/node/commit/828e171107)] - **doc**: add server header into the discarded list of http message.headers (Huachao Mao) [#29962](https://github.com/nodejs/node/pull/29962) +* [[`9729c5da8a`](https://github.com/nodejs/node/commit/9729c5da8a)] - **esm**: modify resolution order for specifier flag (Myles Borins) [#29974](https://github.com/nodejs/node/pull/29974) +* [[`cfd45ebf94`](https://github.com/nodejs/node/commit/cfd45ebf94)] - **module**: refactor modules bootstrap (Bradley Farias) [#29937](https://github.com/nodejs/node/pull/29937) +* [[`d561321e4a`](https://github.com/nodejs/node/commit/d561321e4a)] - **src**: remove unnecessary std::endl usage (Daniel Bevenius) [#30003](https://github.com/nodejs/node/pull/30003) +* [[`ed80c233cd`](https://github.com/nodejs/node/commit/ed80c233cd)] - **src**: make implementing CancelPendingDelayedTasks for platform optional (Anna Henningsen) [#30034](https://github.com/nodejs/node/pull/30034) +* [[`8fcc039de9`](https://github.com/nodejs/node/commit/8fcc039de9)] - **src**: expose ListNode\::prev\_ on postmortem metadata (legendecas) [#30027](https://github.com/nodejs/node/pull/30027) +* [[`0c88dc1932`](https://github.com/nodejs/node/commit/0c88dc1932)] - **src**: fewer uses of NODE\_USE\_V8\_PLATFORM (Shelley Vohr) [#30029](https://github.com/nodejs/node/pull/30029) +* [[`972144073b`](https://github.com/nodejs/node/commit/972144073b)] - **src**: remove unused iomanip include (Daniel Bevenius) [#30004](https://github.com/nodejs/node/pull/30004) +* [[`b019ccd59d`](https://github.com/nodejs/node/commit/b019ccd59d)] - **src**: initialize openssl only once (Sam Roberts) [#29999](https://github.com/nodejs/node/pull/29999) +* [[`3eae670470`](https://github.com/nodejs/node/commit/3eae670470)] - **src**: refine maps parsing for large pages (Gabriel Schulhof) [#29973](https://github.com/nodejs/node/pull/29973) +* [[`f3712dfe83`](https://github.com/nodejs/node/commit/f3712dfe83)] - **stream**: simplify uint8ArrayToBuffer helper (Luigi Pinca) [#30041](https://github.com/nodejs/node/pull/30041) +* [[`46aa4810ad`](https://github.com/nodejs/node/commit/46aa4810ad)] - **stream**: remove dead code (Luigi Pinca) [#30041](https://github.com/nodejs/node/pull/30041) +* [[`f155dfeecb`](https://github.com/nodejs/node/commit/f155dfeecb)] - **test**: expand Worker test for non-shared ArrayBuffer (Anna Henningsen) [#30044](https://github.com/nodejs/node/pull/30044) +* [[`e110d81b17`](https://github.com/nodejs/node/commit/e110d81b17)] - **test**: fix test runner for Python 3 on Windows (Michaël Zasso) [#30023](https://github.com/nodejs/node/pull/30023) +* [[`c096f251e4`](https://github.com/nodejs/node/commit/c096f251e4)] - **test**: remove common.skipIfInspectorEnabled() (Rich Trott) [#29993](https://github.com/nodejs/node/pull/29993) +* [[`b1b8663a23`](https://github.com/nodejs/node/commit/b1b8663a23)] - **test**: add cb error test for fs.close() (Matteo Rossi) [#29970](https://github.com/nodejs/node/pull/29970) + ## 2019-10-22, Version 13.0.0 (Current), @BethGriggs diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js index 775fea064ecb63..48afed2556a51b 100644 --- a/lib/internal/bootstrap/loaders.js +++ b/lib/internal/bootstrap/loaders.js @@ -220,7 +220,10 @@ NativeModule.prototype.compileForPublicLoader = function(needToSyncExports) { this.compile(); if (needToSyncExports) { if (!this.exportKeys) { - this.exportKeys = Object.keys(this.exports); + // When using --expose-internals, we do not want to reflect the named + // exports from core modules as this can trigger unnecessary getters. + const internal = this.id.startsWith('internal/'); + this.exportKeys = internal ? [] : Object.keys(this.exports); } this.getESMFacade(); this.syncExports(); diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index 1126fbcdd71bce..80ac97ee450efa 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -5,6 +5,7 @@ const { Object, SafeWeakMap } = primordials; const { getOptionValue } = require('internal/options'); const { Buffer } = require('buffer'); const { ERR_MANIFEST_ASSERT_INTEGRITY } = require('internal/errors').codes; +const path = require('path'); function prepareMainThreadExecution(expandArgv1 = false) { // Patch the process object with legacy properties and normalizations @@ -404,7 +405,6 @@ function initializeESMLoader() { 'The ESM module loader is experimental.', 'ExperimentalWarning', undefined); } - const { setImportModuleDynamicallyCallback, setInitializeImportMetaObjectCallback @@ -414,14 +414,6 @@ function initializeESMLoader() { // track of for different ESM modules. setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject); setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback); - const userLoader = getOptionValue('--experimental-loader'); - // If --experimental-loader is specified, create a loader with user hooks. - // Otherwise create the default loader. - if (userLoader) { - const { emitExperimentalWarning } = require('internal/util'); - emitExperimentalWarning('--experimental-loader'); - } - esm.initializeLoader(process.cwd(), userLoader); } } @@ -446,11 +438,70 @@ function loadPreloadModules() { } } +function resolveMainPath(main) { + const { toRealPath, Module: CJSModule } = + require('internal/modules/cjs/loader'); + + // Note extension resolution for the main entry point can be deprecated in a + // future major. + let mainPath = CJSModule._findPath(path.resolve(main), null, true); + if (!mainPath) + return; + + const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); + if (!preserveSymlinksMain) + mainPath = toRealPath(mainPath); + + return mainPath; +} + +function shouldUseESMLoader(mainPath) { + const experimentalModules = getOptionValue('--experimental-modules'); + if (!experimentalModules) + return false; + const userLoader = getOptionValue('--experimental-loader'); + if (userLoader) + return true; + // Determine the module format of the main + if (mainPath && mainPath.endsWith('.mjs')) + return true; + if (!mainPath || mainPath.endsWith('.cjs')) + return false; + const { readPackageScope } = require('internal/modules/cjs/loader'); + const pkg = readPackageScope(mainPath); + return pkg && pkg.data.type === 'module'; +} + +function runMainESM(mainPath) { + const esmLoader = require('internal/process/esm_loader'); + const { pathToFileURL } = require('internal/url'); + const { hasUncaughtExceptionCaptureCallback } = + require('internal/process/execution'); + return esmLoader.initializeLoader().then(() => { + const main = path.isAbsolute(mainPath) ? + pathToFileURL(mainPath).href : mainPath; + return esmLoader.ESMLoader.import(main).catch((e) => { + if (hasUncaughtExceptionCaptureCallback()) { + process._fatalException(e); + return; + } + internalBinding('errors').triggerUncaughtException( + e, + true /* fromPromise */ + ); + }); + }); +} + + module.exports = { patchProcessObject, + resolveMainPath, + runMainESM, setupCoverageHooks, setupWarningHandler, setupDebugEnv, + shouldUseESMLoader, prepareMainThreadExecution, initializeDeprecations, initializeESMLoader, diff --git a/lib/internal/main/run_main_module.js b/lib/internal/main/run_main_module.js index 2cad569dcce9fd..77d997b97a1c7a 100644 --- a/lib/internal/main/run_main_module.js +++ b/lib/internal/main/run_main_module.js @@ -10,8 +10,7 @@ const CJSModule = require('internal/modules/cjs/loader').Module; markBootstrapComplete(); -// Note: this actually tries to run the module as a ESM first if -// --experimental-modules is on. -// TODO(joyeecheung): can we move that logic to here? Note that this -// is an undocumented method available via `require('module').runMain` -CJSModule.runMain(); +// Note: this loads the module through the ESM loader if +// --experimental-loader is provided or --experimental-modules is on +// and the module is determined to be an ES module +CJSModule.runMain(process.argv[1]); diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index 50a19be77dd78d..7cf8ffb8b401f5 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -140,8 +140,9 @@ port.on('message', (message) => { const { evalScript } = require('internal/process/execution'); evalScript('[worker eval]', filename); } else { - process.argv[1] = filename; // script filename - require('module').runMain(); + // script filename + const CJSModule = require('internal/modules/cjs/loader').Module; + CJSModule.runMain(process.argv[1] = filename); } } else if (message.type === STDIO_PAYLOAD) { const { stream, chunk, encoding } = message; diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index a8dd3bbaa3f5ae..a28383690ae2d9 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -69,9 +69,14 @@ const { ERR_REQUIRE_ESM } = require('internal/errors').codes; const { validateString } = require('internal/validators'); +const { + resolveMainPath, + shouldUseESMLoader, + runMainESM +} = require('internal/bootstrap/pre_execution'); const pendingDeprecation = getOptionValue('--pending-deprecation'); -module.exports = { wrapSafe, Module }; +module.exports = { wrapSafe, Module, toRealPath, readPackageScope }; let asyncESM, ModuleJob, ModuleWrap, kInstantiated; @@ -810,6 +815,10 @@ Module.prototype.load = function(filename) { this.paths = Module._nodeModulePaths(path.dirname(filename)); const extension = findLongestRegisteredExtension(filename); + // allow .mjs to be overridden + if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) { + throw new ERR_REQUIRE_ESM(filename); + } Module._extensions[extension](this, filename); this.loaded = true; @@ -823,14 +832,19 @@ Module.prototype.load = function(filename) { if (module !== undefined && module.module !== undefined) { if (module.module.getStatus() >= kInstantiated) module.module.setExport('default', exports); - } else { // preemptively cache + } else { + // Preemptively cache + // We use a function to defer promise creation for async hooks. ESMLoader.moduleMap.set( url, - new ModuleJob(ESMLoader, url, () => + // Module job creation will start promises. + // We make it a function to lazily trigger those promises + // for async hooks compatibility. + () => new ModuleJob(ESMLoader, url, () => new ModuleWrap(url, undefined, ['default'], function() { this.setExport('default', exports); }) - ) + , false /* isMain */, false /* inspectBrk */) ); } } @@ -859,7 +873,7 @@ Module.prototype.require = function(id) { var resolvedArgv; let hasPausedEntry = false; -function wrapSafe(filename, content) { +function wrapSafe(filename, content, cjsModuleInstance) { if (patched) { const wrapper = Module.wrap(content); return vm.runInThisContext(wrapper, { @@ -867,7 +881,7 @@ function wrapSafe(filename, content) { lineOffset: 0, displayErrors: true, importModuleDynamically: experimentalModules ? async (specifier) => { - const loader = await asyncESM.loaderPromise; + const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); } : undefined, }); @@ -892,9 +906,8 @@ function wrapSafe(filename, content) { ] ); } catch (err) { - if (experimentalModules) { + if (experimentalModules && process.mainModule === cjsModuleInstance) enrichCJSError(err); - } throw err; } @@ -902,7 +915,7 @@ function wrapSafe(filename, content) { const { callbackMap } = internalBinding('module_wrap'); callbackMap.set(compiled.cacheKey, { importModuleDynamically: async (specifier) => { - const loader = await asyncESM.loaderPromise; + const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); } }); @@ -925,7 +938,7 @@ Module.prototype._compile = function(content, filename) { } maybeCacheSourceMap(filename, content, this); - const compiledWrapper = wrapSafe(filename, content); + const compiledWrapper = wrapSafe(filename, content, this); var inspectorWrapper = null; if (getOptionValue('--inspect-brk') && process._eval == null) { @@ -981,7 +994,11 @@ Module._extensions['.js'] = function(module, filename) { 'files in that package scope as ES modules.\nInstead rename ' + `${basename} to end in .cjs, change the requiring code to use ` + 'import(), or remove "type": "module" from ' + - `${path.resolve(pkg.path, 'package.json')}.` + `${path.resolve(pkg.path, 'package.json')}.`, + undefined, + undefined, + undefined, + true ); warnRequireESM = false; } @@ -1024,26 +1041,15 @@ Module._extensions['.node'] = function(module, filename) { return process.dlopen(module, path.toNamespacedPath(filename)); }; -Module._extensions['.mjs'] = function(module, filename) { - throw new ERR_REQUIRE_ESM(filename); -}; - // Bootstrap main module. -Module.runMain = function() { - // Load the main module--the command line argument. - if (experimentalModules) { - asyncESM.loaderPromise.then((loader) => { - return loader.import(pathToFileURL(process.argv[1]).href); - }) - .catch((e) => { - internalBinding('errors').triggerUncaughtException( - e, - true /* fromPromise */ - ); - }); - return; +Module.runMain = function(main = process.argv[1]) { + const resolvedMain = resolveMainPath(main); + const useESMLoader = shouldUseESMLoader(resolvedMain); + if (useESMLoader) { + runMainESM(resolvedMain || main); + } else { + Module._load(main, null, true); } - Module._load(process.argv[1], null, true); }; function createRequireFromPath(filename) { @@ -1164,7 +1170,7 @@ Module.Module = Module; // We have to load the esm things after module.exports! if (experimentalModules) { - asyncESM = require('internal/process/esm_loader'); ModuleJob = require('internal/modules/esm/module_job'); + asyncESM = require('internal/process/esm_loader'); ({ ModuleWrap, kInstantiated } = internalBinding('module_wrap')); } diff --git a/lib/internal/modules/esm/default_resolve.js b/lib/internal/modules/esm/default_resolve.js index 7686e3e003eede..88af3cb5f8d286 100644 --- a/lib/internal/modules/esm/default_resolve.js +++ b/lib/internal/modules/esm/default_resolve.js @@ -9,6 +9,8 @@ const { getOptionValue } = require('internal/options'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const experimentalJsonModules = getOptionValue('--experimental-json-modules'); +const esModuleSpecifierResolution = + getOptionValue('--es-module-specifier-resolution'); const typeFlag = getOptionValue('--input-type'); const experimentalWasmModules = getOptionValue('--experimental-wasm-modules'); const { resolve: moduleWrapResolve, @@ -110,6 +112,8 @@ function resolve(specifier, parentURL) { if (!format) { if (isMain) format = type === TYPE_MODULE ? 'module' : 'commonjs'; + else if (esModuleSpecifierResolution === 'node') + format = 'commonjs'; else throw new ERR_UNKNOWN_FILE_EXTENSION(fileURLToPath(url)); } diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index a62529e9b32250..875fb97f912a85 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -22,6 +22,7 @@ const createDynamicModule = require( 'internal/modules/esm/create_dynamic_module'); const { translators } = require('internal/modules/esm/translators'); const { ModuleWrap } = internalBinding('module_wrap'); +const { getOptionValue } = require('internal/options'); const debug = require('internal/util/debuglog').debuglog('esm'); @@ -118,7 +119,7 @@ class Loader { url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href ) { const evalInstance = (url) => new ModuleWrap(url, undefined, source, 0, 0); - const job = new ModuleJob(this, url, evalInstance, false); + const job = new ModuleJob(this, url, evalInstance, false, false); this.moduleMap.set(url, job); const { module, result } = await job.run(); return { @@ -146,6 +147,9 @@ class Loader { async getModuleJob(specifier, parentURL) { const { url, format } = await this.resolve(specifier, parentURL); let job = this.moduleMap.get(url); + // CommonJS will set functions for lazy job evaluation. + if (typeof job === 'function') + this.moduleMap.set(url, job = job()); if (job !== undefined) return job; @@ -169,7 +173,10 @@ class Loader { loaderInstance = translators.get(format); } - job = new ModuleJob(this, url, loaderInstance, parentURL === undefined); + const inspectBrk = parentURL === undefined && + format === 'module' && getOptionValue('--inspect-brk'); + job = new ModuleJob(this, url, loaderInstance, parentURL === undefined, + inspectBrk); this.moduleMap.set(url, job); return job; } diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index ef11e2ec833b89..df1edc3810c080 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -9,7 +9,6 @@ const { const { ModuleWrap } = internalBinding('module_wrap'); const { decorateErrorStack } = require('internal/util'); -const { getOptionValue } = require('internal/options'); const assert = require('internal/assert'); const resolvedPromise = SafePromise.resolve(); @@ -22,9 +21,10 @@ let hasPausedEntry = false; class ModuleJob { // `loader` is the Loader instance used for loading dependencies. // `moduleProvider` is a function - constructor(loader, url, moduleProvider, isMain) { + constructor(loader, url, moduleProvider, isMain, inspectBrk) { this.loader = loader; this.isMain = isMain; + this.inspectBrk = inspectBrk; // This is a Promise<{ module, reflect }>, whose fields will be copied // onto `this` by `link()` below once it has been resolved. @@ -83,12 +83,12 @@ class ModuleJob { }; await addJobsToDependencyGraph(this); try { - if (!hasPausedEntry && this.isMain && getOptionValue('--inspect-brk')) { + if (!hasPausedEntry && this.inspectBrk) { hasPausedEntry = true; const initWrapper = internalBinding('inspector').callAndPauseOnStart; initWrapper(this.module.instantiate, this.module); } else { - this.module.instantiate(); + this.module.instantiate(true); } } catch (e) { decorateErrorStack(e); diff --git a/lib/internal/modules/esm/module_map.js b/lib/internal/modules/esm/module_map.js index 01521fb7885ee1..41adc0079ada31 100644 --- a/lib/internal/modules/esm/module_map.js +++ b/lib/internal/modules/esm/module_map.js @@ -16,7 +16,8 @@ class ModuleMap extends SafeMap { } set(url, job) { validateString(url, 'url'); - if (job instanceof ModuleJob !== true) { + if (job instanceof ModuleJob !== true && + typeof job !== 'function') { throw new ERR_INVALID_ARG_TYPE('job', 'ModuleJob', job); } debug(`Storing ${url} in ModuleMap`); diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 18ccfb35e81c8a..34a9a140dd7732 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -23,7 +23,6 @@ const fs = require('fs'); const { fileURLToPath, URL } = require('url'); const { debuglog } = require('internal/util/debuglog'); const { promisify } = require('internal/util'); -const esmLoader = require('internal/process/esm_loader'); const { ERR_INVALID_URL, ERR_INVALID_URL_SCHEME, @@ -69,9 +68,12 @@ function initializeImportMeta(meta, { url }) { meta.url = url; } +let esmLoader; async function importModuleDynamically(specifier, { url }) { - const loader = await esmLoader.loaderPromise; - return loader.import(specifier, url); + if (!esmLoader) { + esmLoader = require('internal/process/esm_loader'); + } + return esmLoader.ESMLoader.import(specifier, url); } // Strategy for loading a standard JavaScript module diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index 69e1fd00163cdb..49463e284c541f 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -3,12 +3,14 @@ const { ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, } = require('internal/errors').codes; - +const assert = require('internal/assert'); const { Loader } = require('internal/modules/esm/loader'); const { pathToFileURL } = require('internal/url'); const { getModuleFromWrap, } = require('internal/vm/module'); +const { getOptionValue } = require('internal/options'); +const userLoader = getOptionValue('--experimental-loader'); exports.initializeImportMetaObject = function(wrap, meta) { const { callbackMap } = internalBinding('module_wrap'); @@ -21,6 +23,7 @@ exports.initializeImportMetaObject = function(wrap, meta) { }; exports.importModuleDynamicallyCallback = async function(wrap, specifier) { + assert(calledInitialize === true || !userLoader); const { callbackMap } = internalBinding('module_wrap'); if (callbackMap.has(wrap)) { const { importModuleDynamically } = callbackMap.get(wrap); @@ -32,24 +35,31 @@ exports.importModuleDynamicallyCallback = async function(wrap, specifier) { throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING(); }; -let loaderResolve; -exports.loaderPromise = new Promise((resolve) => loaderResolve = resolve); - -exports.ESMLoader = undefined; +let ESMLoader = new Loader(); +exports.ESMLoader = ESMLoader; -exports.initializeLoader = function(cwd, userLoader) { - let ESMLoader = new Loader(); - const loaderPromise = (async () => { - if (userLoader) { - const hooks = await ESMLoader.import( - userLoader, pathToFileURL(`${cwd}/`).href); - ESMLoader = new Loader(); - ESMLoader.hook(hooks); - exports.ESMLoader = ESMLoader; - } - return ESMLoader; +let calledInitialize = false; +exports.initializeLoader = initializeLoader; +async function initializeLoader() { + assert(calledInitialize === false); + calledInitialize = true; + if (!userLoader) + return; + let cwd; + try { + cwd = process.cwd() + '/'; + } catch { + cwd = 'file:///'; + } + // If --experimental-loader is specified, create a loader with user hooks. + // Otherwise create the default loader. + const { emitExperimentalWarning } = require('internal/util'); + emitExperimentalWarning('--experimental-loader'); + return (async () => { + const hooks = + await ESMLoader.import(userLoader, pathToFileURL(cwd).href); + ESMLoader = new Loader(); + ESMLoader.hook(hooks); + return exports.ESMLoader = ESMLoader; })(); - loaderResolve(loaderPromise); - - exports.ESMLoader = ESMLoader; -}; +} diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 06dfbce2958f08..eed554263c213c 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -39,7 +39,7 @@ function evalModule(source, print) { const { log, error } = require('internal/console/global'); const { decorateErrorStack } = require('internal/util'); const asyncESM = require('internal/process/esm_loader'); - asyncESM.loaderPromise.then(async (loader) => { + Promise.resolve(asyncESM.ESMLoader).then(async (loader) => { const { result } = await loader.eval(source); if (print) { log(result); diff --git a/lib/repl.js b/lib/repl.js index bce90a18602e8f..88b0f5658489fc 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -99,6 +99,7 @@ const { } = internalBinding('contextify'); const history = require('internal/repl/history'); +const { setImmediate } = require('timers'); // Lazy-loaded. let processTopLevelAwait; @@ -338,11 +339,9 @@ function REPLServer(prompt, script = vm.createScript(code, { filename: file, displayErrors: true, - importModuleDynamically: experimentalModules ? - async (specifier) => { - return (await asyncESM.loaderPromise).import(specifier, pwd); - } : - undefined + importModuleDynamically: experimentalModules ? async (specifier) => { + return asyncESM.ESMLoader.import(specifier, pwd); + } : undefined }); } catch (e) { debug('parse error %j', code, e); @@ -1080,7 +1079,11 @@ function complete(line, callback) { // All this is only profitable if the nested REPL does not have a // bufferedCommand. if (!magic[kBufferedCommandSymbol]) { - magic._domain.on('error', (err) => { throw err; }); + magic._domain.on('error', (err) => { + setImmediate(() => { + throw err; + }); + }); return magic.complete(line, callback); } } diff --git a/lib/stream.js b/lib/stream.js index 826f0e6d9adb6c..725038ba9c0d1c 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -21,9 +21,9 @@ 'use strict'; -const { Buffer } = require('buffer'); const pipeline = require('internal/streams/pipeline'); const eos = require('internal/streams/end-of-stream'); +const internalBuffer = require('internal/buffer'); // Note: export Stream before Readable/Writable/Duplex/... // to avoid a cross-reference(require) issues @@ -42,24 +42,8 @@ Stream.finished = eos; Stream.Stream = Stream; Stream._isUint8Array = require('internal/util/types').isUint8Array; - -const version = process.version.substr(1).split('.'); -if (version[0] === 0 && version[1] < 12) { - Stream._uint8ArrayToBuffer = Buffer; -} else { - try { - const internalBuffer = require('internal/buffer'); - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return new internalBuffer.FastBuffer(chunk.buffer, - chunk.byteOffset, - chunk.byteLength); - }; - } catch (e) { // eslint-disable-line no-unused-vars - } - - if (!Stream._uint8ArrayToBuffer) { - Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { - return Buffer.prototype.slice.call(chunk); - }; - } -} +Stream._uint8ArrayToBuffer = function _uint8ArrayToBuffer(chunk) { + return new internalBuffer.FastBuffer(chunk.buffer, + chunk.byteOffset, + chunk.byteLength); +}; diff --git a/node.gyp b/node.gyp index 9bf8fa2b994da1..ecdecb05f4da8f 100644 --- a/node.gyp +++ b/node.gyp @@ -1,7 +1,7 @@ { 'variables': { 'v8_use_siphash%': 0, - 'v8_use_snapshot%': 0, + 'v8_use_snapshot%': 1, 'v8_trace_maps%': 0, 'node_use_dtrace%': 'false', 'node_use_etw%': 'false', diff --git a/src/env.h b/src/env.h index 46aecfd2521260..0e34c43ebafdf2 100644 --- a/src/env.h +++ b/src/env.h @@ -868,7 +868,7 @@ class Environment : public MemoryRetainer { void CreateProperties(); // Should be called before InitializeInspector() void InitializeDiagnostics(); -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR // If the environment is created for a worker, pass parent_handle and // the ownership if transferred into the Environment. int InitializeInspector(inspector::ParentInspectorHandle* parent_handle); diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc index 220f71fa105ff5..4e2f8fc4410316 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -83,11 +83,11 @@ static void PrintSystemError(int error) { return; } -inline int64_t hugepage_align_up(int64_t addr) { +inline uintptr_t hugepage_align_up(uintptr_t addr) { return (((addr) + (hps) - 1) & ~((hps) - 1)); } -inline int64_t hugepage_align_down(int64_t addr) { +inline uintptr_t hugepage_align_down(uintptr_t addr) { return ((addr) & ~((hps) - 1)); } @@ -103,7 +103,7 @@ static struct text_region FindNodeTextRegion() { std::string permission; std::string dev; char dash; - int64_t start, end, offset, inode; + uintptr_t start, end, offset, inode; struct text_region nregion; nregion.found_text_region = false; @@ -138,18 +138,20 @@ static struct text_region FindNodeTextRegion() { std::string pathname; iss >> pathname; if (pathname == exename && permission == "r-xp") { - start = reinterpret_cast(&__nodetext); - char* from = reinterpret_cast(hugepage_align_up(start)); - char* to = reinterpret_cast(hugepage_align_down(end)); - - if (from < to) { - size_t size = to - from; - nregion.found_text_region = true; - nregion.from = from; - nregion.to = to; - nregion.total_hugepages = size / hps; + uintptr_t ntext = reinterpret_cast(&__nodetext); + if (ntext >= start && ntext < end) { + char* from = reinterpret_cast(hugepage_align_up(ntext)); + char* to = reinterpret_cast(hugepage_align_down(end)); + + if (from < to) { + size_t size = to - from; + nregion.found_text_region = true; + nregion.from = from; + nregion.to = to; + nregion.total_hugepages = size / hps; + } + break; } - break; } } } diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 97e6b5453d33c2..e7df8688cb8582 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -48,11 +48,10 @@ using v8::Undefined; using v8::Value; static const char* const EXTENSIONS[] = { - ".mjs", - ".cjs", ".js", ".json", - ".node" + ".node", + ".mjs" }; ModuleWrap::ModuleWrap(Environment* env, diff --git a/src/node.cc b/src/node.cc index 17963d0b11b297..935be9343f0025 100644 --- a/src/node.cc +++ b/src/node.cc @@ -226,7 +226,7 @@ MaybeLocal ExecuteBootstrapper(Environment* env, return scope.EscapeMaybe(result); } -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR int Environment::InitializeInspector( inspector::ParentInspectorHandle* parent_handle) { std::string inspector_path; @@ -833,13 +833,6 @@ int InitializeNodeWithArgs(std::vector* argv, &default_env_options->redirect_warnings); } -#if HAVE_OPENSSL - std::string* openssl_config = &per_process::cli_options->openssl_config; - if (openssl_config->empty()) { - credentials::SafeGetenv("OPENSSL_CONF", openssl_config); - } -#endif - #if !defined(NODE_WITHOUT_NODE_OPTIONS) std::string node_options; diff --git a/src/node.h b/src/node.h index d5c3c2a6671853..cae0673a37f80e 100644 --- a/src/node.h +++ b/src/node.h @@ -260,7 +260,11 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { // flushing. virtual bool FlushForegroundTasks(v8::Isolate* isolate) = 0; virtual void DrainTasks(v8::Isolate* isolate) = 0; - virtual void CancelPendingDelayedTasks(v8::Isolate* isolate) = 0; + + // TODO(addaleax): Remove this, it is unnecessary. + // This would currently be called before `UnregisterIsolate()` but will be + // folded into it in the future. + virtual void CancelPendingDelayedTasks(v8::Isolate* isolate); // This needs to be called between the calls to `Isolate::Allocate()` and // `Isolate::Initialize()`, so that initialization can already start @@ -270,7 +274,8 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { virtual void RegisterIsolate(v8::Isolate* isolate, struct uv_loop_s* loop) = 0; // This needs to be called right before calling `Isolate::Dispose()`. - // This function may only be called once per `Isolate`. + // This function may only be called once per `Isolate`, and discard any + // pending delayed tasks scheduled for that isolate. virtual void UnregisterIsolate(v8::Isolate* isolate) = 0; // The platform should call the passed function once all state associated // with the given isolate has been cleaned up. This can, but does not have to, diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 3405fbb5b45aa4..d2563c0fb5326b 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -6964,30 +6964,19 @@ void TimingSafeEqual(const FunctionCallbackInfo& args) { } void InitCryptoOnce() { - SSL_load_error_strings(); - OPENSSL_no_config(); +#ifndef OPENSSL_IS_BORINGSSL + OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); // --openssl-config=... if (!per_process::cli_options->openssl_config.empty()) { - OPENSSL_load_builtin_modules(); -#ifndef OPENSSL_NO_ENGINE - ENGINE_load_builtin_engines(); -#endif - ERR_clear_error(); - CONF_modules_load_file(per_process::cli_options->openssl_config.c_str(), - nullptr, - CONF_MFLAGS_DEFAULT_SECTION); - int err = ERR_get_error(); - if (0 != err) { - fprintf(stderr, - "openssl config failed: %s\n", - ERR_error_string(err, nullptr)); - CHECK_NE(err, 0); - } + const char* conf = per_process::cli_options->openssl_config.c_str(); + OPENSSL_INIT_set_config_filename(settings, conf); } - SSL_library_init(); - OpenSSL_add_all_algorithms(); + OPENSSL_init_ssl(0, settings); + OPENSSL_INIT_free(settings); + settings = nullptr; +#endif #ifdef NODE_FIPS_MODE /* Override FIPS settings in cnf file, if needed. */ diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index e41e0c1fb6fe1f..0744063e0dc3a9 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -155,7 +155,6 @@ int NodeMainInstance::Run() { RunAtExit(env.get()); per_process::v8_platform.DrainVMTasks(isolate_); - per_process::v8_platform.CancelVMTasks(isolate_); #if defined(LEAK_SANITIZER) __lsan_do_leak_check(); @@ -204,7 +203,7 @@ std::unique_ptr NodeMainInstance::CreateMainEnvironment( // TODO(joyeecheung): when we snapshot the bootstrapped context, // the inspector and diagnostics setup should after after deserialization. -#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM +#if HAVE_INSPECTOR *exit_code = env->InitializeInspector(nullptr); #endif if (*exit_code != 0) { diff --git a/src/node_platform.cc b/src/node_platform.cc index f726382171488c..6e3b4abfee7287 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -285,22 +285,33 @@ void PerIsolatePlatformData::Shutdown() { // effectively deleting the tasks instead of running them. foreground_delayed_tasks_.PopAll(); foreground_tasks_.PopAll(); + scheduled_delayed_tasks_.clear(); - CancelPendingDelayedTasks(); - - ShutdownCbList* copy = new ShutdownCbList(std::move(shutdown_callbacks_)); - flush_tasks_->data = copy; + // Both destroying the scheduled_delayed_tasks_ lists and closing + // flush_tasks_ handle add tasks to the event loop. We keep a count of all + // non-closed handles, and when that reaches zero, we inform any shutdown + // callbacks that the platform is done as far as this Isolate is concerned. + self_reference_ = shared_from_this(); uv_close(reinterpret_cast(flush_tasks_), [](uv_handle_t* handle) { - std::unique_ptr callbacks( - static_cast(handle->data)); - for (const auto& callback : *callbacks) - callback.cb(callback.data); - delete reinterpret_cast(handle); + std::unique_ptr flush_tasks { + reinterpret_cast(handle) }; + PerIsolatePlatformData* platform_data = + static_cast(flush_tasks->data); + platform_data->DecreaseHandleCount(); + platform_data->self_reference_.reset(); }); flush_tasks_ = nullptr; } +void PerIsolatePlatformData::DecreaseHandleCount() { + CHECK_GE(uv_handle_count_, 1); + if (--uv_handle_count_ == 0) { + for (const auto& callback : shutdown_callbacks_) + callback.cb(callback.data); + } +} + NodePlatform::NodePlatform(int thread_pool_size, TracingController* tracing_controller) { if (tracing_controller) { @@ -382,10 +393,6 @@ void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) { delayed->platform_data->DeleteFromScheduledTasks(delayed); } -void PerIsolatePlatformData::CancelPendingDelayedTasks() { - scheduled_delayed_tasks_.clear(); -} - void NodePlatform::DrainTasks(Isolate* isolate) { std::shared_ptr per_isolate = ForIsolate(isolate); @@ -409,12 +416,15 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() { // the delay is non-zero. This should not be a problem in practice. uv_timer_start(&delayed->timer, RunForegroundTask, delay_millis, 0); uv_unref(reinterpret_cast(&delayed->timer)); + uv_handle_count_++; scheduled_delayed_tasks_.emplace_back(delayed.release(), [](DelayedTask* delayed) { uv_close(reinterpret_cast(&delayed->timer), [](uv_handle_t* handle) { - delete static_cast(handle->data); + std::unique_ptr task { + static_cast(handle->data) }; + task->platform_data->DecreaseHandleCount(); }); }); } @@ -454,10 +464,6 @@ bool NodePlatform::FlushForegroundTasks(Isolate* isolate) { return ForIsolate(isolate)->FlushForegroundTasksInternal(); } -void NodePlatform::CancelPendingDelayedTasks(Isolate* isolate) { - ForIsolate(isolate)->CancelPendingDelayedTasks(); -} - bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; } std::shared_ptr @@ -548,4 +554,6 @@ std::queue> TaskQueue::PopAll() { return result; } +void MultiIsolatePlatform::CancelPendingDelayedTasks(Isolate* isolate) {} + } // namespace node diff --git a/src/node_platform.h b/src/node_platform.h index d2eb325c12113e..24f7b337bb8fd7 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -78,12 +78,12 @@ class PerIsolatePlatformData : // posted during flushing of the queue are postponed until the next // flushing. bool FlushForegroundTasksInternal(); - void CancelPendingDelayedTasks(); const uv_loop_t* event_loop() const { return loop_; } private: void DeleteFromScheduledTasks(DelayedTask* task); + void DecreaseHandleCount(); static void FlushTasks(uv_async_t* handle); static void RunForegroundTask(std::unique_ptr task); @@ -95,6 +95,9 @@ class PerIsolatePlatformData : }; typedef std::vector ShutdownCbList; ShutdownCbList shutdown_callbacks_; + // shared_ptr to self to keep this object alive during shutdown. + std::shared_ptr self_reference_; + uint32_t uv_handle_count_ = 1; // 1 = flush_tasks_ uv_loop_t* const loop_; uv_async_t* flush_tasks_ = nullptr; @@ -102,7 +105,7 @@ class PerIsolatePlatformData : TaskQueue foreground_delayed_tasks_; // Use a custom deleter because libuv needs to close the handle first. - typedef std::unique_ptr> + typedef std::unique_ptr DelayedTaskPointer; std::vector scheduled_delayed_tasks_; }; @@ -137,7 +140,6 @@ class NodePlatform : public MultiIsolatePlatform { ~NodePlatform() override = default; void DrainTasks(v8::Isolate* isolate) override; - void CancelPendingDelayedTasks(v8::Isolate* isolate) override; void Shutdown(); // v8::Platform implementation. diff --git a/src/node_postmortem_metadata.cc b/src/node_postmortem_metadata.cc index 05800f79b09ecc..ccb347e95175c1 100644 --- a/src/node_postmortem_metadata.cc +++ b/src/node_postmortem_metadata.cc @@ -27,9 +27,11 @@ HandleWrap::handle_wrap_queue_) \ V(Environment_HandleWrapQueue, head_, ListNode_HandleWrap, \ Environment::HandleWrapQueue::head_) \ + V(ListNode_HandleWrap, prev_, uintptr_t, ListNode::prev_) \ V(ListNode_HandleWrap, next_, uintptr_t, ListNode::next_) \ V(Environment_ReqWrapQueue, head_, ListNode_ReqWrapQueue, \ Environment::ReqWrapQueue::head_) \ + V(ListNode_ReqWrap, prev_, uintptr_t, ListNode::prev_) \ V(ListNode_ReqWrap, next_, uintptr_t, ListNode::next_) extern "C" { diff --git a/src/node_report.cc b/src/node_report.cc index 088c63b9e8402d..ddeb216c82d6bc 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -18,7 +18,6 @@ #include #include #include -#include constexpr int NODE_REPORT_VERSION = 1; constexpr int NANOS_PER_SEC = 1000 * 1000 * 1000; @@ -111,8 +110,7 @@ std::string TriggerNodeReport(Isolate* isolate, } // Check for errors on the file open if (!outfile.is_open()) { - std::cerr << std::endl - << "Failed to open Node.js report file: " << filename; + std::cerr << "\nFailed to open Node.js report file: " << filename; if (env != nullptr && options->report_directory.length() > 0) std::cerr << " directory: " << options->report_directory; @@ -121,7 +119,7 @@ std::string TriggerNodeReport(Isolate* isolate, return ""; } outstream = &outfile; - std::cerr << std::endl << "Writing Node.js report to file: " << filename; + std::cerr << "\nWriting Node.js report to file: " << filename; } WriteNodeReport(isolate, env, message, trigger, filename, *outstream, @@ -132,7 +130,7 @@ std::string TriggerNodeReport(Isolate* isolate, outfile.close(); } - std::cerr << std::endl << "Node.js report completed" << std::endl; + std::cerr << "\nNode.js report completed" << std::endl; return filename; } diff --git a/src/node_v8_platform-inl.h b/src/node_v8_platform-inl.h index e36f0a7d88bea4..ecd8f21d1a2653 100644 --- a/src/node_v8_platform-inl.h +++ b/src/node_v8_platform-inl.h @@ -113,10 +113,6 @@ struct V8Platform { platform_->DrainTasks(isolate); } - inline void CancelVMTasks(v8::Isolate* isolate) { - platform_->CancelPendingDelayedTasks(isolate); - } - inline void StartTracingAgent() { // Attach a new NodeTraceWriter only if this function hasn't been called // before. @@ -150,7 +146,6 @@ struct V8Platform { inline void Initialize(int thread_pool_size) {} inline void Dispose() {} inline void DrainVMTasks(v8::Isolate* isolate) {} - inline void CancelVMTasks(v8::Isolate* isolate) {} inline void StartTracingAgent() { if (!per_process::cli_options->trace_event_categories.empty()) { fprintf(stderr, diff --git a/src/node_version.h b/src/node_version.h index e15bef4f4ff130..138a7b51b9ceec 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -29,7 +29,7 @@ #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/node_worker.cc b/src/node_worker.cc index 3913c51112a021..025b5fed49cbb5 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -8,7 +8,7 @@ #include "util-inl.h" #include "async_wrap-inl.h" -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR #include "inspector/worker_inspector.h" // ParentInspectorHandle #endif @@ -39,7 +39,7 @@ namespace worker { namespace { -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR void WaitForWorkerInspectorToStop(Environment* child) { child->inspector_agent()->WaitForDisconnect(); child->inspector_agent()->Stop(); @@ -82,7 +82,7 @@ Worker::Worker(Environment* env, Number::New(env->isolate(), static_cast(thread_id_))) .Check(); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR inspector_parent_handle_ = env->inspector_agent()->GetParentHandle(thread_id_, url); #endif @@ -148,8 +148,6 @@ class WorkerThreadData { w_->isolate_ = nullptr; } - w_->platform_->CancelPendingDelayedTasks(isolate); - bool platform_finished = false; isolate_data_.reset(); @@ -193,7 +191,7 @@ void Worker::Run() { Locker locker(isolate_); Isolate::Scope isolate_scope(isolate_); SealHandleScope outer_seal(isolate_); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR bool inspector_started = false; #endif @@ -225,7 +223,7 @@ void Worker::Run() { env_->stop_sub_worker_contexts(); env_->RunCleanup(); RunAtExit(env_.get()); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR if (inspector_started) WaitForWorkerInspectorToStop(env_.get()); #endif @@ -270,7 +268,7 @@ void Worker::Run() { if (is_stopped()) return; { env_->InitializeDiagnostics(); -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR env_->InitializeInspector(inspector_parent_handle_.release()); inspector_started = true; #endif diff --git a/src/node_worker.h b/src/node_worker.h index ffc4f19882cc26..77f68801e7c247 100644 --- a/src/node_worker.h +++ b/src/node_worker.h @@ -65,7 +65,7 @@ class Worker : public AsyncWrap { bool start_profiler_idle_notifier_; uv_thread_t tid_; -#if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR +#if HAVE_INSPECTOR std::unique_ptr inspector_parent_handle_; #endif diff --git a/test/cctest/test_node_postmortem_metadata.cc b/test/cctest/test_node_postmortem_metadata.cc index 79b766939b9d0d..f33d40eb5c23fe 100644 --- a/test/cctest/test_node_postmortem_metadata.cc +++ b/test/cctest/test_node_postmortem_metadata.cc @@ -19,8 +19,10 @@ extern uintptr_t extern uintptr_t nodedbg_offset_Environment__req_wrap_queue___Environment_ReqWrapQueue; extern uintptr_t nodedbg_offset_ExternalString__data__uintptr_t; +extern uintptr_t nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t; extern uintptr_t nodedbg_offset_ListNode_ReqWrap__next___uintptr_t; extern uintptr_t nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue; +extern uintptr_t nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t; extern uintptr_t nodedbg_offset_ListNode_HandleWrap__next___uintptr_t; extern uintptr_t nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue; @@ -129,6 +131,12 @@ TEST_F(DebugSymbolsTest, HandleWrapList) { const Argv argv; Env env{handle_scope, argv}; + auto queue = reinterpret_cast((*env)->handle_wrap_queue()); + auto head = queue + + nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap; + auto tail = head + nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t; + tail = *reinterpret_cast(tail); + uv_tcp_t handle; auto obj_template = v8::FunctionTemplate::New(isolate_); @@ -140,16 +148,12 @@ TEST_F(DebugSymbolsTest, HandleWrapList) { .ToLocalChecked(); TestHandleWrap obj(*env, object, &handle); - auto queue = reinterpret_cast((*env)->handle_wrap_queue()); - auto head = queue + - nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap; - auto next = - head + nodedbg_offset_ListNode_HandleWrap__next___uintptr_t; - next = *reinterpret_cast(next); + auto last = tail + nodedbg_offset_ListNode_HandleWrap__next___uintptr_t; + last = *reinterpret_cast(last); auto expected = reinterpret_cast(&obj); - auto calculated = next - - nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap; + auto calculated = + last - nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap; EXPECT_EQ(expected, calculated); obj.persistent().Reset(); // ~HandleWrap() expects an empty handle. @@ -160,6 +164,13 @@ TEST_F(DebugSymbolsTest, ReqWrapList) { const Argv argv; Env env{handle_scope, argv}; + auto queue = reinterpret_cast((*env)->req_wrap_queue()); + auto head = + queue + + nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue; + auto tail = head + nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t; + tail = *reinterpret_cast(tail); + auto obj_template = v8::FunctionTemplate::New(isolate_); obj_template->InstanceTemplate()->SetInternalFieldCount(1); @@ -174,16 +185,12 @@ TEST_F(DebugSymbolsTest, ReqWrapList) { // ARM64 CI machinies. for (auto it : *(*env)->req_wrap_queue()) (void) ⁢ - auto queue = reinterpret_cast((*env)->req_wrap_queue()); - auto head = queue + - nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue; - auto next = - head + nodedbg_offset_ListNode_ReqWrap__next___uintptr_t; - next = *reinterpret_cast(next); + auto last = tail + nodedbg_offset_ListNode_ReqWrap__next___uintptr_t; + last = *reinterpret_cast(last); auto expected = reinterpret_cast(&obj); auto calculated = - next - nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue; + last - nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue; EXPECT_EQ(expected, calculated); obj.Dispatched(); diff --git a/test/common/index.js b/test/common/index.js index 00ebd283a0c3e9..98a26872223cb9 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -651,12 +651,6 @@ function skipIfInspectorDisabled() { } } -function skipIfInspectorEnabled() { - if (process.features.inspector) { - skip('V8 inspector is enabled'); - } -} - function skipIfReportDisabled() { if (!process.config.variables.node_report) { skip('Diagnostic reporting is disabled'); @@ -789,7 +783,6 @@ module.exports = { skipIf32Bits, skipIfEslintMissing, skipIfInspectorDisabled, - skipIfInspectorEnabled, skipIfReportDisabled, skipIfWorker, diff --git a/test/es-module/test-esm-loader-modulemap.js b/test/es-module/test-esm-loader-modulemap.js index 5493c6c47c9643..70f5a1015907a2 100644 --- a/test/es-module/test-esm-loader-modulemap.js +++ b/test/es-module/test-esm-loader-modulemap.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --expose-internals --experimental-modules // This test ensures that the type checking of ModuleMap throws // errors appropriately diff --git a/test/es-module/test-esm-no-extension.js b/test/es-module/test-esm-no-extension.js index e3f30d6e3c2808..81b8e5b4327ad0 100644 --- a/test/es-module/test-esm-no-extension.js +++ b/test/es-module/test-esm-no-extension.js @@ -15,11 +15,6 @@ const child = spawn(process.execPath, [ entry ]); -let stderr = ''; -child.stderr.setEncoding('utf8'); -child.stderr.on('data', (data) => { - stderr += data; -}); let stdout = ''; child.stdout.setEncoding('utf8'); child.stdout.on('data', (data) => { @@ -29,6 +24,4 @@ child.on('close', common.mustCall((code, signal) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); assert.strictEqual(stdout, 'executed\n'); - assert.strictEqual(stderr, `(node:${child.pid}) ` + - 'ExperimentalWarning: The ESM module loader is experimental.\n'); })); diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs index 0c5e1ac04ad1a8..59d54cbf63dc79 100644 --- a/test/es-module/test-esm-specifiers.mjs +++ b/test/es-module/test-esm-specifiers.mjs @@ -1,5 +1,5 @@ // Flags: --experimental-modules --es-module-specifier-resolution=node -import { mustNotCall } from '../common'; +import { mustNotCall } from '../common/index.mjs'; import assert from 'assert'; // commonJS index.js @@ -14,8 +14,8 @@ assert.strictEqual(commonjs, 'commonjs'); assert.strictEqual(module, 'module'); assert.strictEqual(success, 'success'); assert.strictEqual(explicit, 'esm'); -assert.strictEqual(implicit, 'esm'); -assert.strictEqual(implicitModule, 'esm'); +assert.strictEqual(implicit, 'cjs'); +assert.strictEqual(implicitModule, 'cjs'); async function main() { try { diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js index 5d7af588fd65b7..06db4db1581b44 100644 --- a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js @@ -1 +1 @@ -export default 'nope'; +export default 'cjs'; diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 939658a3b0553f..c963630f5d32ab 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -92,7 +92,6 @@ if (common.isMainThread) { expectedModules.add('NativeModule internal/streams/state'); expectedModules.add('NativeModule internal/worker'); expectedModules.add('NativeModule internal/worker/io'); - expectedModules.add('NativeModule module'); expectedModules.add('NativeModule stream'); expectedModules.add('NativeModule worker_threads'); } diff --git a/test/parallel/test-coverage-with-inspector-disabled.js b/test/parallel/test-coverage-with-inspector-disabled.js index 0b0c2aea43fa60..f2ba070859527e 100644 --- a/test/parallel/test-coverage-with-inspector-disabled.js +++ b/test/parallel/test-coverage-with-inspector-disabled.js @@ -1,7 +1,9 @@ 'use strict'; const common = require('../common'); -common.skipIfInspectorEnabled(); +if (process.features.inspector) { + common.skip('V8 inspector is enabled'); +} const fixtures = require('../common/fixtures'); const assert = require('assert'); diff --git a/test/parallel/test-fs-close-errors.js b/test/parallel/test-fs-close-errors.js index 42d990410f9848..6168d5c20ab8e5 100644 --- a/test/parallel/test-fs-close-errors.js +++ b/test/parallel/test-fs-close-errors.js @@ -17,3 +17,19 @@ const fs = require('fs'); assert.throws(() => fs.close(input), errObj); assert.throws(() => fs.closeSync(input), errObj); }); + +{ + // Test error when cb is not a function + const fd = fs.openSync(__filename, 'r'); + + const errObj = { + code: 'ERR_INVALID_CALLBACK', + name: 'TypeError' + }; + + ['', false, null, {}, []].forEach((input) => { + assert.throws(() => fs.close(fd, input), errObj); + }); + + fs.closeSync(fd); +} diff --git a/test/parallel/test-internal-module-map-asserts.js b/test/parallel/test-internal-module-map-asserts.js index 4563fc605e0792..614da43aba0acb 100644 --- a/test/parallel/test-internal-module-map-asserts.js +++ b/test/parallel/test-internal-module-map-asserts.js @@ -12,7 +12,7 @@ const ModuleMap = require('internal/modules/esm/module_map'); code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: /^The "url" argument must be of type string/ - }, 15); + }, 12); const moduleMap = new ModuleMap(); @@ -21,7 +21,7 @@ const ModuleMap = require('internal/modules/esm/module_map'); // but I think it's useless, and was not simple to mock... const job = undefined; - [{}, [], true, 1, () => {}].forEach((value) => { + [{}, [], true, 1].forEach((value) => { assert.throws(() => moduleMap.get(value), errorReg); assert.throws(() => moduleMap.has(value), errorReg); assert.throws(() => moduleMap.set(value, job), errorReg); @@ -34,11 +34,11 @@ const ModuleMap = require('internal/modules/esm/module_map'); code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: /^The "job" argument must be of type ModuleJob/ - }, 5); + }, 4); const moduleMap = new ModuleMap(); - [{}, [], true, 1, () => {}].forEach((value) => { + [{}, [], true, 1].forEach((value) => { assert.throws(() => moduleMap.set('', value), errorReg); }); } diff --git a/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js b/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js index 56dfe2ec41ab3a..ce8410f6dd3d75 100644 --- a/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js +++ b/test/parallel/test-worker-sharedarraybuffer-from-worker-thread.js @@ -5,19 +5,24 @@ const assert = require('assert'); const { Worker } = require('worker_threads'); // Regression test for https://github.com/nodejs/node/issues/28777 -// Make sure that SharedArrayBuffers created in Worker threads are accessible -// after the creating thread ended. +// Make sure that SharedArrayBuffers and transferred ArrayBuffers created in +// Worker threads are accessible after the creating thread ended. -const w = new Worker(` -const { parentPort } = require('worker_threads'); -const sharedArrayBuffer = new SharedArrayBuffer(4); -parentPort.postMessage(sharedArrayBuffer); -`, { eval: true }); +for (const ctor of ['ArrayBuffer', 'SharedArrayBuffer']) { + const w = new Worker(` + const { parentPort } = require('worker_threads'); + const arrayBuffer = new ${ctor}(4); + parentPort.postMessage( + arrayBuffer, + '${ctor}' === 'SharedArrayBuffer' ? [] : [arrayBuffer]); + `, { eval: true }); -let sharedArrayBuffer; -w.once('message', common.mustCall((message) => sharedArrayBuffer = message)); -w.once('exit', common.mustCall(() => { - const uint8array = new Uint8Array(sharedArrayBuffer); - uint8array[0] = 42; - assert.deepStrictEqual(uint8array, new Uint8Array([42, 0, 0, 0])); -})); + let arrayBuffer; + w.once('message', common.mustCall((message) => arrayBuffer = message)); + w.once('exit', common.mustCall(() => { + assert.strictEqual(arrayBuffer.constructor.name, ctor); + const uint8array = new Uint8Array(arrayBuffer); + uint8array[0] = 42; + assert.deepStrictEqual(uint8array, new Uint8Array([42, 0, 0, 0])); + })); +} diff --git a/test/testpy/__init__.py b/test/testpy/__init__.py index 9c70e18d6a1291..c89ab6e8b576f4 100644 --- a/test/testpy/__init__.py +++ b/test/testpy/__init__.py @@ -29,6 +29,7 @@ import os import re from functools import reduce +from io import open FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") @@ -56,7 +57,7 @@ def GetName(self): def GetCommand(self): result = [self.config.context.GetVm(self.arch, self.mode)] - source = open(self.file).read() + source = open(self.file, encoding='utf8').read() flags_match = FLAGS_PATTERN.search(source) if flags_match: flags = flags_match.group(1).strip().split() diff --git a/tools/test.py b/tools/test.py index 878e2bef35da46..04babded24b590 100755 --- a/tools/test.py +++ b/tools/test.py @@ -45,6 +45,7 @@ import errno import copy +from io import open from os.path import join, dirname, abspath, basename, isdir, exists from datetime import datetime try: @@ -733,8 +734,8 @@ def disableCoreFiles(): ) os.close(fd_out) os.close(fd_err) - output = open(outname).read() - errors = open(errname).read() + output = open(outname, encoding='utf8').read() + errors = open(errname, encoding='utf8').read() CheckedUnlink(outname) CheckedUnlink(errname) diff --git a/vcbuild.bat b/vcbuild.bat index 7613bd8b5ab129..5ddc04aeb25a4a 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -236,26 +236,26 @@ if %target_arch%==x64 if %msvs_host_arch%==amd64 set vcvarsall_arg=amd64 @rem also if both are x86 if %target_arch%==x86 if %msvs_host_arch%==x86 set vcvarsall_arg=x86 -@rem Look for Visual Studio 2017 -:vs-set-2017 -if defined target_env if "%target_env%" NEQ "vs2017" goto vs-set-2019 -echo Looking for Visual Studio 2017 -call tools\msvs\vswhere_usability_wrapper.cmd "[15.0,16.0)" -if "_%VCINSTALLDIR%_" == "__" goto msbuild-not-found +@rem Look for Visual Studio 2019 +:vs-set-2019 +if defined target_env if "%target_env%" NEQ "vs2019" goto vs-set-2017 +echo Looking for Visual Studio 2019 +call tools\msvs\vswhere_usability_wrapper.cmd "[16.0,17.0)" +if "_%VCINSTALLDIR%_" == "__" goto vs-set-2017 if defined msi ( - echo Looking for WiX installation for Visual Studio 2017... + echo Looking for WiX installation for Visual Studio 2019... if not exist "%WIX%\SDK\VS2017" ( - echo Failed to find WiX install for Visual Studio 2017 - echo VS2017 support for WiX is only present starting at version 3.11 - goto msbuild-not-found + echo Failed to find WiX install for Visual Studio 2019 + echo VS2019 support for WiX is only present starting at version 3.11 + goto vs-set-2017 ) if not exist "%VCINSTALLDIR%\..\MSBuild\Microsoft\WiX" ( - echo Failed to find the WiX Toolset Visual Studio 2017 Extension - goto msbuild-not-found + echo Failed to find the WiX Toolset Visual Studio 2019 Extension + goto vs-set-2017 ) ) -@rem check if VS2017 is already setup, and for the requested arch -if "_%VisualStudioVersion%_" == "_15.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2017 +@rem check if VS2019 is already setup, and for the requested arch +if "_%VisualStudioVersion%_" == "_16.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2019 @rem need to clear VSINSTALLDIR for vcvarsall to work as expected set "VSINSTALLDIR=" @rem prevent VsDevCmd.bat from changing the current working directory @@ -263,34 +263,34 @@ set "VSCMD_START_DIR=%CD%" set vcvars_call="%VCINSTALLDIR%\Auxiliary\Build\vcvarsall.bat" %vcvarsall_arg% echo calling: %vcvars_call% call %vcvars_call% -if errorlevel 1 goto msbuild-not-found +if errorlevel 1 goto vs-set-2017 if defined DEBUG_HELPER @ECHO ON -:found_vs2017 +:found_vs2019 echo Found MSVS version %VisualStudioVersion% -set GYP_MSVS_VERSION=2017 -set PLATFORM_TOOLSET=v141 +set GYP_MSVS_VERSION=2019 +set PLATFORM_TOOLSET=v142 goto msbuild-found -@rem Look for Visual Studio 2019 -:vs-set-2019 -if defined target_env if "%target_env%" NEQ "vs2019" goto msbuild-not-found -echo Looking for Visual Studio 2019 -call tools\msvs\vswhere_usability_wrapper.cmd "[16.0,17.0)" +@rem Look for Visual Studio 2017 +:vs-set-2017 +if defined target_env if "%target_env%" NEQ "vs2017" goto msbuild-not-found +echo Looking for Visual Studio 2017 +call tools\msvs\vswhere_usability_wrapper.cmd "[15.0,16.0)" if "_%VCINSTALLDIR%_" == "__" goto msbuild-not-found if defined msi ( - echo Looking for WiX installation for Visual Studio 2019... + echo Looking for WiX installation for Visual Studio 2017... if not exist "%WIX%\SDK\VS2017" ( - echo Failed to find WiX install for Visual Studio 2019 - echo VS2019 support for WiX is only present starting at version 3.11 + echo Failed to find WiX install for Visual Studio 2017 + echo VS2017 support for WiX is only present starting at version 3.11 goto msbuild-not-found ) if not exist "%VCINSTALLDIR%\..\MSBuild\Microsoft\WiX" ( - echo Failed to find the WiX Toolset Visual Studio 2019 Extension + echo Failed to find the WiX Toolset Visual Studio 2017 Extension goto msbuild-not-found ) ) -@rem check if VS2019 is already setup, and for the requested arch -if "_%VisualStudioVersion%_" == "_16.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2019 +@rem check if VS2017 is already setup, and for the requested arch +if "_%VisualStudioVersion%_" == "_15.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%target_arch%_" goto found_vs2017 @rem need to clear VSINSTALLDIR for vcvarsall to work as expected set "VSINSTALLDIR=" @rem prevent VsDevCmd.bat from changing the current working directory @@ -300,10 +300,10 @@ echo calling: %vcvars_call% call %vcvars_call% if errorlevel 1 goto msbuild-not-found if defined DEBUG_HELPER @ECHO ON -:found_vs2019 +:found_vs2017 echo Found MSVS version %VisualStudioVersion% -set GYP_MSVS_VERSION=2019 -set PLATFORM_TOOLSET=v142 +set GYP_MSVS_VERSION=2017 +set PLATFORM_TOOLSET=v141 goto msbuild-found :msbuild-not-found