diff --git a/BUILDING.md b/BUILDING.md index a4a00a9f1ffe49..a7dc040f5f385e 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -204,7 +204,7 @@ For use of AVX2, * nasm version 2.10 or higher in Windows Please refer to - https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html for details. + for details. If compiling without one of the above, use `configure` with the `--openssl-no-asm` flag. Otherwise, `configure` will fail. @@ -277,7 +277,7 @@ $ make -j4 If you run into a `No module named 'distutils.spawn'` error when executing `./configure`, please try `python3 -m pip install --upgrade setuptools` or `sudo apt install python3-distutils -y`. -For more information, see https://github.com/nodejs/node/issues/30189. +For more information, see . The `-j4` option will cause `make` to run 4 simultaneous compilation jobs which may reduce build time. For more information, see the diff --git a/CHANGELOG.md b/CHANGELOG.md index 01427cc73bf993..4cd6fceaddbfcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,8 @@ release. -14.0.0
+14.1.0
+14.0.0
13.12.0
diff --git a/README.md b/README.md index 5b42f731b791e5..af3a57ccaac992 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

-Each directory name and filename contains a date (in UTC time) and the commit +Each directory name and filename contains a date (in UTC) and the commit SHA at the HEAD of the release. #### API Documentation @@ -331,6 +332,8 @@ For information about the governance of the Node.js project, see **João Reis** <reis@janeasystems.com> * [joyeecheung](https://github.com/joyeecheung) - **Joyee Cheung** <joyeec9h3@gmail.com> (she/her) +* [juanarbol](https://github.com/juanarbol) - +**Juan José Arboleda** <soyjuanarbol@gmail.com> (he/him) * [JungMinu](https://github.com/JungMinu) - **Minwoo Jung** <nodecorelab@gmail.com> (he/him) * [kfarnung](https://github.com/kfarnung) - diff --git a/SECURITY.md b/SECURITY.md index 3196055ccb78e5..64714043db7e3b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,8 +11,7 @@ handling your submission. After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement, and may ask for additional information or guidance surrounding the reported -issue. These updates will be sent at least every five days; in practice, this -is more likely to be every 24-48 hours. +issue. ### Node.js Bug Bounty Program diff --git a/benchmark/streams/writable-manywrites.js b/benchmark/streams/writable-manywrites.js index e4ae9ab91e5f4a..025a5017ee6446 100644 --- a/benchmark/streams/writable-manywrites.js +++ b/benchmark/streams/writable-manywrites.js @@ -7,11 +7,12 @@ const bench = common.createBenchmark(main, { n: [2e6], sync: ['yes', 'no'], writev: ['yes', 'no'], - callback: ['yes', 'no'] + callback: ['yes', 'no'], + len: [1024, 32 * 1024] }); -function main({ n, sync, writev, callback }) { - const b = Buffer.allocUnsafe(1024); +function main({ n, sync, writev, callback, len }) { + const b = Buffer.allocUnsafe(len); const s = new Writable(); sync = sync === 'yes'; diff --git a/common.gypi b/common.gypi index 040d0d1593eb15..fec140bbae983b 100644 --- a/common.gypi +++ b/common.gypi @@ -35,7 +35,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.30', + 'v8_embedder_string': '-node.32', ##### V8 defaults for Node.js ##### diff --git a/deps/openssl/config/archs/BSD-x86/asm/configdata.pm b/deps/openssl/config/archs/BSD-x86/asm/configdata.pm index 08ca80d5165130..e2c6b91ad4322a 100644 --- a/deps/openssl/config/archs/BSD-x86/asm/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7413,6 +7413,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h index c1217da5225db5..8906bbcd1667c1 100644 --- a/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86" -#define DATE "built on: Tue Mar 31 13:06:25 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:30 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm b/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm index 5ee9dadffd58ce..cde9ab3f9cad77 100644 --- a/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7413,6 +7413,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h index 060858b510af1a..9ae71b203b5c9c 100644 --- a/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86" -#define DATE "built on: Tue Mar 31 13:06:27 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:32 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm b/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm index cb7ef8b1d0dc9c..5569ba1f1ef9c6 100644 --- a/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7363,6 +7363,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h index da7a46d286147f..0617bee2e0ff83 100644 --- a/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86" -#define DATE "built on: Tue Mar 31 13:06:30 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:34 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm index 663c00a7885252..bae66a2b0d362c 100644 --- a/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h index 28ea564386bb3e..4fa13f787cd0d3 100644 --- a/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86_64" -#define DATE "built on: Tue Mar 31 13:06:31 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:35 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm index 608f5cfd9124f6..f7a112c24ff188 100644 --- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h index 304f2aeec37ea4..e3d1b2ac9e4093 100644 --- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86_64" -#define DATE "built on: Tue Mar 31 13:06:37 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:40 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm index 830dd61c38c9e8..71aac6079d34a6 100644 --- a/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm +++ b/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "BSD-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h index d0b6a3b33d2127..21c7eb8a7ea97d 100644 --- a/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: BSD-x86_64" -#define DATE "built on: Tue Mar 31 13:06:43 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:45 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm b/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm index bc6472d789ce3f..2971043ad9180a 100644 --- a/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm @@ -115,8 +115,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -132,7 +132,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x55e4d97a23c8)", + RANLIB => "CODE(0x555663f9f6e8)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c vpaes-x86.s aesni-x86.s", @@ -7460,6 +7460,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h index c5f019621159f6..ce39e2899efdb8 100644 --- a/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:08:59 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:38 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm b/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm index 567fd89b831f3b..7cb55073eb56a0 100644 --- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm @@ -115,8 +115,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -132,7 +132,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x55e7fe7b8518)", + RANLIB => "CODE(0x557555fd4548)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c vpaes-x86.s aesni-x86.s", @@ -7460,6 +7460,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h index 6c678de053103a..91ea9162d31cac 100644 --- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:09:01 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:40 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm index 38463db00b925e..88ac450625e93a 100644 --- a/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm @@ -114,8 +114,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -131,7 +131,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x56297fab3cf8)", + RANLIB => "CODE(0x55b7cbf3ba68)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c", @@ -7410,6 +7410,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h index 42e833d4987ca6..13dfc8011a07c9 100644 --- a/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:09:04 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:42 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm index a2cc3195c62ea8..dbeb526a5afa98 100644 --- a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm @@ -113,8 +113,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN64-ARM", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -128,7 +128,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x55d021518948)", + RANLIB => "CODE(0x561bd9d97ee8)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/50-win-onecore.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c", @@ -7404,6 +7404,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h index 8d6831636e9cd7..c10c09b484eeea 100644 --- a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: VC-WIN64-ARM" -#define DATE "built on: Tue Mar 31 13:09:05 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:43 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm index b86898557c11d6..88152c050df8df 100644 --- a/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm @@ -116,8 +116,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN64A", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -133,7 +133,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x5636e84e0f08)", + RANLIB => "CODE(0x5647ca1193c8)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c vpaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s", @@ -7517,6 +7517,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h index 83bab9cf6b64be..af137fbaf4057b 100644 --- a/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:08:44 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:25 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm index b3fe1077ab5899..0685aba7d91e61 100644 --- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm @@ -116,8 +116,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN64A", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -133,7 +133,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x55c9eeaa7548)", + RANLIB => "CODE(0x55fd09262448)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c vpaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s", @@ -7517,6 +7517,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h index 5604bc0c8d4d58..bf0778567f4261 100644 --- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:08:50 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:31 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm index e290ef9ba0b04f..7163514b940850 100644 --- a/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm +++ b/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm @@ -115,8 +115,8 @@ our %config = ( sourcedir => ".", target => "VC-WIN64A", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -132,7 +132,7 @@ our %target = ( LDFLAGS => "/nologo /debug", MT => "mt", MTFLAGS => "-nologo", - RANLIB => "CODE(0x55e2b213e978)", + RANLIB => "CODE(0x55d89d717d18)", RC => "rc", _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/10-main.conf", "Configurations/shared-info.pl" ], aes_asm_src => "aes_core.c aes_cbc.c", @@ -7412,6 +7412,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h index 25d909fedcd60a..f7d39297a9d538 100644 --- a/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: " -#define DATE "built on: Tue Mar 31 13:08:57 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:37 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix-gcc/asm/configdata.pm b/deps/openssl/config/archs/aix-gcc/asm/configdata.pm index e215fe2c64caee..5e4cd5c0aab624 100644 --- a/deps/openssl/config/archs/aix-gcc/asm/configdata.pm +++ b/deps/openssl/config/archs/aix-gcc/asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7434,6 +7434,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/aix-gcc/asm/crypto/buildinf.h index 1bf4b0c91391ac..667b3ca4f1c370 100644 --- a/deps/openssl/config/archs/aix-gcc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix-gcc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix-gcc" -#define DATE "built on: Tue Mar 31 13:06:13 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:20 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/aix-gcc/asm_avx2/configdata.pm index ee23e92155abb4..2478703e1f6320 100644 --- a/deps/openssl/config/archs/aix-gcc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/aix-gcc/asm_avx2/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7434,6 +7434,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/aix-gcc/asm_avx2/crypto/buildinf.h index caee112a51705c..58ce87ebdd9a8f 100644 --- a/deps/openssl/config/archs/aix-gcc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix-gcc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix-gcc" -#define DATE "built on: Tue Mar 31 13:06:15 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:22 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/aix-gcc/no-asm/configdata.pm index d8b9a02b58d791..fa2542f6f7f844 100644 --- a/deps/openssl/config/archs/aix-gcc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/aix-gcc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7380,6 +7380,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/aix-gcc/no-asm/crypto/buildinf.h index 7700603f9c6072..52e8166985ad74 100644 --- a/deps/openssl/config/archs/aix-gcc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix-gcc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix-gcc" -#define DATE "built on: Tue Mar 31 13:06:17 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:23 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix64-gcc/asm/configdata.pm b/deps/openssl/config/archs/aix64-gcc/asm/configdata.pm index b1f37dd0e2fb58..cd41ec80d1ffcf 100644 --- a/deps/openssl/config/archs/aix64-gcc/asm/configdata.pm +++ b/deps/openssl/config/archs/aix64-gcc/asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7452,6 +7452,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix64-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc/asm/crypto/buildinf.h index bf1dea5cbf71ef..643ee46d44519c 100644 --- a/deps/openssl/config/archs/aix64-gcc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix64-gcc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix64-gcc" -#define DATE "built on: Tue Mar 31 13:06:19 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:25 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix64-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/aix64-gcc/asm_avx2/configdata.pm index 85a65040b9139d..da22ab7abdb422 100644 --- a/deps/openssl/config/archs/aix64-gcc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/aix64-gcc/asm_avx2/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7452,6 +7452,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix64-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc/asm_avx2/crypto/buildinf.h index 5ebc4866787eb9..8a8695172bdaaf 100644 --- a/deps/openssl/config/archs/aix64-gcc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix64-gcc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix64-gcc" -#define DATE "built on: Tue Mar 31 13:06:21 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:27 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/aix64-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/aix64-gcc/no-asm/configdata.pm index 5d2193f6036eff..936675844138cf 100644 --- a/deps/openssl/config/archs/aix64-gcc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/aix64-gcc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "aix64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7380,6 +7380,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/aix64-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc/no-asm/crypto/buildinf.h index 0164f65785626d..bf9bd49b324c41 100644 --- a/deps/openssl/config/archs/aix64-gcc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/aix64-gcc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: aix64-gcc" -#define DATE "built on: Tue Mar 31 13:06:23 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:28 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm index b3c3e1c8afd567..a1fc1ab0e21672 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm +++ b/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "darwin-i386-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7408,6 +7408,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h index 88846892fcea2b..0e279fa03d0d04 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin-i386-cc" -#define DATE "built on: Tue Mar 31 13:06:57 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:57 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm index 92089136fa7317..49da9df5ba50ac 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "darwin-i386-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7408,6 +7408,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h index f1ca76d4d22c98..48b19f2a62aa0c 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin-i386-cc" -#define DATE "built on: Tue Mar 31 13:07:00 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:59 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm index 2cc2a0942d2e2f..2c457c5cffc0c5 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "darwin-i386-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7358,6 +7358,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h index 46c7b22f94f618..e3fca2397cc7f9 100644 --- a/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin-i386-cc" -#define DATE "built on: Tue Mar 31 13:07:02 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:02 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm index 0508addbfb9028..0323e8891f9049 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "darwin64-x86_64-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7476,6 +7476,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h index 435e112c225f32..ef775454948310 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin64-x86_64-cc" -#define DATE "built on: Tue Mar 31 13:06:44 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:47 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm index 28e2afa0405d4c..ef6bab0fa6569f 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "darwin64-x86_64-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7476,6 +7476,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h index f57777e0182e75..e51b17fc4afb6f 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin64-x86_64-cc" -#define DATE "built on: Tue Mar 31 13:06:50 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:51 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm index d6178f690faf12..da6f564d23da0c 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "darwin64-x86_64-cc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7358,6 +7358,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h index 3f9061e9182b39..8219a109e06583 100644 --- a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: darwin64-x86_64-cc" -#define DATE "built on: Tue Mar 31 13:06:56 2020 UTC" +#define DATE "built on: Tue Apr 21 13:28:56 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm b/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm index 87970f636ee3e3..b5e9d18a4cbea7 100644 --- a/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-aarch64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7417,6 +7417,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h index f6403bc170b2b1..6479d9cf084b05 100644 --- a/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-aarch64" -#define DATE "built on: Tue Mar 31 13:07:04 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:03 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm index 8ec96f7608fe44..4c89d33ad1b784 100644 --- a/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-aarch64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7417,6 +7417,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h index 1706b65541668c..b8787fef6970fb 100644 --- a/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-aarch64" -#define DATE "built on: Tue Mar 31 13:07:06 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:05 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm b/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm index 2b55760f8ce3b2..5125170f571c6b 100644 --- a/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-aarch64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7383,6 +7383,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h index f48903bda838a5..c592d53e84e5da 100644 --- a/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-aarch64" -#define DATE "built on: Tue Mar 31 13:07:08 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:07 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-armv4/asm/configdata.pm b/deps/openssl/config/archs/linux-armv4/asm/configdata.pm index e363ad088ac90d..38f4e239e52990 100644 --- a/deps/openssl/config/archs/linux-armv4/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-armv4/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-armv4", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7414,6 +7414,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h index 8b54c08b597490..f899ea4fcc39ef 100644 --- a/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-armv4" -#define DATE "built on: Tue Mar 31 13:07:10 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:08 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm index 4baa86c1bc3a17..d1a4696ff0b844 100644 --- a/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-armv4", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7414,6 +7414,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h index 0a1cfb5af65396..2a707b15293df3 100644 --- a/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-armv4" -#define DATE "built on: Tue Mar 31 13:07:12 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:10 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm b/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm index 9d3f8edad4d5e8..1d593fbfe38a73 100644 --- a/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-armv4", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7383,6 +7383,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h index b408fbceb5a6fe..c40dc3bcc88fb8 100644 --- a/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-armv4" -#define DATE "built on: Tue Mar 31 13:07:15 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:12 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-elf/asm/configdata.pm b/deps/openssl/config/archs/linux-elf/asm/configdata.pm index 52cc1f512470c6..a80e71e4f4a71c 100644 --- a/deps/openssl/config/archs/linux-elf/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-elf/asm/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-elf", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7433,6 +7433,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h index ff8d7e208faf16..c471b16f716f74 100644 --- a/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-elf" -#define DATE "built on: Tue Mar 31 13:07:16 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:13 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm index 502c6b3e860bcb..e7c10a1cef796d 100644 --- a/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-elf", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7433,6 +7433,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h index eca89be75df62c..57ad9b8f411c74 100644 --- a/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-elf" -#define DATE "built on: Tue Mar 31 13:07:19 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:15 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm b/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm index 90fb20dc6e8cc9..428ba35f579ecb 100644 --- a/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-elf", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7382,6 +7382,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h index 1c29f7b8db2b8c..23a4508342ad5e 100644 --- a/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-elf" -#define DATE "built on: Tue Mar 31 13:07:22 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:17 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc/asm/configdata.pm b/deps/openssl/config/archs/linux-ppc/asm/configdata.pm index 9ffd0d94f2b8a0..4c1bcb3f95609f 100644 --- a/deps/openssl/config/archs/linux-ppc/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7437,6 +7437,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc/asm/crypto/buildinf.h index 8d2f93f288559e..cb44914dd64005 100644 --- a/deps/openssl/config/archs/linux-ppc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc" -#define DATE "built on: Tue Mar 31 13:07:51 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:40 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-ppc/asm_avx2/configdata.pm index 151da7ad6f1d44..61e0463f5e62c0 100644 --- a/deps/openssl/config/archs/linux-ppc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7437,6 +7437,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc/asm_avx2/crypto/buildinf.h index d4badd62c4bdf7..b06edc3d7d44fd 100644 --- a/deps/openssl/config/archs/linux-ppc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc" -#define DATE "built on: Tue Mar 31 13:07:53 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:42 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc/no-asm/configdata.pm b/deps/openssl/config/archs/linux-ppc/no-asm/configdata.pm index b76936f817ebd0..2a10b1bba9ec48 100644 --- a/deps/openssl/config/archs/linux-ppc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7383,6 +7383,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc/no-asm/crypto/buildinf.h index cd9f1386d1172f..002eddcba2880d 100644 --- a/deps/openssl/config/archs/linux-ppc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc" -#define DATE "built on: Tue Mar 31 13:07:55 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:44 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64/asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64/asm/configdata.pm index dc2a11c290559c..52394a0961e477 100644 --- a/deps/openssl/config/archs/linux-ppc64/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7456,6 +7456,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64/asm/crypto/buildinf.h index 7a0f24d3f79d1d..3d95753bf02679 100644 --- a/deps/openssl/config/archs/linux-ppc64/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64" -#define DATE "built on: Tue Mar 31 13:07:57 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:45 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-ppc64/asm_avx2/configdata.pm index 5a400521b6c608..f1b96bbe74d80b 100644 --- a/deps/openssl/config/archs/linux-ppc64/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7456,6 +7456,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64/asm_avx2/crypto/buildinf.h index 0ca1c74d67b723..1ce61a43114354 100644 --- a/deps/openssl/config/archs/linux-ppc64/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64" -#define DATE "built on: Tue Mar 31 13:07:59 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:47 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64/no-asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64/no-asm/configdata.pm index 880d6d0455672b..de71bb6e5a9173 100644 --- a/deps/openssl/config/archs/linux-ppc64/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64/no-asm/crypto/buildinf.h index 1d7d48e4df4c82..a07f6603043d98 100644 --- a/deps/openssl/config/archs/linux-ppc64/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64" -#define DATE "built on: Tue Mar 31 13:08:02 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:49 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm index 2c3557016cc97e..2709dbc5bc3047 100644 --- a/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64le", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7455,6 +7455,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h index 7f2ca33a6fbf08..13abf9fd8ad900 100644 --- a/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64le" -#define DATE "built on: Tue Mar 31 13:08:04 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:50 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm index a760edb45e8416..32c6f0b14a398c 100644 --- a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64le", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7455,6 +7455,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h index 10ac028310ea43..06be7372834085 100644 --- a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64le" -#define DATE "built on: Tue Mar 31 13:08:06 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:52 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm index 2cd3cf0361253f..f79ec0ca0aec3b 100644 --- a/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-ppc64le", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7383,6 +7383,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h index cba3ef37310283..4363c13947b980 100644 --- a/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-ppc64le" -#define DATE "built on: Tue Mar 31 13:08:08 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:54 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x32/asm/configdata.pm b/deps/openssl/config/archs/linux-x32/asm/configdata.pm index 35c87ff1cacb87..b24448028a0014 100644 --- a/deps/openssl/config/archs/linux-x32/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-x32/asm/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-x32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x32/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x32/asm/crypto/buildinf.h index 3017190e3325a4..c234a16b3b4e29 100644 --- a/deps/openssl/config/archs/linux-x32/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x32/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x32" -#define DATE "built on: Tue Mar 31 13:07:23 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:19 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x32/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-x32/asm_avx2/configdata.pm index 427ec7fa242d93..18de59ca09c2d6 100644 --- a/deps/openssl/config/archs/linux-x32/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-x32/asm_avx2/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-x32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x32/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-x32/asm_avx2/crypto/buildinf.h index 5100bc5a9ecc23..b89bda8653dc28 100644 --- a/deps/openssl/config/archs/linux-x32/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x32/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x32" -#define DATE "built on: Tue Mar 31 13:07:29 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:24 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x32/no-asm/configdata.pm b/deps/openssl/config/archs/linux-x32/no-asm/configdata.pm index b4c992be1e4755..4b5a7704d93b2a 100644 --- a/deps/openssl/config/archs/linux-x32/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-x32/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-x32", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x32/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x32/no-asm/crypto/buildinf.h index 44c24ddc95fadd..f4c2dce6f1602c 100644 --- a/deps/openssl/config/archs/linux-x32/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x32/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x32" -#define DATE "built on: Tue Mar 31 13:07:36 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:28 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm b/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm index 64b19df0b50315..d24a1adde8a741 100644 --- a/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm +++ b/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h index de8d70dfab22ff..919af33bcabd6a 100644 --- a/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x86_64" -#define DATE "built on: Tue Mar 31 13:07:37 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:29 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm index 3a92a5f3df421e..9ba4396da82590 100644 --- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm @@ -112,8 +112,8 @@ our %config = ( sourcedir => ".", target => "linux-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7502,6 +7502,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h index 973a1d49fc7f8c..ae4d93579aeb67 100644 --- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x86_64" -#define DATE "built on: Tue Mar 31 13:07:43 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:34 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm b/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm index ec40df48a6db36..d82eea4612f3bd 100644 --- a/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux-x86_64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h index 8b3e2ac9d677ce..adf411b4c51c86 100644 --- a/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-x86_64" -#define DATE "built on: Tue Mar 31 13:07:49 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:39 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm b/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm index 4baa96d1a54f66..9e49cb981e695e 100644 --- a/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm +++ b/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux32-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7392,6 +7392,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h index 78112639711a4f..ec1ee2efd11e27 100644 --- a/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux32-s390x" -#define DATE "built on: Tue Mar 31 13:08:10 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:56 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm index 9a6b1d89da1a1a..1b8bc39854d564 100644 --- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux32-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7392,6 +7392,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h index 4628d77442dc09..4beac3e2af8a7c 100644 --- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux32-s390x" -#define DATE "built on: Tue Mar 31 13:08:11 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:57 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm b/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm index 3ba5360d81c20c..22b2fb67657d9f 100644 --- a/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux32-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7378,6 +7378,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h index 69aac7b4136fe0..80c3ebb97e0598 100644 --- a/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux32-s390x" -#define DATE "built on: Tue Mar 31 13:08:13 2020 UTC" +#define DATE "built on: Tue Apr 21 13:29:58 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm b/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm index 6d647fb70ff59f..6ea79c233bd4ec 100644 --- a/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm +++ b/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-mips64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7388,6 +7388,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h index e34c4f639e20a3..4aaf2f715b2786 100644 --- a/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-mips64" -#define DATE "built on: Tue Mar 31 13:08:19 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:04 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm index c6552186a38de3..335a17f197b2d7 100644 --- a/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-mips64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7388,6 +7388,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h index aebc04c835dbd9..b1ca7beae8b4f7 100644 --- a/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-mips64" -#define DATE "built on: Tue Mar 31 13:08:21 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:05 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm index 22ad32263b92f2..2850108eecf20e 100644 --- a/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-mips64", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h index ccc6b1170b9199..a3592bdfa133af 100644 --- a/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-mips64" -#define DATE "built on: Tue Mar 31 13:08:22 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:07 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm b/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm index b588a78aaa396c..262b20c7c7b23e 100644 --- a/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm +++ b/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7405,6 +7405,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h index 7906059969df10..0a88ba38dac443 100644 --- a/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-s390x" -#define DATE "built on: Tue Mar 31 13:08:14 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:00 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm index cfc5eec1e38caf..0e2c4a34fb94d8 100644 --- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7405,6 +7405,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h index a64e67ec338d7b..e6c0d9746137dc 100644 --- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-s390x" -#define DATE "built on: Tue Mar 31 13:08:16 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:01 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm index fe7360fbc1263a..6cf06f127a9f5a 100644 --- a/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm +++ b/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "linux64-s390x", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7384,6 +7384,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h index c040b1b01640ae..36544bc5da2990 100644 --- a/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux64-s390x" -#define DATE "built on: Tue Mar 31 13:08:18 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:03 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm index 27ac0f01f4e9ef..3ac47d94a63097 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm +++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "solaris-x86-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7429,6 +7429,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h index d6c8a3b7631169..36ae42ae77bf05 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris-x86-gcc" -#define DATE "built on: Tue Mar 31 13:08:24 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:08 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm index 46a918d381edcf..791a0c1e993f8e 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "solaris-x86-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7429,6 +7429,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h index 2b864734a6f618..028f93b66991c7 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris-x86-gcc" -#define DATE "built on: Tue Mar 31 13:08:27 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:10 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm index 47d9080b188c77..23c76c2a4055b0 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "solaris-x86-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7378,6 +7378,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h index 794a3b4f92dd9c..bb1034543d523b 100644 --- a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris-x86-gcc" -#define DATE "built on: Tue Mar 31 13:08:29 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:13 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm index 219287bc9d6085..48d568b9d8a45e 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "solaris64-x86_64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7498,6 +7498,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h index 2eb96dc54d9a91..a0b629e46d0cfd 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris64-x86_64-gcc" -#define DATE "built on: Tue Mar 31 13:08:31 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:14 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm index dcdb2d6fbc7428..4f155ddf1fc637 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm @@ -111,8 +111,8 @@ our %config = ( sourcedir => ".", target => "solaris64-x86_64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7498,6 +7498,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h index 0a097756d91843..d4965b40b0e150 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris64-x86_64-gcc" -#define DATE "built on: Tue Mar 31 13:08:36 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:19 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm index d4f7b159c7225e..bb91b718764c0f 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm @@ -110,8 +110,8 @@ our %config = ( sourcedir => ".", target => "solaris64-x86_64-gcc", tdirs => [ "ossl_shim" ], - version => "1.1.1f", - version_num => "0x1010106fL", + version => "1.1.1g", + version_num => "0x1010107fL", ); our %target = ( @@ -7380,6 +7380,7 @@ our %unified_info = ( [ ".", "include", + "crypto/modes", ], "crypto/rand/drbg_lib.o" => [ diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h index b76962598a553b..b88ad42bb166a2 100644 --- a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h +++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: solaris64-x86_64-gcc" -#define DATE "built on: Tue Mar 31 13:08:42 2020 UTC" +#define DATE "built on: Tue Apr 21 13:30:24 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/deps/openssl/openssl/CHANGES b/deps/openssl/openssl/CHANGES index f4230aaac03185..057405b0bff935 100644 --- a/deps/openssl/openssl/CHANGES +++ b/deps/openssl/openssl/CHANGES @@ -7,6 +7,27 @@ https://github.com/openssl/openssl/commits/ and pick the appropriate release branch. + Changes between 1.1.1f and 1.1.1g [21 Apr 2020] + + *) Fixed segmentation fault in SSL_check_chain() + Server or client applications that call the SSL_check_chain() function + during or after a TLS 1.3 handshake may crash due to a NULL pointer + dereference as a result of incorrect handling of the + "signature_algorithms_cert" TLS extension. The crash occurs if an invalid + or unrecognised signature algorithm is received from the peer. This could + be exploited by a malicious peer in a Denial of Service attack. + (CVE-2020-1967) + [Benjamin Kaduk] + + *) Added AES consttime code for no-asm configurations + an optional constant time support for AES was added + when building openssl for no-asm. + Enable with: ./config no-asm -DOPENSSL_AES_CONST_TIME + Disable with: ./config no-asm -DOPENSSL_NO_AES_CONST_TIME + At this time this feature is by default disabled. + It will be enabled by default in 3.0. + [Bernd Edlinger] + Changes between 1.1.1e and 1.1.1f [31 Mar 2020] *) Revert the change of EOF detection while reading in libssl to avoid diff --git a/deps/openssl/openssl/INSTALL b/deps/openssl/openssl/INSTALL index 328ad2baf480b4..f5118428b3bca2 100644 --- a/deps/openssl/openssl/INSTALL +++ b/deps/openssl/openssl/INSTALL @@ -535,9 +535,9 @@ conjunction with the "-DPEDANTIC" option (or the --strict-warnings option). - no-ui - Don't build with the "UI" capability (i.e. the set of - features enabling text based prompts). + no-ui-console + Don't build with the "UI" console method (i.e. the "UI" + method that enables text based console prompts). enable-unit-test Enable additional unit test APIs. This should not typically diff --git a/deps/openssl/openssl/NEWS b/deps/openssl/openssl/NEWS index 85470793b20996..455b02dcb264bd 100644 --- a/deps/openssl/openssl/NEWS +++ b/deps/openssl/openssl/NEWS @@ -5,6 +5,10 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.1.1f and OpenSSL 1.1.1g [21 Apr 2020] + + o Fixed segmentation fault in SSL_check_chain() (CVE-2020-1967) + Major changes between OpenSSL 1.1.1e and OpenSSL 1.1.1f [31 Mar 2020] o Revert the unexpected EOF reporting via SSL_ERROR_SSL diff --git a/deps/openssl/openssl/README b/deps/openssl/openssl/README index d7d44aa3a01b13..46c2b537bed482 100644 --- a/deps/openssl/openssl/README +++ b/deps/openssl/openssl/README @@ -1,5 +1,5 @@ - OpenSSL 1.1.1f 31 Mar 2020 + OpenSSL 1.1.1g 21 Apr 2020 Copyright (c) 1998-2020 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/deps/openssl/openssl/apps/build.info b/deps/openssl/openssl/apps/build.info index 751d8da8281815..01537361820e1d 100644 --- a/deps/openssl/openssl/apps/build.info +++ b/deps/openssl/openssl/apps/build.info @@ -1,16 +1,17 @@ {- our @apps_openssl_src = qw(openssl.c - asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c - dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c - genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c - pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c + asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c + enc.c errstr.c + genpkey.c nseq.c passwd.c pkcs7.c pkcs8.c + pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c - srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c); + verify.c version.c x509.c rehash.c storeutl.c); our @apps_lib_src = ( qw(apps.c opt.c s_cb.c s_socket.c app_rand.c bf_prefix.c), split(/\s+/, $target{apps_aux_src}) ); our @apps_init_src = split(/\s+/, $target{apps_init_src}); "" -} + IF[{- !$disabled{apps} -}] LIBS_NO_INST=libapps.a SOURCE[libapps.a]={- join(" ", @apps_lib_src) -} @@ -21,11 +22,51 @@ IF[{- !$disabled{apps} -}] SOURCE[openssl]={- join(" ", @apps_openssl_src) -} INCLUDE[openssl]=.. ../include DEPEND[openssl]=libapps.a ../libssl - -IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] - GENERATE[openssl.rc]=../util/mkrc.pl openssl - SOURCE[openssl]=openssl.rc -ENDIF + IF[{- !$disabled{'des'} -}] + SOURCE[openssl]=pkcs12.c + DEPEND[pkcs12.o]=progs.h + ENDIF + IF[{- !$disabled{'ec'} -}] + SOURCE[openssl]=ec.c ecparam.c + DEPEND[ec.o]=progs.h + DEPEND[ecparam.o]=progs.h + ENDIF + IF[{- !$disabled{'ocsp'} -}] + SOURCE[openssl]=ocsp.c + DEPEND[ocsp.o]=progs.h + ENDIF + IF[{- !$disabled{'srp'} -}] + SOURCE[openssl]=srp.c + DEPEND[srp.o]=progs.h + ENDIF + IF[{- !$disabled{'ts'} -}] + SOURCE[openssl]=ts.c + DEPEND[ts.o]=progs.h + ENDIF + IF[{- !$disabled{'dh'} -}] + SOURCE[openssl]=dhparam.c + DEPEND[dhparam.o]=progs.h + ENDIF + IF[{- !$disabled{'dsa'} -}] + SOURCE[openssl]=dsa.c dsaparam.c gendsa.c + DEPEND[dsa.o]=progs.h + DEPEND[dsaparam.o]=progs.h + DEPEND[gendsa.o]=progs.h + ENDIF + IF[{- !$disabled{'engine'} -}] + SOURCE[openssl]=engine.c + DEPEND[engine.o]=progs.h + ENDIF + IF[{- !$disabled{'rsa'} -}] + SOURCE[openssl]=rsa.c rsautl.c genrsa.c + DEPEND[rsa.o]=progs.h + DEPEND[rsautl.o]=progs.h + DEPEND[genrsa.o]=progs.h + ENDIF + IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}] + GENERATE[openssl.rc]=../util/mkrc.pl openssl + SOURCE[openssl]=openssl.rc + ENDIF {- join("\n ", map { (my $x = $_) =~ s|\.c$|.o|; "DEPEND[$x]=progs.h" } @apps_openssl_src) -} diff --git a/deps/openssl/openssl/apps/dhparam.c b/deps/openssl/openssl/apps/dhparam.c index 13f76754d27cbe..98c73214b53e26 100644 --- a/deps/openssl/openssl/apps/dhparam.c +++ b/deps/openssl/openssl/apps/dhparam.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,28 +8,24 @@ */ #include -#ifdef OPENSSL_NO_DH -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include - -# ifndef OPENSSL_NO_DSA -# include -# endif - -# define DEFBITS 2048 +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_DSA +# include +#endif + +#define DEFBITS 2048 static int dh_cb(int p, int n, BN_GENCB *cb); @@ -56,13 +52,13 @@ const OPTIONS dhparam_options[] = { {"C", OPT_C, '-', "Print C code"}, {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, -# ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DSA {"dsaparam", OPT_DSAPARAM, '-', "Read or generate DSA parameters, convert to DH"}, -# endif -# ifndef OPENSSL_NO_ENGINE +#endif +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -146,13 +142,13 @@ int dhparam_main(int argc, char **argv) if (g && !num) num = DEFBITS; -# ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DSA if (dsaparam && g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } -# endif +#endif out = bio_open_default(outfile, 'w', outformat); if (out == NULL) @@ -173,7 +169,7 @@ int dhparam_main(int argc, char **argv) BN_GENCB_set(cb, dh_cb, bio_err); -# ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa = DSA_new(); @@ -196,7 +192,7 @@ int dhparam_main(int argc, char **argv) goto end; } } else -# endif +#endif { dh = DH_new(); BIO_printf(bio_err, @@ -217,7 +213,7 @@ int dhparam_main(int argc, char **argv) if (in == NULL) goto end; -# ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; @@ -239,7 +235,7 @@ int dhparam_main(int argc, char **argv) goto end; } } else -# endif +#endif { if (informat == FORMAT_ASN1) { /* @@ -376,4 +372,3 @@ static int dh_cb(int p, int n, BN_GENCB *cb) (void)BIO_flush(BN_GENCB_get_arg(cb)); return 1; } -#endif diff --git a/deps/openssl/openssl/apps/dsa.c b/deps/openssl/openssl/apps/dsa.c index 6022e64cd4cebe..c7884df166b70f 100644 --- a/deps/openssl/openssl/apps/dsa.c +++ b/deps/openssl/openssl/apps/dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,23 +8,19 @@ */ #include -#ifdef OPENSSL_NO_DSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -49,14 +45,14 @@ const OPTIONS dsa_options[] = { {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, -# ifndef OPENSSL_NO_RC4 +#ifndef OPENSSL_NO_RC4 {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, -# endif -# ifndef OPENSSL_NO_ENGINE +#endif +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -71,9 +67,9 @@ int dsa_main(int argc, char **argv) OPTION_CHOICE o; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; int i, modulus = 0, pubin = 0, pubout = 0, ret = 1; -# ifndef OPENSSL_NO_RC4 +#ifndef OPENSSL_NO_RC4 int pvk_encr = 2; -# endif +#endif int private = 0; prog = opt_init(argc, argv, dsa_options); @@ -214,7 +210,7 @@ int dsa_main(int argc, char **argv) i = PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout); } -# ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_RSA } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); @@ -229,13 +225,13 @@ int dsa_main(int argc, char **argv) goto end; } assert(private); -# ifdef OPENSSL_NO_RC4 +# ifdef OPENSSL_NO_RC4 BIO_printf(bio_err, "PVK format not supported\n"); EVP_PKEY_free(pk); goto end; -# else +# else i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -# endif +# endif } else if (pubin || pubout) { i = i2b_PublicKey_bio(out, pk); } else { @@ -243,7 +239,7 @@ int dsa_main(int argc, char **argv) i = i2b_PrivateKey_bio(out, pk); } EVP_PKEY_free(pk); -# endif +#endif } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; @@ -262,4 +258,3 @@ int dsa_main(int argc, char **argv) OPENSSL_free(passout); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/dsaparam.c b/deps/openssl/openssl/apps/dsaparam.c index b227b76a372362..75589ac6bc4eaa 100644 --- a/deps/openssl/openssl/apps/dsaparam.c +++ b/deps/openssl/openssl/apps/dsaparam.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,22 +8,18 @@ */ #include -#ifdef OPENSSL_NO_DSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include static int dsa_cb(int p, int n, BN_GENCB *cb); @@ -44,9 +40,9 @@ const OPTIONS dsaparam_options[] = { {"noout", OPT_NOOUT, '-', "No output"}, {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -255,4 +251,3 @@ static int dsa_cb(int p, int n, BN_GENCB *cb) (void)BIO_flush(BN_GENCB_get_arg(cb)); return 1; } -#endif diff --git a/deps/openssl/openssl/apps/ec.c b/deps/openssl/openssl/apps/ec.c index 03abb00683373b..0c8ed750cc1788 100644 --- a/deps/openssl/openssl/apps/ec.c +++ b/deps/openssl/openssl/apps/ec.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,19 +8,15 @@ */ #include -#ifdef OPENSSL_NO_EC -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include static OPT_PAIR conv_forms[] = { {"compressed", POINT_CONVERSION_COMPRESSED}, @@ -62,9 +58,9 @@ const OPTIONS ec_options[] = { "Specifies the way the ec parameters are encoded"}, {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, {"", OPT_CIPHER, '-', "Any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -280,4 +276,3 @@ int ec_main(int argc, char **argv) OPENSSL_free(passout); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/ecparam.c b/deps/openssl/openssl/apps/ecparam.c index 917f1a86b2e36c..58fbeb95c9ce31 100644 --- a/deps/openssl/openssl/apps/ecparam.c +++ b/deps/openssl/openssl/apps/ecparam.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -9,22 +9,18 @@ */ #include -#ifdef OPENSSL_NO_EC -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -55,9 +51,9 @@ const OPTIONS ecparam_options[] = { "Specifies the way the ec parameters are encoded"}, {"genkey", OPT_GENKEY, '-', "Generate ec key"}, OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -446,5 +442,3 @@ int ecparam_main(int argc, char **argv) BIO_free_all(out); return ret; } - -#endif diff --git a/deps/openssl/openssl/apps/engine.c b/deps/openssl/openssl/apps/engine.c index 83f9588a0ab19f..746cace354b2e0 100644 --- a/deps/openssl/openssl/apps/engine.c +++ b/deps/openssl/openssl/apps/engine.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,19 +8,15 @@ */ #include -#ifdef OPENSSL_NO_ENGINE -NON_EMPTY_TRANSLATION_UNIT -#else - -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include -# include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -486,4 +482,3 @@ int engine_main(int argc, char **argv) BIO_free_all(out); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/gendsa.c b/deps/openssl/openssl/apps/gendsa.c index 401375420bffad..ec57c92a949274 100644 --- a/deps/openssl/openssl/apps/gendsa.c +++ b/deps/openssl/openssl/apps/gendsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,22 +8,18 @@ */ #include -#ifdef OPENSSL_NO_DSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -39,9 +35,9 @@ const OPTIONS gendsa_options[] = { {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, OPT_R_OPTIONS, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -143,4 +139,3 @@ int gendsa_main(int argc, char **argv) OPENSSL_free(passout); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/genrsa.c b/deps/openssl/openssl/apps/genrsa.c index c17cd147154eea..e34a2f7ab9e883 100644 --- a/deps/openssl/openssl/apps/genrsa.c +++ b/deps/openssl/openssl/apps/genrsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,27 +8,23 @@ */ #include -#ifdef OPENSSL_NO_RSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include -# include -# include - -# define DEFBITS 2048 -# define DEFPRIMES 2 +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFBITS 2048 +#define DEFPRIMES 2 static int genrsa_cb(int p, int n, BN_GENCB *cb); @@ -48,9 +44,9 @@ const OPTIONS genrsa_options[] = { OPT_R_OPTIONS, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, {NULL} }; @@ -198,4 +194,3 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb) (void)BIO_flush(BN_GENCB_get_arg(cb)); return 1; } -#endif diff --git a/deps/openssl/openssl/apps/ocsp.c b/deps/openssl/openssl/apps/ocsp.c index b85a4d82c1bd14..27ec94fa6b8d48 100644 --- a/deps/openssl/openssl/apps/ocsp.c +++ b/deps/openssl/openssl/apps/ocsp.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,65 +9,62 @@ #include -#ifdef OPENSSL_NO_OCSP -NON_EMPTY_TRANSLATION_UNIT -#else -# ifdef OPENSSL_SYS_VMS -# define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined +#ifdef OPENSSL_SYS_VMS +# define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined * on OpenVMS */ -# endif +#endif -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include /* Needs to be included before the openssl headers */ -# include "apps.h" -# include "progs.h" -# include "internal/sockets.h" -# include -# include -# include -# include -# include -# include -# include -# include +#include "apps.h" +#include "progs.h" +#include "internal/sockets.h" +#include +#include +#include +#include +#include +#include +#include +#include #ifndef HAVE_FORK -# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) -# define HAVE_FORK 0 -# else -# define HAVE_FORK 1 -# endif +#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) +# define HAVE_FORK 0 +#else +# define HAVE_FORK 1 +#endif #endif #if HAVE_FORK -# undef NO_FORK +#undef NO_FORK #else -# define NO_FORK +#define NO_FORK #endif -# if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \ +#if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \ && !defined(OPENSSL_NO_POSIX_IO) -# define OCSP_DAEMON -# include -# include -# include -# include -# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */ -# else -# undef LOG_INFO -# undef LOG_WARNING -# undef LOG_ERR -# define LOG_INFO 0 -# define LOG_WARNING 1 -# define LOG_ERR 2 -# endif +# define OCSP_DAEMON +# include +# include +# include +# include +# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */ +#else +# undef LOG_INFO +# undef LOG_WARNING +# undef LOG_ERR +# define LOG_INFO 0 +# define LOG_WARNING 1 +# define LOG_ERR 2 +#endif -# if defined(OPENSSL_SYS_VXWORKS) +#if defined(OPENSSL_SYS_VXWORKS) /* not supported */ int setpgid(pid_t pid, pid_t pgid) { @@ -80,9 +77,9 @@ pid_t fork(void) errno = ENOSYS; return (pid_t) -1; } -# endif +#endif /* Maximum leeway in validity period: default 5 minutes */ -# define MAX_VALIDITY_PERIOD (5 * 60) +#define MAX_VALIDITY_PERIOD (5 * 60) static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, @@ -109,20 +106,20 @@ static void log_message(int level, const char *fmt, ...); static char *prog; static int multi = 0; -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON static int acfd = (int) INVALID_SOCKET; static int index_changed(CA_DB *); static void spawn_loop(void); static int print_syslog(const char *str, size_t len, void *levPtr); static void socket_timeout(int signum); -# endif +#endif -# ifndef OPENSSL_NO_SOCK +#ifndef OPENSSL_NO_SOCK static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, const char *path, const STACK_OF(CONF_VALUE) *headers, OCSP_REQUEST *req, int req_timeout); -# endif +#endif typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -160,9 +157,9 @@ const OPTIONS ocsp_options[] = { "Don't include any certificates in response"}, {"resp_key_id", OPT_RESP_KEY_ID, '-', "Identify response by signing certificate key ID"}, -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON {"multi", OPT_MULTI, 'p', "run multiple responder processes"}, -# endif +#endif {"no_certs", OPT_NO_CERTS, '-', "Don't include any certificates in signed request"}, {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', @@ -511,9 +508,9 @@ int ocsp_main(int argc, char **argv) trailing_md = 1; break; case OPT_MULTI: -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON multi = atoi(opt_arg()); -# endif +#endif break; } } @@ -593,7 +590,7 @@ int ocsp_main(int argc, char **argv) } } -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON if (multi && acbio != NULL) spawn_loop(); if (acbio != NULL && req_timeout > 0) @@ -606,7 +603,7 @@ int ocsp_main(int argc, char **argv) redo_accept: if (acbio != NULL) { -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON if (index_changed(rdb)) { CA_DB *newrdb = load_index(ridx_filename, NULL); @@ -619,7 +616,7 @@ int ocsp_main(int argc, char **argv) ridx_filename); } } -# endif +#endif req = NULL; if (!do_responder(&req, &cbio, acbio, req_timeout)) @@ -688,16 +685,16 @@ int ocsp_main(int argc, char **argv) if (cbio != NULL) send_ocsp_response(cbio, resp); } else if (host != NULL) { -# ifndef OPENSSL_NO_SOCK +#ifndef OPENSSL_NO_SOCK resp = process_responder(req, host, path, port, use_ssl, headers, req_timeout); if (resp == NULL) goto end; -# else +#else BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); goto end; -# endif +#endif } else if (respin != NULL) { derbio = bio_open_default(respin, 'r', FORMAT_ASN1); if (derbio == NULL) @@ -840,7 +837,7 @@ log_message(int level, const char *fmt, ...) va_list ap; va_start(ap, fmt); -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON if (multi) { char buf[1024]; if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) { @@ -849,7 +846,7 @@ log_message(int level, const char *fmt, ...) if (level >= LOG_ERR) ERR_print_errors_cb(print_syslog, &level); } -# endif +#endif if (!multi) { BIO_printf(bio_err, "%s: ", prog); BIO_vprintf(bio_err, fmt, ap); @@ -858,7 +855,7 @@ log_message(int level, const char *fmt, ...) va_end(ap); } -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON static int print_syslog(const char *str, size_t len, void *levPtr) { @@ -1011,7 +1008,7 @@ static void spawn_loop(void) syslog(LOG_INFO, "terminating on signal: %d", termsig); killall(0, kidpids); } -# endif +#endif static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer, @@ -1291,11 +1288,11 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) static BIO *init_responder(const char *port) { -# ifdef OPENSSL_NO_SOCK +#ifdef OPENSSL_NO_SOCK BIO_printf(bio_err, "Error setting up accept BIO - sockets not supported.\n"); return NULL; -# else +#else BIO *acbio = NULL, *bufbio = NULL; bufbio = BIO_new(BIO_f_buffer()); @@ -1322,10 +1319,10 @@ static BIO *init_responder(const char *port) BIO_free_all(acbio); BIO_free(bufbio); return NULL; -# endif +#endif } -# ifndef OPENSSL_NO_SOCK +#ifndef OPENSSL_NO_SOCK /* * Decode %xx URL-decoding in-place. Ignores mal-formed sequences. */ @@ -1349,22 +1346,22 @@ static int urldecode(char *p) *out = '\0'; return (int)(out - save); } -# endif +#endif -# ifdef OCSP_DAEMON +#ifdef OCSP_DAEMON static void socket_timeout(int signum) { if (acfd != (int)INVALID_SOCKET) (void)shutdown(acfd, SHUT_RD); } -# endif +#endif static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, int timeout) { -# ifdef OPENSSL_NO_SOCK +#ifdef OPENSSL_NO_SOCK return 0; -# else +#else int len; OCSP_REQUEST *req = NULL; char inbuf[2048], reqbuf[2048]; @@ -1382,12 +1379,12 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, *pcbio = cbio; client = BIO_get_peer_name(cbio); -# ifdef OCSP_DAEMON +# ifdef OCSP_DAEMON if (timeout > 0) { (void) BIO_get_fd(cbio, &acfd); alarm(timeout); } -# endif +# endif /* Read the request line. */ len = BIO_gets(cbio, reqbuf, sizeof(reqbuf)); @@ -1450,11 +1447,11 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, break; } -# ifdef OCSP_DAEMON +# ifdef OCSP_DAEMON /* Clear alarm before we close the client socket */ alarm(0); timeout = 0; -# endif +# endif /* Try to read OCSP request */ if (getbio != NULL) { @@ -1470,13 +1467,13 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, *preq = req; out: -# ifdef OCSP_DAEMON +# ifdef OCSP_DAEMON if (timeout > 0) alarm(0); acfd = (int)INVALID_SOCKET; -# endif - return 1; # endif + return 1; +#endif } static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) @@ -1492,7 +1489,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) return 1; } -# ifndef OPENSSL_NO_SOCK +#ifndef OPENSSL_NO_SOCK static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, const char *path, const STACK_OF(CONF_VALUE) *headers, @@ -1623,6 +1620,4 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, SSL_CTX_free(ctx); return resp; } -# endif - #endif diff --git a/deps/openssl/openssl/apps/pkcs12.c b/deps/openssl/openssl/apps/pkcs12.c index 3603b60c19b3ab..8c5d963b8c654a 100644 --- a/deps/openssl/openssl/apps/pkcs12.c +++ b/deps/openssl/openssl/apps/pkcs12.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,25 +8,21 @@ */ #include -#if defined(OPENSSL_NO_DES) -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include - -# define NOKEYS 0x1 -# define NOCERTS 0x2 -# define INFO 0x4 -# define CLCERTS 0x8 -# define CACERTS 0x10 +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include + +#define NOKEYS 0x1 +#define NOCERTS 0x2 +#define INFO 0x4 +#define CLCERTS 0x8 +#define CACERTS 0x10 #define PASSWD_BUF_SIZE 2048 @@ -74,15 +70,15 @@ const OPTIONS pkcs12_options[] = { {"chain", OPT_CHAIN, '-', "Add certificate chain"}, {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, -# ifndef OPENSSL_NO_RC2 +#ifndef OPENSSL_NO_RC2 {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (default RC2-40)"}, {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default RC2-40)"}, -# else +#else {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, -# endif +#endif {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, {"maciter", OPT_MACITER, '-', "Use MAC iteration"}, @@ -113,9 +109,9 @@ const OPTIONS pkcs12_options[] = { {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -126,11 +122,11 @@ int pkcs12_main(int argc, char **argv) char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = ""; int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; -# ifndef OPENSSL_NO_RC2 +#ifndef OPENSSL_NO_RC2 int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; -# else +#else int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -# endif +#endif int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1, macver = 1, add_lmk = 0, private = 0; int noprompt = 0; @@ -976,5 +972,3 @@ static int set_pbe(int *ppbe, const char *str) } return 1; } - -#endif diff --git a/deps/openssl/openssl/apps/rsa.c b/deps/openssl/openssl/apps/rsa.c index fdd02dce32419a..aeda917cc7686e 100644 --- a/deps/openssl/openssl/apps/rsa.c +++ b/deps/openssl/openssl/apps/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,23 +8,19 @@ */ #include -#ifdef OPENSSL_NO_RSA -NON_EMPTY_TRANSLATION_UNIT -#else - -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include +#include typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -53,14 +49,14 @@ const OPTIONS rsa_options[] = { {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, {"check", OPT_CHECK, '-', "Verify key consistency"}, {"", OPT_CIPHER, '-', "Any supported cipher"}, -# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, -# endif -# ifndef OPENSSL_NO_ENGINE +#endif +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -75,9 +71,9 @@ int rsa_main(int argc, char **argv) int i, private = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; int noout = 0, modulus = 0, pubin = 0, pubout = 0, ret = 1; -# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) int pvk_encr = 2; -# endif +#endif OPTION_CHOICE o; prog = opt_init(argc, argv, rsa_options); @@ -130,9 +126,9 @@ int rsa_main(int argc, char **argv) case OPT_PVK_STRONG: /* pvk_encr:= 2 */ case OPT_PVK_WEAK: /* pvk_encr:= 1 */ case OPT_PVK_NONE: /* pvk_encr:= 0 */ -# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) +#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) pvk_encr = (o - OPT_PVK_NONE); -# endif +#endif break; case OPT_NOOUT: noout = 1; @@ -265,7 +261,7 @@ int rsa_main(int argc, char **argv) i = PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, NULL, passout); } -# ifndef OPENSSL_NO_DSA +#ifndef OPENSSL_NO_DSA } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); @@ -280,13 +276,13 @@ int rsa_main(int argc, char **argv) goto end; } assert(private); -# ifdef OPENSSL_NO_RC4 +# ifdef OPENSSL_NO_RC4 BIO_printf(bio_err, "PVK format not supported\n"); EVP_PKEY_free(pk); goto end; -# else +# else i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -# endif +# endif } else if (pubin || pubout) { i = i2b_PublicKey_bio(out, pk); } else { @@ -294,7 +290,7 @@ int rsa_main(int argc, char **argv) i = i2b_PrivateKey_bio(out, pk); } EVP_PKEY_free(pk); -# endif +#endif } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; @@ -313,4 +309,3 @@ int rsa_main(int argc, char **argv) OPENSSL_free(passout); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/rsautl.c b/deps/openssl/openssl/apps/rsautl.c index 5da8504d3c061f..0c0fa8eba30ade 100644 --- a/deps/openssl/openssl/apps/rsautl.c +++ b/deps/openssl/openssl/apps/rsautl.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,25 +8,21 @@ */ #include -#ifdef OPENSSL_NO_RSA -NON_EMPTY_TRANSLATION_UNIT -#else +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include +#define RSA_SIGN 1 +#define RSA_VERIFY 2 +#define RSA_ENCRYPT 3 +#define RSA_DECRYPT 4 -# define RSA_SIGN 1 -# define RSA_VERIFY 2 -# define RSA_ENCRYPT 3 -# define RSA_DECRYPT 4 - -# define KEY_PRIVKEY 1 -# define KEY_PUBKEY 2 -# define KEY_CERT 3 +#define KEY_PRIVKEY 1 +#define KEY_PUBKEY 2 +#define KEY_CERT 3 typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, @@ -60,9 +56,9 @@ const OPTIONS rsautl_options[] = { {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -279,4 +275,3 @@ int rsautl_main(int argc, char **argv) OPENSSL_free(passin); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/s_time.c b/deps/openssl/openssl/apps/s_time.c index 82d40a5a513246..628e65b26e19c0 100644 --- a/deps/openssl/openssl/apps/s_time.c +++ b/deps/openssl/openssl/apps/s_time.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,6 +62,7 @@ const OPTIONS s_time_options[] = { {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', diff --git a/deps/openssl/openssl/apps/srp.c b/deps/openssl/openssl/apps/srp.c index 689574a4854c84..6c58173879739f 100644 --- a/deps/openssl/openssl/apps/srp.c +++ b/deps/openssl/openssl/apps/srp.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use @@ -12,28 +12,24 @@ */ #include -#ifdef OPENSSL_NO_SRP -NON_EMPTY_TRANSLATION_UNIT -#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include "apps.h" -# include "progs.h" +#define BASE_SECTION "srp" +#define CONFIG_FILE "openssl.cnf" -# define BASE_SECTION "srp" -# define CONFIG_FILE "openssl.cnf" - -# define ENV_DATABASE "srpvfile" -# define ENV_DEFAULT_SRP "default_srp" +#define ENV_DATABASE "srpvfile" +#define ENV_DEFAULT_SRP "default_srp" static int get_index(CA_DB *db, char *id, char type) { @@ -212,9 +208,9 @@ const OPTIONS srp_options[] = { {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, OPT_R_OPTIONS, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {NULL} }; @@ -610,4 +606,3 @@ int srp_main(int argc, char **argv) release_engine(e); return ret; } -#endif diff --git a/deps/openssl/openssl/apps/ts.c b/deps/openssl/openssl/apps/ts.c index 44a8f75d4a370b..66a0c810e0c301 100644 --- a/deps/openssl/openssl/apps/ts.c +++ b/deps/openssl/openssl/apps/ts.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,29 +8,26 @@ */ #include -#ifdef OPENSSL_NO_TS -NON_EMPTY_TRANSLATION_UNIT -#else -# include -# include -# include -# include "apps.h" -# include "progs.h" -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include /* Request nonce length, in bits (must be a multiple of 8). */ -# define NONCE_LENGTH 64 +#define NONCE_LENGTH 64 /* Name of config entry that defines the OID file. */ -# define ENV_OID_FILE "oid_file" +#define ENV_OID_FILE "oid_file" /* Is |EXACTLY_ONE| of three pointers set? */ -# define EXACTLY_ONE(a, b, c) \ +#define EXACTLY_ONE(a, b, c) \ (( a && !b && !c) || \ ( b && !a && !c) || \ ( c && !a && !b)) @@ -114,9 +111,9 @@ const OPTIONS ts_options[] = { {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"}, {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"}, {"", OPT_MD, '-', "Any supported digest"}, -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -# endif +#endif {OPT_HELP_STR, 1, '-', "\nOptions specific to 'ts -verify': \n"}, OPT_V_OPTIONS, {OPT_HELP_STR, 1, '-', "\n"}, @@ -137,11 +134,11 @@ static char* opt_helplist[] = { " [-signer tsa_cert.pem] [-inkey private_key.pem]", " [-chain certs_file.pem] [-tspolicy oid]", " [-in file] [-token_in] [-out file] [-token_out]", -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE " [-text] [-engine id]", -# else +#else " [-text]", -# endif +#endif " or", "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem", " [-data file] [-digest hexstring]", @@ -682,10 +679,10 @@ static TS_RESP *create_response(CONF *conf, const char *section, const char *eng goto end; if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end; -# ifndef OPENSSL_NO_ENGINE +#ifndef OPENSSL_NO_ENGINE if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end; -# endif +#endif if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end; if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) @@ -984,4 +981,3 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx) { return ok; } -#endif /* ndef OPENSSL_NO_TS */ diff --git a/deps/openssl/openssl/crypto/aes/aes_core.c b/deps/openssl/openssl/crypto/aes/aes_core.c index e3e688f528a5d5..687dd5829baaf4 100644 --- a/deps/openssl/openssl/crypto/aes/aes_core.c +++ b/deps/openssl/openssl/crypto/aes/aes_core.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -43,7 +43,988 @@ #include #include "aes_local.h" -#ifndef AES_ASM +#if defined(OPENSSL_AES_CONST_TIME) && !defined(AES_ASM) +typedef union { + unsigned char b[8]; + u32 w[2]; + u64 d; +} uni; + +/* + * Compute w := (w * x) mod (x^8 + x^4 + x^3 + x^1 + 1) + * Therefore the name "xtime". + */ +static void XtimeWord(u32 *w) +{ + u32 a, b; + + a = *w; + b = a & 0x80808080u; + a ^= b; + b -= b >> 7; + b &= 0x1B1B1B1Bu; + b ^= a << 1; + *w = b; +} + +static void XtimeLong(u64 *w) +{ + u64 a, b; + + a = *w; + b = a & 0x8080808080808080uLL; + a ^= b; + b -= b >> 7; + b &= 0x1B1B1B1B1B1B1B1BuLL; + b ^= a << 1; + *w = b; +} + +/* + * This computes w := S * w ^ -1 + c, where c = {01100011}. + * Instead of using GF(2^8) mod (x^8+x^4+x^3+x+1} we do the inversion + * in GF(GF(GF(2^2)^2)^2) mod (X^2+X+8) + * and GF(GF(2^2)^2) mod (X^2+X+2) + * and GF(2^2) mod (X^2+X+1) + * The first part of the algorithm below transfers the coordinates + * {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80} => + * {1,Y,Y^2,Y^3,Y^4,Y^5,Y^6,Y^7} with Y=0x41: + * {0x01,0x41,0x66,0x6c,0x56,0x9a,0x58,0xc4} + * The last part undoes the coordinate transfer and the final affine + * transformation S: + * b[i] = b[i] + b[(i+4)%8] + b[(i+5)%8] + b[(i+6)%8] + b[(i+7)%8] + c[i] + * in one step. + * The multiplication in GF(2^2^2^2) is done in ordinary coords: + * A = (a0*1 + a1*x^4) + * B = (b0*1 + b1*x^4) + * AB = ((a0*b0 + 8*a1*b1)*1 + (a1*b0 + (a0+a1)*b1)*x^4) + * When A = (a0,a1) is given we want to solve AB = 1: + * (a) 1 = a0*b0 + 8*a1*b1 + * (b) 0 = a1*b0 + (a0+a1)*b1 + * => multiply (a) by a1 and (b) by a0 + * (c) a1 = a1*a0*b0 + (8*a1*a1)*b1 + * (d) 0 = a1*a0*b0 + (a0*a0+a1*a0)*b1 + * => add (c) + (d) + * (e) a1 = (a0*a0 + a1*a0 + 8*a1*a1)*b1 + * => therefore + * b1 = (a0*a0 + a1*a0 + 8*a1*a1)^-1 * a1 + * => and adding (a1*b0) to (b) we get + * (f) a1*b0 = (a0+a1)*b1 + * => therefore + * b0 = (a0*a0 + a1*a0 + 8*a1*a1)^-1 * (a0+a1) + * Note this formula also works for the case + * (a0+a1)*a0 + 8*a1*a1 = 0 + * if the inverse element for 0^-1 is mapped to 0. + * Repeat the same for GF(2^2^2) and GF(2^2). + * We get the following algorithm: + * inv8(a0,a1): + * x0 = a0^a1 + * [y0,y1] = mul4([x0,a1],[a0,a1]); (*) + * y1 = mul4(8,y1); + * t = inv4(y0^y1); + * [b0,b1] = mul4([x0,a1],[t,t]); (*) + * return [b0,b1]; + * The non-linear multiplies (*) can be done in parallel at no extra cost. + */ +static void SubWord(u32 *w) +{ + u32 x, y, a1, a2, a3, a4, a5, a6; + + x = *w; + y = ((x & 0xFEFEFEFEu) >> 1) | ((x & 0x01010101u) << 7); + x &= 0xDDDDDDDDu; + x ^= y & 0x57575757u; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x1C1C1C1Cu; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x4A4A4A4Au; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x42424242u; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x64646464u; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0xE0E0E0E0u; + a1 = x; + a1 ^= (x & 0xF0F0F0F0u) >> 4; + a2 = ((x & 0xCCCCCCCCu) >> 2) | ((x & 0x33333333u) << 2); + a3 = x & a1; + a3 ^= (a3 & 0xAAAAAAAAu) >> 1; + a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAu; + a4 = a2 & a1; + a4 ^= (a4 & 0xAAAAAAAAu) >> 1; + a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAu; + a5 = (a3 & 0xCCCCCCCCu) >> 2; + a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCu; + a4 = a5 & 0x22222222u; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x22222222u; + a3 ^= a4; + a5 = a3 & 0xA0A0A0A0u; + a5 |= a5 >> 1; + a5 ^= (a3 << 1) & 0xA0A0A0A0u; + a4 = a5 & 0xC0C0C0C0u; + a6 = a4 >> 2; + a4 ^= (a5 << 2) & 0xC0C0C0C0u; + a5 = a6 & 0x20202020u; + a5 |= a5 >> 1; + a5 ^= (a6 << 1) & 0x20202020u; + a4 |= a5; + a3 ^= a4 >> 4; + a3 &= 0x0F0F0F0Fu; + a2 = a3; + a2 ^= (a3 & 0x0C0C0C0Cu) >> 2; + a4 = a3 & a2; + a4 ^= (a4 & 0x0A0A0A0A0Au) >> 1; + a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0Au; + a5 = a4 & 0x08080808u; + a5 |= a5 >> 1; + a5 ^= (a4 << 1) & 0x08080808u; + a4 ^= a5 >> 2; + a4 &= 0x03030303u; + a4 ^= (a4 & 0x02020202u) >> 1; + a4 |= a4 << 2; + a3 = a2 & a4; + a3 ^= (a3 & 0x0A0A0A0Au) >> 1; + a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0Au; + a3 |= a3 << 4; + a2 = ((a1 & 0xCCCCCCCCu) >> 2) | ((a1 & 0x33333333u) << 2); + x = a1 & a3; + x ^= (x & 0xAAAAAAAAu) >> 1; + x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAu; + a4 = a2 & a3; + a4 ^= (a4 & 0xAAAAAAAAu) >> 1; + a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAu; + a5 = (x & 0xCCCCCCCCu) >> 2; + x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCu; + a4 = a5 & 0x22222222u; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x22222222u; + x ^= a4; + y = ((x & 0xFEFEFEFEu) >> 1) | ((x & 0x01010101u) << 7); + x &= 0x39393939u; + x ^= y & 0x3F3F3F3Fu; + y = ((y & 0xFCFCFCFCu) >> 2) | ((y & 0x03030303u) << 6); + x ^= y & 0x97979797u; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x9B9B9B9Bu; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x3C3C3C3Cu; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0xDDDDDDDDu; + y = ((y & 0xFEFEFEFEu) >> 1) | ((y & 0x01010101u) << 7); + x ^= y & 0x72727272u; + x ^= 0x63636363u; + *w = x; +} + +static void SubLong(u64 *w) +{ + u64 x, y, a1, a2, a3, a4, a5, a6; + + x = *w; + y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); + x &= 0xDDDDDDDDDDDDDDDDuLL; + x ^= y & 0x5757575757575757uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x1C1C1C1C1C1C1C1CuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x4A4A4A4A4A4A4A4AuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x4242424242424242uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x6464646464646464uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xE0E0E0E0E0E0E0E0uLL; + a1 = x; + a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4; + a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2); + a3 = x & a1; + a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL; + a4 = a2 & a1; + a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; + a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2; + a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; + a4 = a5 & 0x2222222222222222uLL; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a3 ^= a4; + a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL; + a5 |= a5 >> 1; + a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL; + a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL; + a6 = a4 >> 2; + a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL; + a5 = a6 & 0x2020202020202020uLL; + a5 |= a5 >> 1; + a5 ^= (a6 << 1) & 0x2020202020202020uLL; + a4 |= a5; + a3 ^= a4 >> 4; + a3 &= 0x0F0F0F0F0F0F0F0FuLL; + a2 = a3; + a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2; + a4 = a3 & a2; + a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; + a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL; + a5 = a4 & 0x0808080808080808uLL; + a5 |= a5 >> 1; + a5 ^= (a4 << 1) & 0x0808080808080808uLL; + a4 ^= a5 >> 2; + a4 &= 0x0303030303030303uLL; + a4 ^= (a4 & 0x0202020202020202uLL) >> 1; + a4 |= a4 << 2; + a3 = a2 & a4; + a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; + a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL; + a3 |= a3 << 4; + a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2); + x = a1 & a3; + x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL; + a4 = a2 & a3; + a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; + a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2; + x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; + a4 = a5 & 0x2222222222222222uLL; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x2222222222222222uLL; + x ^= a4; + y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); + x &= 0x3939393939393939uLL; + x ^= y & 0x3F3F3F3F3F3F3F3FuLL; + y = ((y & 0xFCFCFCFCFCFCFCFCuLL) >> 2) | ((y & 0x0303030303030303uLL) << 6); + x ^= y & 0x9797979797979797uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x9B9B9B9B9B9B9B9BuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x3C3C3C3C3C3C3C3CuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xDDDDDDDDDDDDDDDDuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x7272727272727272uLL; + x ^= 0x6363636363636363uLL; + *w = x; +} + +/* + * This computes w := (S^-1 * (w + c))^-1 + */ +static void InvSubLong(u64 *w) +{ + u64 x, y, a1, a2, a3, a4, a5, a6; + + x = *w; + x ^= 0x6363636363636363uLL; + y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); + x &= 0xFDFDFDFDFDFDFDFDuLL; + x ^= y & 0x5E5E5E5E5E5E5E5EuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xF3F3F3F3F3F3F3F3uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xF5F5F5F5F5F5F5F5uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x7878787878787878uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x7777777777777777uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x1515151515151515uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xA5A5A5A5A5A5A5A5uLL; + a1 = x; + a1 ^= (x & 0xF0F0F0F0F0F0F0F0uLL) >> 4; + a2 = ((x & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((x & 0x3333333333333333uLL) << 2); + a3 = x & a1; + a3 ^= (a3 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a3 ^= (((x << 1) & a1) ^ ((a1 << 1) & x)) & 0xAAAAAAAAAAAAAAAAuLL; + a4 = a2 & a1; + a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a4 ^= (((a2 << 1) & a1) ^ ((a1 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; + a5 = (a3 & 0xCCCCCCCCCCCCCCCCuLL) >> 2; + a3 ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; + a4 = a5 & 0x2222222222222222uLL; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x2222222222222222uLL; + a3 ^= a4; + a5 = a3 & 0xA0A0A0A0A0A0A0A0uLL; + a5 |= a5 >> 1; + a5 ^= (a3 << 1) & 0xA0A0A0A0A0A0A0A0uLL; + a4 = a5 & 0xC0C0C0C0C0C0C0C0uLL; + a6 = a4 >> 2; + a4 ^= (a5 << 2) & 0xC0C0C0C0C0C0C0C0uLL; + a5 = a6 & 0x2020202020202020uLL; + a5 |= a5 >> 1; + a5 ^= (a6 << 1) & 0x2020202020202020uLL; + a4 |= a5; + a3 ^= a4 >> 4; + a3 &= 0x0F0F0F0F0F0F0F0FuLL; + a2 = a3; + a2 ^= (a3 & 0x0C0C0C0C0C0C0C0CuLL) >> 2; + a4 = a3 & a2; + a4 ^= (a4 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; + a4 ^= (((a3 << 1) & a2) ^ ((a2 << 1) & a3)) & 0x0A0A0A0A0A0A0A0AuLL; + a5 = a4 & 0x0808080808080808uLL; + a5 |= a5 >> 1; + a5 ^= (a4 << 1) & 0x0808080808080808uLL; + a4 ^= a5 >> 2; + a4 &= 0x0303030303030303uLL; + a4 ^= (a4 & 0x0202020202020202uLL) >> 1; + a4 |= a4 << 2; + a3 = a2 & a4; + a3 ^= (a3 & 0x0A0A0A0A0A0A0A0AuLL) >> 1; + a3 ^= (((a2 << 1) & a4) ^ ((a4 << 1) & a2)) & 0x0A0A0A0A0A0A0A0AuLL; + a3 |= a3 << 4; + a2 = ((a1 & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((a1 & 0x3333333333333333uLL) << 2); + x = a1 & a3; + x ^= (x & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + x ^= (((a1 << 1) & a3) ^ ((a3 << 1) & a1)) & 0xAAAAAAAAAAAAAAAAuLL; + a4 = a2 & a3; + a4 ^= (a4 & 0xAAAAAAAAAAAAAAAAuLL) >> 1; + a4 ^= (((a2 << 1) & a3) ^ ((a3 << 1) & a2)) & 0xAAAAAAAAAAAAAAAAuLL; + a5 = (x & 0xCCCCCCCCCCCCCCCCuLL) >> 2; + x ^= ((a4 << 2) ^ a4) & 0xCCCCCCCCCCCCCCCCuLL; + a4 = a5 & 0x2222222222222222uLL; + a4 |= a4 >> 1; + a4 ^= (a5 << 1) & 0x2222222222222222uLL; + x ^= a4; + y = ((x & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((x & 0x0101010101010101uLL) << 7); + x &= 0xB5B5B5B5B5B5B5B5uLL; + x ^= y & 0x4040404040404040uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x8080808080808080uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x1616161616161616uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xEBEBEBEBEBEBEBEBuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x9797979797979797uLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0xFBFBFBFBFBFBFBFBuLL; + y = ((y & 0xFEFEFEFEFEFEFEFEuLL) >> 1) | ((y & 0x0101010101010101uLL) << 7); + x ^= y & 0x7D7D7D7D7D7D7D7DuLL; + *w = x; +} + +static void ShiftRows(u64 *state) +{ + unsigned char s[4]; + unsigned char *s0; + int r; + + s0 = (unsigned char *)state; + for (r = 0; r < 4; r++) { + s[0] = s0[0*4 + r]; + s[1] = s0[1*4 + r]; + s[2] = s0[2*4 + r]; + s[3] = s0[3*4 + r]; + s0[0*4 + r] = s[(r+0) % 4]; + s0[1*4 + r] = s[(r+1) % 4]; + s0[2*4 + r] = s[(r+2) % 4]; + s0[3*4 + r] = s[(r+3) % 4]; + } +} + +static void InvShiftRows(u64 *state) +{ + unsigned char s[4]; + unsigned char *s0; + int r; + + s0 = (unsigned char *)state; + for (r = 0; r < 4; r++) { + s[0] = s0[0*4 + r]; + s[1] = s0[1*4 + r]; + s[2] = s0[2*4 + r]; + s[3] = s0[3*4 + r]; + s0[0*4 + r] = s[(4-r) % 4]; + s0[1*4 + r] = s[(5-r) % 4]; + s0[2*4 + r] = s[(6-r) % 4]; + s0[3*4 + r] = s[(7-r) % 4]; + } +} + +static void MixColumns(u64 *state) +{ + uni s1; + uni s; + int c; + + for (c = 0; c < 2; c++) { + s1.d = state[c]; + s.d = s1.d; + s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16) + | ((s.d & 0x0000FFFF0000FFFFuLL) << 16); + s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8) + | ((s.d & 0x00FF00FF00FF00FFuLL) << 8); + s.d ^= s1.d; + XtimeLong(&s1.d); + s.d ^= s1.d; + s.b[0] ^= s1.b[1]; + s.b[1] ^= s1.b[2]; + s.b[2] ^= s1.b[3]; + s.b[3] ^= s1.b[0]; + s.b[4] ^= s1.b[5]; + s.b[5] ^= s1.b[6]; + s.b[6] ^= s1.b[7]; + s.b[7] ^= s1.b[4]; + state[c] = s.d; + } +} + +static void InvMixColumns(u64 *state) +{ + uni s1; + uni s; + int c; + + for (c = 0; c < 2; c++) { + s1.d = state[c]; + s.d = s1.d; + s.d ^= ((s.d & 0xFFFF0000FFFF0000uLL) >> 16) + | ((s.d & 0x0000FFFF0000FFFFuLL) << 16); + s.d ^= ((s.d & 0xFF00FF00FF00FF00uLL) >> 8) + | ((s.d & 0x00FF00FF00FF00FFuLL) << 8); + s.d ^= s1.d; + XtimeLong(&s1.d); + s.d ^= s1.d; + s.b[0] ^= s1.b[1]; + s.b[1] ^= s1.b[2]; + s.b[2] ^= s1.b[3]; + s.b[3] ^= s1.b[0]; + s.b[4] ^= s1.b[5]; + s.b[5] ^= s1.b[6]; + s.b[6] ^= s1.b[7]; + s.b[7] ^= s1.b[4]; + XtimeLong(&s1.d); + s1.d ^= ((s1.d & 0xFFFF0000FFFF0000uLL) >> 16) + | ((s1.d & 0x0000FFFF0000FFFFuLL) << 16); + s.d ^= s1.d; + XtimeLong(&s1.d); + s1.d ^= ((s1.d & 0xFF00FF00FF00FF00uLL) >> 8) + | ((s1.d & 0x00FF00FF00FF00FFuLL) << 8); + s.d ^= s1.d; + state[c] = s.d; + } +} + +static void AddRoundKey(u64 *state, const u64 *w) +{ + state[0] ^= w[0]; + state[1] ^= w[1]; +} + +static void Cipher(const unsigned char *in, unsigned char *out, + const u64 *w, int nr) +{ + u64 state[2]; + int i; + + memcpy(state, in, 16); + + AddRoundKey(state, w); + + for (i = 1; i < nr; i++) { + SubLong(&state[0]); + SubLong(&state[1]); + ShiftRows(state); + MixColumns(state); + AddRoundKey(state, w + i*2); + } + + SubLong(&state[0]); + SubLong(&state[1]); + ShiftRows(state); + AddRoundKey(state, w + nr*2); + + memcpy(out, state, 16); +} + +static void InvCipher(const unsigned char *in, unsigned char *out, + const u64 *w, int nr) + +{ + u64 state[2]; + int i; + + memcpy(state, in, 16); + + AddRoundKey(state, w + nr*2); + + for (i = nr - 1; i > 0; i--) { + InvShiftRows(state); + InvSubLong(&state[0]); + InvSubLong(&state[1]); + AddRoundKey(state, w + i*2); + InvMixColumns(state); + } + + InvShiftRows(state); + InvSubLong(&state[0]); + InvSubLong(&state[1]); + AddRoundKey(state, w); + + memcpy(out, state, 16); +} + +static void RotWord(u32 *x) +{ + unsigned char *w0; + unsigned char tmp; + + w0 = (unsigned char *)x; + tmp = w0[0]; + w0[0] = w0[1]; + w0[1] = w0[2]; + w0[2] = w0[3]; + w0[3] = tmp; +} + +static void KeyExpansion(const unsigned char *key, u64 *w, + int nr, int nk) +{ + u32 rcon; + uni prev; + u32 temp; + int i, n; + + memcpy(w, key, nk*4); + memcpy(&rcon, "\1\0\0\0", 4); + n = nk/2; + prev.d = w[n-1]; + for (i = n; i < (nr+1)*2; i++) { + temp = prev.w[1]; + if (i % n == 0) { + RotWord(&temp); + SubWord(&temp); + temp ^= rcon; + XtimeWord(&rcon); + } else if (nk > 6 && i % n == 2) { + SubWord(&temp); + } + prev.d = w[i-n]; + prev.w[0] ^= temp; + prev.w[1] ^= prev.w[0]; + w[i] = prev.d; + } +} + +/** + * Expand the cipher key into the encryption key schedule. + */ +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + u64 *rk; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = (u64*)key->rd_key; + + if (bits == 128) + key->rounds = 10; + else if (bits == 192) + key->rounds = 12; + else + key->rounds = 14; + + KeyExpansion(userKey, rk, key->rounds, bits/32); + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + return AES_set_encrypt_key(userKey, bits, key); +} + +/* + * Encrypt a single block + * in and out can overlap + */ +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + const u64 *rk; + + assert(in && out && key); + rk = (u64*)key->rd_key; + + Cipher(in, out, rk, key->rounds); +} + +/* + * Decrypt a single block + * in and out can overlap + */ +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + const u64 *rk; + + assert(in && out && key); + rk = (u64*)key->rd_key; + + InvCipher(in, out, rk, key->rounds); +} + +# ifndef OPENSSL_SMALL_FOOTPRINT +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char *ivec); + +static void RawToBits(const u8 raw[64], u64 bits[8]) +{ + int i, j; + u64 in, out; + + memset(bits, 0, 64); + for (i = 0; i < 8; i++) { + in = 0; + for (j = 0; j < 8; j++) + in |= ((u64)raw[i * 8 + j]) << (8 * j); + out = in & 0xF0F0F0F00F0F0F0FuLL; + out |= (in & 0x0F0F0F0F00000000uLL) >> 28; + out |= (in & 0x00000000F0F0F0F0uLL) << 28; + in = out & 0xCCCC3333CCCC3333uLL; + in |= (out & 0x3333000033330000uLL) >> 14; + in |= (out & 0x0000CCCC0000CCCCuLL) << 14; + out = in & 0xAA55AA55AA55AA55uLL; + out |= (in & 0x5500550055005500uLL) >> 7; + out |= (in & 0x00AA00AA00AA00AAuLL) << 7; + for (j = 0; j < 8; j++) { + bits[j] |= (out & 0xFFuLL) << (8 * i); + out = out >> 8; + } + } +} + +static void BitsToRaw(const u64 bits[8], u8 raw[64]) +{ + int i, j; + u64 in, out; + + for (i = 0; i < 8; i++) { + in = 0; + for (j = 0; j < 8; j++) + in |= ((bits[j] >> (8 * i)) & 0xFFuLL) << (8 * j); + out = in & 0xF0F0F0F00F0F0F0FuLL; + out |= (in & 0x0F0F0F0F00000000uLL) >> 28; + out |= (in & 0x00000000F0F0F0F0uLL) << 28; + in = out & 0xCCCC3333CCCC3333uLL; + in |= (out & 0x3333000033330000uLL) >> 14; + in |= (out & 0x0000CCCC0000CCCCuLL) << 14; + out = in & 0xAA55AA55AA55AA55uLL; + out |= (in & 0x5500550055005500uLL) >> 7; + out |= (in & 0x00AA00AA00AA00AAuLL) << 7; + for (j = 0; j < 8; j++) { + raw[i * 8 + j] = (u8)out; + out = out >> 8; + } + } +} + +static void BitsXtime(u64 state[8]) +{ + u64 b; + + b = state[7]; + state[7] = state[6]; + state[6] = state[5]; + state[5] = state[4]; + state[4] = state[3] ^ b; + state[3] = state[2] ^ b; + state[2] = state[1]; + state[1] = state[0] ^ b; + state[0] = b; +} + +/* + * This S-box implementation follows a circuit described in + * Boyar and Peralta: "A new combinational logic minimization + * technique with applications to cryptology." + * https://eprint.iacr.org/2009/191.pdf + * + * The math is similar to above, in that it uses + * a tower field of GF(2^2^2^2) but with a different + * basis representation, that is better suited to + * logic designs. + */ +static void BitsSub(u64 state[8]) +{ + u64 x0, x1, x2, x3, x4, x5, x6, x7; + u64 y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11; + u64 y12, y13, y14, y15, y16, y17, y18, y19, y20, y21; + u64 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11; + u64 t12, t13, t14, t15, t16, t17, t18, t19, t20, t21; + u64 t22, t23, t24, t25, t26, t27, t28, t29, t30, t31; + u64 t32, t33, t34, t35, t36, t37, t38, t39, t40, t41; + u64 t42, t43, t44, t45, t46, t47, t48, t49, t50, t51; + u64 t52, t53, t54, t55, t56, t57, t58, t59, t60, t61; + u64 t62, t63, t64, t65, t66, t67; + u64 z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11; + u64 z12, z13, z14, z15, z16, z17; + u64 s0, s1, s2, s3, s4, s5, s6, s7; + + x7 = state[0]; + x6 = state[1]; + x5 = state[2]; + x4 = state[3]; + x3 = state[4]; + x2 = state[5]; + x1 = state[6]; + x0 = state[7]; + y14 = x3 ^ x5; + y13 = x0 ^ x6; + y9 = x0 ^ x3; + y8 = x0 ^ x5; + t0 = x1 ^ x2; + y1 = t0 ^ x7; + y4 = y1 ^ x3; + y12 = y13 ^ y14; + y2 = y1 ^ x0; + y5 = y1 ^ x6; + y3 = y5 ^ y8; + t1 = x4 ^ y12; + y15 = t1 ^ x5; + y20 = t1 ^ x1; + y6 = y15 ^ x7; + y10 = y15 ^ t0; + y11 = y20 ^ y9; + y7 = x7 ^ y11; + y17 = y10 ^ y11; + y19 = y10 ^ y8; + y16 = t0 ^ y11; + y21 = y13 ^ y16; + y18 = x0 ^ y16; + t2 = y12 & y15; + t3 = y3 & y6; + t4 = t3 ^ t2; + t5 = y4 & x7; + t6 = t5 ^ t2; + t7 = y13 & y16; + t8 = y5 & y1; + t9 = t8 ^ t7; + t10 = y2 & y7; + t11 = t10 ^ t7; + t12 = y9 & y11; + t13 = y14 & y17; + t14 = t13 ^ t12; + t15 = y8 & y10; + t16 = t15 ^ t12; + t17 = t4 ^ t14; + t18 = t6 ^ t16; + t19 = t9 ^ t14; + t20 = t11 ^ t16; + t21 = t17 ^ y20; + t22 = t18 ^ y19; + t23 = t19 ^ y21; + t24 = t20 ^ y18; + t25 = t21 ^ t22; + t26 = t21 & t23; + t27 = t24 ^ t26; + t28 = t25 & t27; + t29 = t28 ^ t22; + t30 = t23 ^ t24; + t31 = t22 ^ t26; + t32 = t31 & t30; + t33 = t32 ^ t24; + t34 = t23 ^ t33; + t35 = t27 ^ t33; + t36 = t24 & t35; + t37 = t36 ^ t34; + t38 = t27 ^ t36; + t39 = t29 & t38; + t40 = t25 ^ t39; + t41 = t40 ^ t37; + t42 = t29 ^ t33; + t43 = t29 ^ t40; + t44 = t33 ^ t37; + t45 = t42 ^ t41; + z0 = t44 & y15; + z1 = t37 & y6; + z2 = t33 & x7; + z3 = t43 & y16; + z4 = t40 & y1; + z5 = t29 & y7; + z6 = t42 & y11; + z7 = t45 & y17; + z8 = t41 & y10; + z9 = t44 & y12; + z10 = t37 & y3; + z11 = t33 & y4; + z12 = t43 & y13; + z13 = t40 & y5; + z14 = t29 & y2; + z15 = t42 & y9; + z16 = t45 & y14; + z17 = t41 & y8; + t46 = z15 ^ z16; + t47 = z10 ^ z11; + t48 = z5 ^ z13; + t49 = z9 ^ z10; + t50 = z2 ^ z12; + t51 = z2 ^ z5; + t52 = z7 ^ z8; + t53 = z0 ^ z3; + t54 = z6 ^ z7; + t55 = z16 ^ z17; + t56 = z12 ^ t48; + t57 = t50 ^ t53; + t58 = z4 ^ t46; + t59 = z3 ^ t54; + t60 = t46 ^ t57; + t61 = z14 ^ t57; + t62 = t52 ^ t58; + t63 = t49 ^ t58; + t64 = z4 ^ t59; + t65 = t61 ^ t62; + t66 = z1 ^ t63; + s0 = t59 ^ t63; + s6 = ~(t56 ^ t62); + s7 = ~(t48 ^ t60); + t67 = t64 ^ t65; + s3 = t53 ^ t66; + s4 = t51 ^ t66; + s5 = t47 ^ t65; + s1 = ~(t64 ^ s3); + s2 = ~(t55 ^ t67); + state[0] = s7; + state[1] = s6; + state[2] = s5; + state[3] = s4; + state[4] = s3; + state[5] = s2; + state[6] = s1; + state[7] = s0; +} + +static void BitsShiftRows(u64 state[8]) +{ + u64 s, s0; + int i; + + for (i = 0; i < 8; i++) { + s = state[i]; + s0 = s & 0x1111111111111111uLL; + s0 |= ((s & 0x2220222022202220uLL) >> 4) | ((s & 0x0002000200020002uLL) << 12); + s0 |= ((s & 0x4400440044004400uLL) >> 8) | ((s & 0x0044004400440044uLL) << 8); + s0 |= ((s & 0x8000800080008000uLL) >> 12) | ((s & 0x0888088808880888uLL) << 4); + state[i] = s0; + } +} + +static void BitsMixColumns(u64 state[8]) +{ + u64 s1, s; + u64 s0[8]; + int i; + + for (i = 0; i < 8; i++) { + s1 = state[i]; + s = s1; + s ^= ((s & 0xCCCCCCCCCCCCCCCCuLL) >> 2) | ((s & 0x3333333333333333uLL) << 2); + s ^= ((s & 0xAAAAAAAAAAAAAAAAuLL) >> 1) | ((s & 0x5555555555555555uLL) << 1); + s ^= s1; + s0[i] = s; + } + BitsXtime(state); + for (i = 0; i < 8; i++) { + s1 = state[i]; + s = s0[i]; + s ^= s1; + s ^= ((s1 & 0xEEEEEEEEEEEEEEEEuLL) >> 1) | ((s1 & 0x1111111111111111uLL) << 3); + state[i] = s; + } +} + +static void BitsAddRoundKey(u64 state[8], const u64 key[8]) +{ + int i; + + for (i = 0; i < 8; i++) + state[i] ^= key[i]; +} + +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char *ivec) +{ + struct { + u8 cipher[64]; + u64 state[8]; + u64 rd_key[AES_MAXNR + 1][8]; + } *bs; + u32 ctr32; + int i; + + ctr32 = GETU32(ivec + 12); + if (blocks >= 4 + && (bs = OPENSSL_malloc(sizeof(*bs)))) { + for (i = 0; i < key->rounds + 1; i++) { + memcpy(bs->cipher + 0, &key->rd_key[4 * i], 16); + memcpy(bs->cipher + 16, bs->cipher, 16); + memcpy(bs->cipher + 32, bs->cipher, 32); + RawToBits(bs->cipher, bs->rd_key[i]); + } + while (blocks) { + memcpy(bs->cipher, ivec, 12); + PUTU32(bs->cipher + 12, ctr32); + ctr32++; + memcpy(bs->cipher + 16, ivec, 12); + PUTU32(bs->cipher + 28, ctr32); + ctr32++; + memcpy(bs->cipher + 32, ivec, 12); + PUTU32(bs->cipher + 44, ctr32); + ctr32++; + memcpy(bs->cipher + 48, ivec, 12); + PUTU32(bs->cipher + 60, ctr32); + ctr32++; + RawToBits(bs->cipher, bs->state); + BitsAddRoundKey(bs->state, bs->rd_key[0]); + for (i = 1; i < key->rounds; i++) { + BitsSub(bs->state); + BitsShiftRows(bs->state); + BitsMixColumns(bs->state); + BitsAddRoundKey(bs->state, bs->rd_key[i]); + } + BitsSub(bs->state); + BitsShiftRows(bs->state); + BitsAddRoundKey(bs->state, bs->rd_key[key->rounds]); + BitsToRaw(bs->state, bs->cipher); + for (i = 0; i < 64 && blocks; i++) { + out[i] = in[i] ^ bs->cipher[i]; + if ((i & 15) == 15) + blocks--; + } + in += i; + out += i; + } + OPENSSL_clear_free(bs, sizeof(*bs)); + } else { + unsigned char cipher[16]; + + while (blocks) { + memcpy(cipher, ivec, 12); + PUTU32(cipher + 12, ctr32); + AES_encrypt(cipher, cipher, key); + for (i = 0; i < 16; i++) + out[i] = in[i] ^ cipher[i]; + in += 16; + out += 16; + ctr32++; + blocks--; + } + } +} +# endif +#elif !defined(AES_ASM) /*- Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; diff --git a/deps/openssl/openssl/crypto/aes/aes_local.h b/deps/openssl/openssl/crypto/aes/aes_local.h index cc8456861d928e..a9c0059e52ccbc 100644 --- a/deps/openssl/openssl/crypto/aes/aes_local.h +++ b/deps/openssl/openssl/crypto/aes/aes_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,6 +24,7 @@ # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } # endif +typedef unsigned long long u64; # ifdef AES_LONG typedef unsigned long u32; # else diff --git a/deps/openssl/openssl/crypto/asn1/asn1_lib.c b/deps/openssl/openssl/crypto/asn1/asn1_lib.c index a7d32ae5e2c3cf..366afc5f6c6b52 100644 --- a/deps/openssl/openssl/crypto/asn1/asn1_lib.c +++ b/deps/openssl/openssl/crypto/asn1/asn1_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -268,18 +268,29 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) return ret; } -int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) { unsigned char *c; const char *data = _data; + size_t len; - if (len < 0) { + if (len_in < 0) { if (data == NULL) return 0; - else - len = strlen(data); + len = strlen(data); + } else { + len = (size_t)len_in; + } + /* + * Verify that the length fits within an integer for assignment to + * str->length below. The additional 1 is subtracted to allow for the + * '\0' terminator even though this isn't strictly necessary. + */ + if (len > INT_MAX - 1) { + ASN1err(0, ASN1_R_TOO_LARGE); + return 0; } - if ((str->length <= len) || (str->data == NULL)) { + if ((size_t)str->length <= len || str->data == NULL) { c = str->data; str->data = OPENSSL_realloc(c, len + 1); if (str->data == NULL) { diff --git a/deps/openssl/openssl/crypto/bio/bss_acpt.c b/deps/openssl/openssl/crypto/bio/bss_acpt.c index b38e47a592f44f..5a2cb50dfc39fe 100644 --- a/deps/openssl/openssl/crypto/bio/bss_acpt.c +++ b/deps/openssl/openssl/crypto/bio/bss_acpt.c @@ -222,10 +222,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) break; case ACPT_S_CREATE_SOCKET: - ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), - BIO_ADDRINFO_socktype(c->addr_iter), - BIO_ADDRINFO_protocol(c->addr_iter), 0); - if (ret == (int)INVALID_SOCKET) { + s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), + BIO_ADDRINFO_socktype(c->addr_iter), + BIO_ADDRINFO_protocol(c->addr_iter), 0); + if (s == (int)INVALID_SOCKET) { SYSerr(SYS_F_SOCKET, get_last_socket_error()); ERR_add_error_data(4, "hostname=", c->param_addr, @@ -233,9 +233,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c) BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); goto exit_loop; } - c->accept_sock = ret; - b->num = ret; + c->accept_sock = s; + b->num = s; c->state = ACPT_S_LISTEN; + s = -1; break; case ACPT_S_LISTEN: diff --git a/deps/openssl/openssl/crypto/ec/ec_asn1.c b/deps/openssl/openssl/crypto/ec/ec_asn1.c index 336afc989d3016..006f9a5dea1781 100644 --- a/deps/openssl/openssl/crypto/ec/ec_asn1.c +++ b/deps/openssl/openssl/crypto/ec/ec_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1297,5 +1297,7 @@ int ECDSA_size(const EC_KEY *r) i = i2d_ASN1_INTEGER(&bs, NULL); i += i; /* r and s */ ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + if (ret < 0) + return 0; return ret; } diff --git a/deps/openssl/openssl/crypto/ec/ec_lib.c b/deps/openssl/openssl/crypto/ec/ec_lib.c index 3554ada82797b9..6832383cad5181 100644 --- a/deps/openssl/openssl/crypto/ec/ec_lib.c +++ b/deps/openssl/openssl/crypto/ec/ec_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -1007,14 +1007,14 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t i = 0; BN_CTX *new_ctx = NULL; - if ((scalar == NULL) && (num == 0)) { - return EC_POINT_set_to_infinity(group, r); - } - if (!ec_point_is_compat(r, group)) { ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; } + + if (scalar == NULL && num == 0) + return EC_POINT_set_to_infinity(group, r); + for (i = 0; i < num; i++) { if (!ec_point_is_compat(points[i], group)) { ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); diff --git a/deps/openssl/openssl/crypto/ec/ec_mult.c b/deps/openssl/openssl/crypto/ec/ec_mult.c index 7980a6728288d8..9a1e3974ed9e29 100644 --- a/deps/openssl/openssl/crypto/ec/ec_mult.c +++ b/deps/openssl/openssl/crypto/ec/ec_mult.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -260,17 +260,10 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, goto err; } - /*- - * Apply coordinate blinding for EC_POINT. - * - * The underlying EC_METHOD can optionally implement this function: - * ec_point_blind_coordinates() returns 0 in case of errors or 1 on - * success or if coordinate blinding is not implemented for this - * group. - */ - if (!ec_point_blind_coordinates(group, p, ctx)) { - ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE); - goto err; + /* ensure input point is in affine coords for ladder step efficiency */ + if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) { + ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB); + goto err; } /* Initialize the Montgomery ladder */ @@ -747,6 +740,20 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, if (r_is_at_infinity) { if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err; + + /*- + * Apply coordinate blinding for EC_POINT. + * + * The underlying EC_METHOD can optionally implement this function: + * ec_point_blind_coordinates() returns 0 in case of errors or 1 on + * success or if coordinate blinding is not implemented for this + * group. + */ + if (!ec_point_blind_coordinates(group, r, ctx)) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_POINT_COORDINATES_BLIND_FAILURE); + goto err; + } + r_is_at_infinity = 0; } else { if (!EC_POINT_add diff --git a/deps/openssl/openssl/crypto/ec/ecp_smpl.c b/deps/openssl/openssl/crypto/ec/ecp_smpl.c index b354bfe9ce9ee4..b3110ec89dbe21 100644 --- a/deps/openssl/openssl/crypto/ec/ecp_smpl.c +++ b/deps/openssl/openssl/crypto/ec/ecp_smpl.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -1372,6 +1372,7 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, * Computes the multiplicative inverse of a in GF(p), storing the result in r. * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error. * Since we don't have a Mont structure here, SCA hardening is with blinding. + * NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.) */ int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) @@ -1431,112 +1432,133 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, temp = BN_CTX_get(ctx); if (temp == NULL) { ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE); - goto err; + goto end; } - /* make sure lambda is not zero */ + /*- + * Make sure lambda is not zero. + * If the RNG fails, we cannot blind but nevertheless want + * code to continue smoothly and not clobber the error stack. + */ do { - if (!BN_priv_rand_range(lambda, group->field)) { - ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB); - goto err; + ERR_set_mark(); + ret = BN_priv_rand_range(lambda, group->field); + ERR_pop_to_mark(); + if (ret == 0) { + ret = 1; + goto end; } } while (BN_is_zero(lambda)); /* if field_encode defined convert between representations */ - if (group->meth->field_encode != NULL - && !group->meth->field_encode(group, lambda, lambda, ctx)) - goto err; - if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)) - goto err; - if (!group->meth->field_sqr(group, temp, lambda, ctx)) - goto err; - if (!group->meth->field_mul(group, p->X, p->X, temp, ctx)) - goto err; - if (!group->meth->field_mul(group, temp, temp, lambda, ctx)) - goto err; - if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx)) - goto err; - p->Z_is_one = 0; + if ((group->meth->field_encode != NULL + && !group->meth->field_encode(group, lambda, lambda, ctx)) + || !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx) + || !group->meth->field_sqr(group, temp, lambda, ctx) + || !group->meth->field_mul(group, p->X, p->X, temp, ctx) + || !group->meth->field_mul(group, temp, temp, lambda, ctx) + || !group->meth->field_mul(group, p->Y, p->Y, temp, ctx)) + goto end; + p->Z_is_one = 0; ret = 1; - err: + end: BN_CTX_end(ctx); return ret; } /*- - * Set s := p, r := 2p. + * Input: + * - p: affine coordinates + * + * Output: + * - s := p, r := 2p: blinded projective (homogeneous) coordinates * * For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve - * multiplication resistant against side channel attacks" appendix, as described - * at + * multiplication resistant against side channel attacks" appendix, described at * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2 + * simplified for Z1=1. * - * The input point p will be in randomized Jacobian projective coords: - * x = X/Z**2, y=Y/Z**3 - * - * The output points p, s, and r are converted to standard (homogeneous) - * projective coords: - * x = X/Z, y=Y/Z + * Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z) + * for any non-zero \lambda that holds for projective (homogeneous) coords. */ int ec_GFp_simple_ladder_pre(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, EC_POINT *p, BN_CTX *ctx) { - BIGNUM *t1, *t2, *t3, *t4, *t5, *t6 = NULL; + BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL; - t1 = r->Z; - t2 = r->Y; + t1 = s->Z; + t2 = r->Z; t3 = s->X; t4 = r->X; t5 = s->Y; - t6 = s->Z; - - /* convert p: (X,Y,Z) -> (XZ,Y,Z**3) */ - if (!group->meth->field_mul(group, p->X, p->X, p->Z, ctx) - || !group->meth->field_sqr(group, t1, p->Z, ctx) - || !group->meth->field_mul(group, p->Z, p->Z, t1, ctx) - /* r := 2p */ - || !group->meth->field_sqr(group, t2, p->X, ctx) - || !group->meth->field_sqr(group, t3, p->Z, ctx) - || !group->meth->field_mul(group, t4, t3, group->a, ctx) - || !BN_mod_sub_quick(t5, t2, t4, group->field) - || !BN_mod_add_quick(t2, t2, t4, group->field) - || !group->meth->field_sqr(group, t5, t5, ctx) - || !group->meth->field_mul(group, t6, t3, group->b, ctx) - || !group->meth->field_mul(group, t1, p->X, p->Z, ctx) - || !group->meth->field_mul(group, t4, t1, t6, ctx) - || !BN_mod_lshift_quick(t4, t4, 3, group->field) + + if (!p->Z_is_one /* r := 2p */ + || !group->meth->field_sqr(group, t3, p->X, ctx) + || !BN_mod_sub_quick(t4, t3, group->a, group->field) + || !group->meth->field_sqr(group, t4, t4, ctx) + || !group->meth->field_mul(group, t5, p->X, group->b, ctx) + || !BN_mod_lshift_quick(t5, t5, 3, group->field) /* r->X coord output */ - || !BN_mod_sub_quick(r->X, t5, t4, group->field) - || !group->meth->field_mul(group, t1, t1, t2, ctx) - || !group->meth->field_mul(group, t2, t3, t6, ctx) - || !BN_mod_add_quick(t1, t1, t2, group->field) + || !BN_mod_sub_quick(r->X, t4, t5, group->field) + || !BN_mod_add_quick(t1, t3, group->a, group->field) + || !group->meth->field_mul(group, t2, p->X, t1, ctx) + || !BN_mod_add_quick(t2, group->b, t2, group->field) /* r->Z coord output */ - || !BN_mod_lshift_quick(r->Z, t1, 2, group->field) - || !EC_POINT_copy(s, p)) + || !BN_mod_lshift_quick(r->Z, t2, 2, group->field)) + return 0; + + /* make sure lambda (r->Y here for storage) is not zero */ + do { + if (!BN_priv_rand_range(r->Y, group->field)) + return 0; + } while (BN_is_zero(r->Y)); + + /* make sure lambda (s->Z here for storage) is not zero */ + do { + if (!BN_priv_rand_range(s->Z, group->field)) + return 0; + } while (BN_is_zero(s->Z)); + + /* if field_encode defined convert between representations */ + if (group->meth->field_encode != NULL + && (!group->meth->field_encode(group, r->Y, r->Y, ctx) + || !group->meth->field_encode(group, s->Z, s->Z, ctx))) + return 0; + + /* blind r and s independently */ + if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx) + || !group->meth->field_mul(group, r->X, r->X, r->Y, ctx) + || !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */ return 0; r->Z_is_one = 0; s->Z_is_one = 0; - p->Z_is_one = 0; return 1; } /*- - * Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi + * Input: + * - s, r: projective (homogeneous) coordinates + * - p: affine coordinates + * + * Output: + * - s := r + s, r := 2r: projective (homogeneous) coordinates + * + * Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi * "A fast parallel elliptic curve multiplication resistant against side channel * attacks", as described at - * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-4 + * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4 */ int ec_GFp_simple_ladder_step(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, EC_POINT *p, BN_CTX *ctx) { int ret = 0; - BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7 = NULL; + BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL; BN_CTX_start(ctx); t0 = BN_CTX_get(ctx); @@ -1546,50 +1568,47 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group, t4 = BN_CTX_get(ctx); t5 = BN_CTX_get(ctx); t6 = BN_CTX_get(ctx); - t7 = BN_CTX_get(ctx); - if (t7 == NULL - || !group->meth->field_mul(group, t0, r->X, s->X, ctx) - || !group->meth->field_mul(group, t1, r->Z, s->Z, ctx) - || !group->meth->field_mul(group, t2, r->X, s->Z, ctx) + if (t6 == NULL + || !group->meth->field_mul(group, t6, r->X, s->X, ctx) + || !group->meth->field_mul(group, t0, r->Z, s->Z, ctx) + || !group->meth->field_mul(group, t4, r->X, s->Z, ctx) || !group->meth->field_mul(group, t3, r->Z, s->X, ctx) - || !group->meth->field_mul(group, t4, group->a, t1, ctx) - || !BN_mod_add_quick(t0, t0, t4, group->field) - || !BN_mod_add_quick(t4, t3, t2, group->field) - || !group->meth->field_mul(group, t0, t4, t0, ctx) - || !group->meth->field_sqr(group, t1, t1, ctx) - || !BN_mod_lshift_quick(t7, group->b, 2, group->field) - || !group->meth->field_mul(group, t1, t7, t1, ctx) - || !BN_mod_lshift1_quick(t0, t0, group->field) - || !BN_mod_add_quick(t0, t1, t0, group->field) - || !BN_mod_sub_quick(t1, t2, t3, group->field) - || !group->meth->field_sqr(group, t1, t1, ctx) - || !group->meth->field_mul(group, t3, t1, p->X, ctx) - || !group->meth->field_mul(group, t0, p->Z, t0, ctx) - /* s->X coord output */ - || !BN_mod_sub_quick(s->X, t0, t3, group->field) - /* s->Z coord output */ - || !group->meth->field_mul(group, s->Z, p->Z, t1, ctx) - || !group->meth->field_sqr(group, t3, r->X, ctx) - || !group->meth->field_sqr(group, t2, r->Z, ctx) - || !group->meth->field_mul(group, t4, t2, group->a, ctx) - || !BN_mod_add_quick(t5, r->X, r->Z, group->field) - || !group->meth->field_sqr(group, t5, t5, ctx) - || !BN_mod_sub_quick(t5, t5, t3, group->field) - || !BN_mod_sub_quick(t5, t5, t2, group->field) - || !BN_mod_sub_quick(t6, t3, t4, group->field) - || !group->meth->field_sqr(group, t6, t6, ctx) - || !group->meth->field_mul(group, t0, t2, t5, ctx) - || !group->meth->field_mul(group, t0, t7, t0, ctx) - /* r->X coord output */ - || !BN_mod_sub_quick(r->X, t6, t0, group->field) + || !group->meth->field_mul(group, t5, group->a, t0, ctx) + || !BN_mod_add_quick(t5, t6, t5, group->field) || !BN_mod_add_quick(t6, t3, t4, group->field) - || !group->meth->field_sqr(group, t3, t2, ctx) - || !group->meth->field_mul(group, t7, t3, t7, ctx) - || !group->meth->field_mul(group, t5, t5, t6, ctx) + || !group->meth->field_mul(group, t5, t6, t5, ctx) + || !group->meth->field_sqr(group, t0, t0, ctx) + || !BN_mod_lshift_quick(t2, group->b, 2, group->field) + || !group->meth->field_mul(group, t0, t2, t0, ctx) || !BN_mod_lshift1_quick(t5, t5, group->field) + || !BN_mod_sub_quick(t3, t4, t3, group->field) + /* s->Z coord output */ + || !group->meth->field_sqr(group, s->Z, t3, ctx) + || !group->meth->field_mul(group, t4, s->Z, p->X, ctx) + || !BN_mod_add_quick(t0, t0, t5, group->field) + /* s->X coord output */ + || !BN_mod_sub_quick(s->X, t0, t4, group->field) + || !group->meth->field_sqr(group, t4, r->X, ctx) + || !group->meth->field_sqr(group, t5, r->Z, ctx) + || !group->meth->field_mul(group, t6, t5, group->a, ctx) + || !BN_mod_add_quick(t1, r->X, r->Z, group->field) + || !group->meth->field_sqr(group, t1, t1, ctx) + || !BN_mod_sub_quick(t1, t1, t4, group->field) + || !BN_mod_sub_quick(t1, t1, t5, group->field) + || !BN_mod_sub_quick(t3, t4, t6, group->field) + || !group->meth->field_sqr(group, t3, t3, ctx) + || !group->meth->field_mul(group, t0, t5, t1, ctx) + || !group->meth->field_mul(group, t0, t2, t0, ctx) + /* r->X coord output */ + || !BN_mod_sub_quick(r->X, t3, t0, group->field) + || !BN_mod_add_quick(t3, t4, t6, group->field) + || !group->meth->field_sqr(group, t4, t5, ctx) + || !group->meth->field_mul(group, t4, t4, t2, ctx) + || !group->meth->field_mul(group, t1, t1, t3, ctx) + || !BN_mod_lshift1_quick(t1, t1, group->field) /* r->Z coord output */ - || !BN_mod_add_quick(r->Z, t7, t5, group->field)) + || !BN_mod_add_quick(r->Z, t4, t1, group->field)) goto err; ret = 1; @@ -1600,17 +1619,23 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group, } /*- + * Input: + * - s, r: projective (homogeneous) coordinates + * - p: affine coordinates + * + * Output: + * - r := (x,y): affine coordinates + * * Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass - * Elliptic Curves and Side-Channel Attacks", modified to work in projective - * coordinates and return r in Jacobian projective coordinates. + * Elliptic Curves and Side-Channel Attacks", modified to work in mixed + * projective coords, i.e. p is affine and (r,s) in projective (homogeneous) + * coords, and return r in affine coordinates. * - * X4 = two*Y1*X2*Z3*Z2*Z1; - * Y4 = two*b*Z3*SQR(Z2*Z1) + Z3*(a*Z2*Z1+X1*X2)*(X1*Z2+X2*Z1) - X3*SQR(X1*Z2-X2*Z1); - * Z4 = two*Y1*Z3*SQR(Z2)*Z1; + * X4 = two*Y1*X2*Z3*Z2; + * Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2); + * Z4 = two*Y1*Z3*SQR(Z2); * * Z4 != 0 because: - * - Z1==0 implies p is at infinity, which would have caused an early exit in - * the caller; * - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch); * - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch); * - Y1==0 implies p has order 2, so either r or s are infinity and handled by @@ -1627,11 +1652,7 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group, return EC_POINT_set_to_infinity(group, r); if (BN_is_zero(s->Z)) { - /* (X,Y,Z) -> (XZ,YZ**2,Z) */ - if (!group->meth->field_mul(group, r->X, p->X, p->Z, ctx) - || !group->meth->field_sqr(group, r->Z, p->Z, ctx) - || !group->meth->field_mul(group, r->Y, p->Y, r->Z, ctx) - || !BN_copy(r->Z, p->Z) + if (!EC_POINT_copy(r, p) || !EC_POINT_invert(group, r, ctx)) return 0; return 1; @@ -1647,38 +1668,46 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group, t6 = BN_CTX_get(ctx); if (t6 == NULL - || !BN_mod_lshift1_quick(t0, p->Y, group->field) - || !group->meth->field_mul(group, t1, r->X, p->Z, ctx) - || !group->meth->field_mul(group, t2, r->Z, s->Z, ctx) - || !group->meth->field_mul(group, t2, t1, t2, ctx) - || !group->meth->field_mul(group, t3, t2, t0, ctx) - || !group->meth->field_mul(group, t2, r->Z, p->Z, ctx) - || !group->meth->field_sqr(group, t4, t2, ctx) - || !BN_mod_lshift1_quick(t5, group->b, group->field) - || !group->meth->field_mul(group, t4, t4, t5, ctx) - || !group->meth->field_mul(group, t6, t2, group->a, ctx) - || !group->meth->field_mul(group, t5, r->X, p->X, ctx) - || !BN_mod_add_quick(t5, t6, t5, group->field) - || !group->meth->field_mul(group, t6, r->Z, p->X, ctx) - || !BN_mod_add_quick(t2, t6, t1, group->field) - || !group->meth->field_mul(group, t5, t5, t2, ctx) - || !BN_mod_sub_quick(t6, t6, t1, group->field) - || !group->meth->field_sqr(group, t6, t6, ctx) - || !group->meth->field_mul(group, t6, t6, s->X, ctx) - || !BN_mod_add_quick(t4, t5, t4, group->field) - || !group->meth->field_mul(group, t4, t4, s->Z, ctx) - || !BN_mod_sub_quick(t4, t4, t6, group->field) - || !group->meth->field_sqr(group, t5, r->Z, ctx) - || !group->meth->field_mul(group, r->Z, p->Z, s->Z, ctx) - || !group->meth->field_mul(group, r->Z, t5, r->Z, ctx) - || !group->meth->field_mul(group, r->Z, r->Z, t0, ctx) - /* t3 := X, t4 := Y */ - /* (X,Y,Z) -> (XZ,YZ**2,Z) */ - || !group->meth->field_mul(group, r->X, t3, r->Z, ctx) + || !BN_mod_lshift1_quick(t4, p->Y, group->field) + || !group->meth->field_mul(group, t6, r->X, t4, ctx) + || !group->meth->field_mul(group, t6, s->Z, t6, ctx) + || !group->meth->field_mul(group, t5, r->Z, t6, ctx) + || !BN_mod_lshift1_quick(t1, group->b, group->field) + || !group->meth->field_mul(group, t1, s->Z, t1, ctx) || !group->meth->field_sqr(group, t3, r->Z, ctx) - || !group->meth->field_mul(group, r->Y, t4, t3, ctx)) + || !group->meth->field_mul(group, t2, t3, t1, ctx) + || !group->meth->field_mul(group, t6, r->Z, group->a, ctx) + || !group->meth->field_mul(group, t1, p->X, r->X, ctx) + || !BN_mod_add_quick(t1, t1, t6, group->field) + || !group->meth->field_mul(group, t1, s->Z, t1, ctx) + || !group->meth->field_mul(group, t0, p->X, r->Z, ctx) + || !BN_mod_add_quick(t6, r->X, t0, group->field) + || !group->meth->field_mul(group, t6, t6, t1, ctx) + || !BN_mod_add_quick(t6, t6, t2, group->field) + || !BN_mod_sub_quick(t0, t0, r->X, group->field) + || !group->meth->field_sqr(group, t0, t0, ctx) + || !group->meth->field_mul(group, t0, t0, s->X, ctx) + || !BN_mod_sub_quick(t0, t6, t0, group->field) + || !group->meth->field_mul(group, t1, s->Z, t4, ctx) + || !group->meth->field_mul(group, t1, t3, t1, ctx) + || (group->meth->field_decode != NULL + && !group->meth->field_decode(group, t1, t1, ctx)) + || !group->meth->field_inv(group, t1, t1, ctx) + || (group->meth->field_encode != NULL + && !group->meth->field_encode(group, t1, t1, ctx)) + || !group->meth->field_mul(group, r->X, t5, t1, ctx) + || !group->meth->field_mul(group, r->Y, t0, t1, ctx)) goto err; + if (group->meth->field_set_to_one != NULL) { + if (!group->meth->field_set_to_one(group, r->Z, ctx)) + goto err; + } else { + if (!BN_one(r->Z)) + goto err; + } + + r->Z_is_one = 1; ret = 1; err: diff --git a/deps/openssl/openssl/crypto/evp/e_aes.c b/deps/openssl/openssl/crypto/evp/e_aes.c index 4ebceeb95bb548..38c7cd42deb0c2 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes.c +++ b/deps/openssl/openssl/crypto/evp/e_aes.c @@ -130,6 +130,11 @@ void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); #endif +#if !defined(AES_ASM) && !defined(AES_CTR_ASM) \ + && defined(OPENSSL_AES_CONST_TIME) \ + && !defined(OPENSSL_SMALL_FOOTPRINT) +# define AES_CTR_ASM +#endif #ifdef AES_CTR_ASM void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, const AES_KEY *key, diff --git a/deps/openssl/openssl/crypto/rand/build.info b/deps/openssl/openssl/crypto/rand/build.info index df9bac67f04ccb..a4e7900bdbffc0 100644 --- a/deps/openssl/openssl/crypto/rand/build.info +++ b/deps/openssl/openssl/crypto/rand/build.info @@ -2,3 +2,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ randfile.c rand_lib.c rand_err.c rand_egd.c \ rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c + +INCLUDE[drbg_ctr.o]=../modes diff --git a/deps/openssl/openssl/crypto/rand/drbg_ctr.c b/deps/openssl/openssl/crypto/rand/drbg_ctr.c index 93b82f34ceda12..0f0ad1b37be475 100644 --- a/deps/openssl/openssl/crypto/rand/drbg_ctr.c +++ b/deps/openssl/openssl/crypto/rand/drbg_ctr.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,28 +12,25 @@ #include #include #include -#include "internal/thread_once.h" +#include "modes_local.h" #include "internal/thread_once.h" #include "rand_local.h" + /* * Implementation of NIST SP 800-90A CTR DRBG. */ static void inc_128(RAND_DRBG_CTR *ctr) { - int i; - unsigned char c; - unsigned char *p = &ctr->V[15]; - - for (i = 0; i < 16; i++, p--) { - c = *p; - c++; - *p = c; - if (c != 0) { - /* If we didn't wrap around, we're done. */ - break; - } - } + unsigned char *p = &ctr->V[0]; + u32 n = 16, c = 1; + + do { + --n; + c += p[n]; + p[n] = (u8)c; + c >>= 8; + } while (n); } static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen) diff --git a/deps/openssl/openssl/crypto/threads_win.c b/deps/openssl/openssl/crypto/threads_win.c index ba25d2719aadb3..83dccb84fb6848 100644 --- a/deps/openssl/openssl/crypto/threads_win.c +++ b/deps/openssl/openssl/crypto/threads_win.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -155,7 +155,7 @@ int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b) int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) { - *ret = InterlockedExchangeAdd(val, amount) + amount; + *ret = (int)InterlockedExchangeAdd((long volatile *)val, (long)amount) + amount; return 1; } diff --git a/deps/openssl/openssl/crypto/x509/x509_vfy.c b/deps/openssl/openssl/crypto/x509/x509_vfy.c index f28f2d2610f6db..41625e75ad6a65 100644 --- a/deps/openssl/openssl/crypto/x509/x509_vfy.c +++ b/deps/openssl/openssl/crypto/x509/x509_vfy.c @@ -508,6 +508,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) ret = 1; break; } + if ((x->ex_flags & EXFLAG_CA) == 0 + && x->ex_pathlen != -1 + && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ret = 0; + } if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK)) return 0; /* check_purpose() makes the callback as needed */ diff --git a/deps/openssl/openssl/crypto/x509v3/v3_purp.c b/deps/openssl/openssl/crypto/x509v3/v3_purp.c index 2bc8253d2dab3a..f023c6489548b5 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_purp.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_purp.c @@ -384,12 +384,16 @@ static void x509v3_cache_extensions(X509 *x) if (bs->ca) x->ex_flags |= EXFLAG_CA; if (bs->pathlen) { - if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) - || !bs->ca) { + if (bs->pathlen->type == V_ASN1_NEG_INTEGER) { x->ex_flags |= EXFLAG_INVALID; x->ex_pathlen = 0; - } else + } else { x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + if (!bs->ca && x->ex_pathlen != 0) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } + } } else x->ex_pathlen = -1; BASIC_CONSTRAINTS_free(bs); @@ -545,9 +549,11 @@ static void x509v3_cache_extensions(X509 *x) * return codes: * 0 not a CA * 1 is a CA - * 2 basicConstraints absent so "maybe" a CA + * 2 Only possible in older versions of openSSL when basicConstraints are absent + * new versions will not return this value. May be a CA * 3 basicConstraints absent but self signed V1. * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. + * 5 Netscape specific CA Flags present */ static int check_ca(const X509 *x) diff --git a/deps/openssl/openssl/doc/man1/s_time.pod b/deps/openssl/openssl/doc/man1/s_time.pod index ac32f36bc78985..e1a3bef41cfc36 100644 --- a/deps/openssl/openssl/doc/man1/s_time.pod +++ b/deps/openssl/openssl/doc/man1/s_time.pod @@ -14,7 +14,7 @@ B B [B<-cert filename>] [B<-key filename>] [B<-CApath directory>] -[B<-cafile filename>] +[B<-CAfile filename>] [B<-no-CAfile>] [B<-no-CApath>] [B<-reuse>] @@ -202,7 +202,7 @@ L, L, L =head1 COPYRIGHT -Copyright 2004-2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_aes.pod b/deps/openssl/openssl/doc/man3/EVP_aes.pod index 4192a9ec369f90..6377fc9a21b0ab 100644 --- a/deps/openssl/openssl/doc/man3/EVP_aes.pod +++ b/deps/openssl/openssl/doc/man3/EVP_aes.pod @@ -160,6 +160,13 @@ In particular, XTS-AES-128 (B) takes input of a 256-bit key to achieve AES 128-bit security, and XTS-AES-256 (B) takes input of a 512-bit key to achieve AES 256-bit security. +The XTS implementation in OpenSSL does not support streaming. That is there must +only be one L call per L call (and +similarly with the "Decrypt" functions). + +The I parameter to L or L is +the XTS "tweak" value. + =back =head1 RETURN VALUES @@ -176,7 +183,7 @@ L =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/RAND_set_rand_method.pod b/deps/openssl/openssl/doc/man3/RAND_set_rand_method.pod index b120e712e6f3d7..1e9360d220dce4 100644 --- a/deps/openssl/openssl/doc/man3/RAND_set_rand_method.pod +++ b/deps/openssl/openssl/doc/man3/RAND_set_rand_method.pod @@ -33,10 +33,10 @@ RAND_get_rand_method() returns a pointer to the current B. =head1 THE RAND_METHOD STRUCTURE typedef struct rand_meth_st { - void (*seed)(const void *buf, int num); + int (*seed)(const void *buf, int num); int (*bytes)(unsigned char *buf, int num); void (*cleanup)(void); - void (*add)(const void *buf, int num, int randomness); + int (*add)(const void *buf, int num, double entropy); int (*pseudorand)(unsigned char *buf, int num); int (*status)(void); } RAND_METHOD; @@ -60,7 +60,7 @@ L =head1 COPYRIGHT -Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/X509_check_purpose.pod b/deps/openssl/openssl/doc/man3/X509_check_purpose.pod new file mode 100644 index 00000000000000..bc38138743cdd8 --- /dev/null +++ b/deps/openssl/openssl/doc/man3/X509_check_purpose.pod @@ -0,0 +1,74 @@ +=pod + +=head1 NAME + +X509_check_purpose - Check the purpose of a certificate + +=head1 SYNOPSIS + + #include + + int X509_check_purpose(X509 *x, int id, int ca) + +=head1 DESCRIPTION + +This function checks if certificate I was created with the purpose +represented by I. If I is nonzero, then certificate I is +checked to determine if it's a possible CA with various levels of certainty +possibly returned. + +Below are the potential ID's that can be checked: + + # define X509_PURPOSE_SSL_CLIENT 1 + # define X509_PURPOSE_SSL_SERVER 2 + # define X509_PURPOSE_NS_SSL_SERVER 3 + # define X509_PURPOSE_SMIME_SIGN 4 + # define X509_PURPOSE_SMIME_ENCRYPT 5 + # define X509_PURPOSE_CRL_SIGN 6 + # define X509_PURPOSE_ANY 7 + # define X509_PURPOSE_OCSP_HELPER 8 + # define X509_PURPOSE_TIMESTAMP_SIGN 9 + +=head1 RETURN VALUES + +For non-CA checks + +=over 4 + +=item -1 an error condition has occured + +=item E<32>1 if the certificate was created to perform the purpose represented by I + +=item E<32>0 if the certificate was not created to perform the purpose represented by I + +=back + +For CA checks the below integers could be returned with the following meanings: + +=over 4 + +=item -1 an error condition has occured + +=item E<32>0 not a CA or does not have the purpose represented by I + +=item E<32>1 is a CA. + +=item E<32>2 Only possible in old versions of openSSL when basicConstraints are absent. + New versions will not return this value. May be a CA + +=item E<32>3 basicConstraints absent but self signed V1. + +=item E<32>4 basicConstraints absent but keyUsage present and keyCertSign asserted. + +=item E<32>5 legacy Netscape specific CA Flags present + +=back + +=head1 COPYRIGHT + +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. +Licensed under the Apache License 2.0 (the "License"). You may not use this +file except in compliance with the License. You can obtain a copy in the file +LICENSE in the source distribution or at L. + +=cut diff --git a/deps/openssl/openssl/include/openssl/opensslv.h b/deps/openssl/openssl/include/openssl/opensslv.h index 8c697f5f7acc85..17d271f54c7f52 100644 --- a/deps/openssl/openssl/include/openssl/opensslv.h +++ b/deps/openssl/openssl/include/openssl/opensslv.h @@ -39,8 +39,8 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x1010106fL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1f 31 Mar 2020" +# define OPENSSL_VERSION_NUMBER 0x1010107fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1g 21 Apr 2020" /*- * The macros below are to be used for shared library (.so, .dll, ...) diff --git a/deps/openssl/openssl/ssl/t1_lib.c b/deps/openssl/openssl/ssl/t1_lib.c index a254fd5a055913..76b4baa38893f8 100644 --- a/deps/openssl/openssl/ssl/t1_lib.c +++ b/deps/openssl/openssl/ssl/t1_lib.c @@ -2130,7 +2130,7 @@ static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) sigalg = use_pc_sigalgs ? tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]) : s->shared_sigalgs[i]; - if (sig_nid == sigalg->sigandhash) + if (sigalg != NULL && sig_nid == sigalg->sigandhash) return 1; } return 0; diff --git a/deps/openssl/openssl/test/certs/ee-pathlen.pem b/deps/openssl/openssl/test/certs/ee-pathlen.pem new file mode 100644 index 00000000000000..0bcae1d7bdb91e --- /dev/null +++ b/deps/openssl/openssl/test/certs/ee-pathlen.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg +Fw0yMDA0MDMwODA0MTVaGA8yMTIwMDQwNDA4MDQxNVowGTEXMBUGA1UEAwwOc2Vy +dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY +YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT +5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l +Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1 +U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5 +ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn +iIQPYf55NB9KiR+3AgMBAAGjEDAOMAwGA1UdEwQFMAMCAQAwDQYJKoZIhvcNAQEL +BQADggEBAApOUnWWd09I0ts3xa1oK7eakc+fKTF4d7pbGznFNONaCR3KFRgnBVlG +Bm8/oehrrQ28Ad3XPSug34DQQ5kM6JIuaddx50/n4Xkgj8/fgXVA0HXizOJ3QpKC +IojLVajXlQHhpo72VUQuNOha0UxG9daYjS20iXRhanTm9rUz7qQZEugVQCiR0z/f +9NgM7FU9UaSidzH3gZu/Ufc4Ggn6nZV7LM9sf4IUV+KszS1VpcK+9phAmsB6BaAi +cFXvVXZjTNualQgPyPwOD8c+vVCIfIemfF5TZ6fyqpOjprWQAphwrTtfNDSmqRTz +FRhDf+vJERQclgUtg37EgWGKtnNQeRY= +-----END CERTIFICATE----- diff --git a/deps/openssl/openssl/test/certs/setup.sh b/deps/openssl/openssl/test/certs/setup.sh index 2d53ea5b08c6cb..bbe4842a5187ae 100755 --- a/deps/openssl/openssl/test/certs/setup.sh +++ b/deps/openssl/openssl/test/certs/setup.sh @@ -154,7 +154,7 @@ openssl x509 -in sca-cert.pem -trustout \ -addtrust anyExtendedKeyUsage -out sca+anyEKU.pem # Primary leaf cert: ee-cert -# ee variants: expired, issuer-key2, issuer-name2 +# ee variants: expired, issuer-key2, issuer-name2, bad-pathlen # trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth # purpose variants: client # @@ -163,6 +163,8 @@ openssl x509 -in sca-cert.pem -trustout \ ./mkcert.sh genee server.example ee-key ee-cert2 ca-key2 ca-cert2 ./mkcert.sh genee server.example ee-key ee-name2 ca-key ca-name2 ./mkcert.sh genee -p clientAuth server.example ee-key ee-client ca-key ca-cert +./mkcert.sh genee server.example ee-key ee-pathlen ca-key ca-cert \ + -extfile <(echo "basicConstraints=CA:FALSE,pathlen:0") # openssl x509 -in ee-cert.pem -trustout \ -addtrust serverAuth -out ee+serverAuth.pem diff --git a/deps/openssl/openssl/test/recipes/25-test_verify.t b/deps/openssl/openssl/test/recipes/25-test_verify.t index b80a1cde3edde0..cf7842cdfdd90c 100644 --- a/deps/openssl/openssl/test/recipes/25-test_verify.t +++ b/deps/openssl/openssl/test/recipes/25-test_verify.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -27,7 +27,7 @@ sub verify { run(app([@args])); } -plan tests => 135; +plan tests => 137; # Canonical success ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), @@ -222,6 +222,10 @@ ok(verify("ee-client", "sslclient", [qw(ee+clientAuth)], [], "-partial_chain"), "accept direct match with client trust"); ok(!verify("ee-client", "sslclient", [qw(ee-clientAuth)], [], "-partial_chain"), "reject direct match with client mistrust"); +ok(verify("ee-pathlen", "sslserver", [qw(root-cert)], [qw(ca-cert)]), + "accept non-ca with pathlen:0 by default"); +ok(!verify("ee-pathlen", "sslserver", [qw(root-cert)], [qw(ca-cert)], "-x509_strict"), + "reject non-ca with pathlen:0 with strict flag"); # Proxy certificates ok(!verify("pc1-cert", "sslclient", [qw(root-cert)], [qw(ee-client ca-cert)]), diff --git a/deps/openssl/openssl/test/recipes/70-test_sslsigalgs.t b/deps/openssl/openssl/test/recipes/70-test_sslsigalgs.t index b3339ff59f9833..9ea9d05219ca24 100644 --- a/deps/openssl/openssl/test/recipes/70-test_sslsigalgs.t +++ b/deps/openssl/openssl/test/recipes/70-test_sslsigalgs.t @@ -44,7 +44,9 @@ use constant { COMPAT_SIGALGS => 6, SIGALGS_CERT_ALL => 7, SIGALGS_CERT_PKCS => 8, - SIGALGS_CERT_INVALID => 9 + SIGALGS_CERT_INVALID => 9, + UNRECOGNIZED_SIGALGS_CERT => 10, + UNRECOGNIZED_SIGALG => 11 }; #Note: Throughout this test we override the default ciphersuites where TLSv1.2 @@ -53,7 +55,7 @@ use constant { #Test 1: Default sig algs should succeed $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 24; +plan tests => 26; ok(TLSProxy::Message->success, "Default sigalgs"); my $testtype; @@ -282,6 +284,39 @@ SKIP: { ok(TLSProxy::Message->fail, "No matching certificate for sigalgs_cert"); } +SKIP: { + skip "TLS 1.3 disabled", 2 if disabled("tls1_3"); + #Test 25: Send an unrecognized signature_algorithms_cert + # We should be able to skip over the unrecognized value and use a + # valid one that appears later in the list. + $proxy->clear(); + $proxy->filter(\&inject_unrecognized_sigalg); + $proxy->clientflags("-tls1_3"); + # Use -xcert to get SSL_check_chain() to run in the cert_cb. This is + # needed to trigger (e.g.) CVE-2020-1967 + $proxy->serverflags("" . + " -xcert " . srctop_file("test", "certs", "servercert.pem") . + " -xkey " . srctop_file("test", "certs", "serverkey.pem") . + " -xchain " . srctop_file("test", "certs", "rootcert.pem")); + $testtype = UNRECOGNIZED_SIGALGS_CERT; + $proxy->start(); + ok(TLSProxy::Message->success(), "Unrecognized sigalg_cert in ClientHello"); + + #Test 26: Send an unrecognized signature_algorithms + # We should be able to skip over the unrecognized value and use a + # valid one that appears later in the list. + $proxy->clear(); + $proxy->filter(\&inject_unrecognized_sigalg); + $proxy->clientflags("-tls1_3"); + $proxy->serverflags("" . + " -xcert " . srctop_file("test", "certs", "servercert.pem") . + " -xkey " . srctop_file("test", "certs", "serverkey.pem") . + " -xchain " . srctop_file("test", "certs", "rootcert.pem")); + $testtype = UNRECOGNIZED_SIGALG; + $proxy->start(); + ok(TLSProxy::Message->success(), "Unrecognized sigalg in ClientHello"); +} + sub sigalgs_filter @@ -427,3 +462,30 @@ sub modify_cert_verify_sigalg } } } + +sub inject_unrecognized_sigalg +{ + my $proxy = shift; + my $type; + + # We're only interested in the initial ClientHello + if ($proxy->flight != 0) { + return; + } + if ($testtype == UNRECOGNIZED_SIGALGS_CERT) { + $type = TLSProxy::Message::EXT_SIG_ALGS_CERT; + } elsif ($testtype == UNRECOGNIZED_SIGALG) { + $type = TLSProxy::Message::EXT_SIG_ALGS; + } else { + return; + } + + my $ext = pack "C8", + 0x00, 0x06, #Extension length + 0xfe, 0x18, #private use + 0x04, 0x01, #rsa_pkcs1_sha256 + 0x08, 0x04; #rsa_pss_rsae_sha256; + my $message = ${$proxy->message_list}[0]; + $message->set_extension($type, $ext); + $message->repack; +} diff --git a/deps/openssl/openssl/test/sm2_internal_test.c b/deps/openssl/openssl/test/sm2_internal_test.c index 952f688e8b1448..2bb73947ff3bd6 100644 --- a/deps/openssl/openssl/test/sm2_internal_test.c +++ b/deps/openssl/openssl/test/sm2_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,17 +32,18 @@ static size_t fake_rand_size = 0; static int get_faked_bytes(unsigned char *buf, int num) { - int i; - if (fake_rand_bytes == NULL) return saved_rand->bytes(buf, num); - if (!TEST_size_t_le(fake_rand_bytes_offset + num, fake_rand_size)) + if (!TEST_size_t_gt(fake_rand_size, 0)) return 0; - for (i = 0; i != num; ++i) - buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i]; - fake_rand_bytes_offset += num; + while (num-- > 0) { + if (fake_rand_bytes_offset >= fake_rand_size) + fake_rand_bytes_offset = 0; + *buf++ = fake_rand_bytes[fake_rand_bytes_offset++]; + } + return 1; } @@ -175,8 +176,7 @@ static int test_sm2_crypt(const EC_GROUP *group, start_fake_rand(k_hex); if (!TEST_true(sm2_encrypt(key, digest, (const uint8_t *)message, msg_len, - ctext, &ctext_len)) - || !TEST_size_t_eq(fake_rand_bytes_offset, fake_rand_size)) { + ctext, &ctext_len))) { restore_rand(); goto done; } @@ -296,8 +296,7 @@ static int test_sm2_sign(const EC_GROUP *group, start_fake_rand(k_hex); sig = sm2_do_sign(key, EVP_sm3(), (const uint8_t *)userid, strlen(userid), (const uint8_t *)message, msg_len); - if (!TEST_ptr(sig) - || !TEST_size_t_eq(fake_rand_bytes_offset, fake_rand_size)) { + if (!TEST_ptr(sig)) { restore_rand(); goto done; } diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 39e5a9bcc984b6..f21a0b8dd0fd69 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 8 #define V8_MINOR_VERSION 1 #define V8_BUILD_NUMBER 307 -#define V8_PATCH_LEVEL 30 +#define V8_PATCH_LEVEL 31 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/ic/handler-configuration.cc b/deps/v8/src/ic/handler-configuration.cc index 3a57fc8e4f7457..a9bae12482660a 100644 --- a/deps/v8/src/ic/handler-configuration.cc +++ b/deps/v8/src/ic/handler-configuration.cc @@ -200,11 +200,14 @@ KeyedAccessStoreMode StoreHandler::GetKeyedAccessStoreMode( // static Handle StoreHandler::StoreElementTransition( Isolate* isolate, Handle receiver_map, Handle transition, - KeyedAccessStoreMode store_mode) { + KeyedAccessStoreMode store_mode, MaybeHandle prev_validity_cell) { Handle stub = CodeFactory::ElementsTransitionAndStore(isolate, store_mode).code(); - Handle validity_cell = - Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); + Handle validity_cell; + if (!prev_validity_cell.ToHandle(&validity_cell)) { + validity_cell = + Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate); + } Handle handler = isolate->factory()->NewStoreHandler(1); handler->set_smi_handler(*stub); handler->set_validity_cell(*validity_cell); diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h index a0bef4bfcc666b..7f110d17756306 100644 --- a/deps/v8/src/ic/handler-configuration.h +++ b/deps/v8/src/ic/handler-configuration.h @@ -275,10 +275,10 @@ class StoreHandler final : public DataHandler { MaybeObjectHandle maybe_data1 = MaybeObjectHandle(), MaybeObjectHandle maybe_data2 = MaybeObjectHandle()); - static Handle StoreElementTransition(Isolate* isolate, - Handle receiver_map, - Handle transition, - KeyedAccessStoreMode store_mode); + static Handle StoreElementTransition( + Isolate* isolate, Handle receiver_map, Handle transition, + KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell = MaybeHandle()); static Handle StoreProxy(Isolate* isolate, Handle receiver_map, Handle proxy, diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index fcfd5a580365b2..5f6ff322d27132 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -363,9 +363,20 @@ void IC::ConfigureVectorState(Handle name, Handle map, void IC::ConfigureVectorState(Handle name, MapHandles const& maps, MaybeObjectHandles* handlers) { DCHECK(!IsGlobalIC()); + std::vector maps_and_handlers; + DCHECK_EQ(maps.size(), handlers->size()); + for (size_t i = 0; i < maps.size(); i++) { + maps_and_handlers.push_back(MapAndHandler(maps[i], handlers->at(i))); + } + ConfigureVectorState(name, maps_and_handlers); +} + +void IC::ConfigureVectorState( + Handle name, std::vector const& maps_and_handlers) { + DCHECK(!IsGlobalIC()); // Non-keyed ICs don't track the name explicitly. if (!is_keyed()) name = Handle::null(); - nexus()->ConfigurePolymorphic(name, maps, handlers); + nexus()->ConfigurePolymorphic(name, maps_and_handlers); OnFeedbackChanged("Polymorphic"); } @@ -521,6 +532,22 @@ static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps, return true; } +static bool AddOneReceiverMapIfMissing( + std::vector* receiver_maps_and_handlers, + Handle new_receiver_map) { + DCHECK(!new_receiver_map.is_null()); + if (new_receiver_map->is_deprecated()) return false; + for (MapAndHandler map_and_handler : *receiver_maps_and_handlers) { + Handle map = map_and_handler.first; + if (!map.is_null() && map.is_identical_to(new_receiver_map)) { + return false; + } + } + receiver_maps_and_handlers->push_back( + MapAndHandler(new_receiver_map, MaybeObjectHandle())); + return true; +} + bool IC::UpdatePolymorphicIC(Handle name, const MaybeObjectHandle& handler) { DCHECK(IsHandler(*handler)); @@ -528,16 +555,16 @@ bool IC::UpdatePolymorphicIC(Handle name, if (nexus()->GetName() != *name) return false; } Handle map = receiver_map(); - MapHandles maps; - MaybeObjectHandles handlers; - nexus()->ExtractMapsAndHandlers(&maps, &handlers); - int number_of_maps = static_cast(maps.size()); + std::vector maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&maps_and_handlers); + int number_of_maps = static_cast(maps_and_handlers.size()); int deprecated_maps = 0; int handler_to_overwrite = -1; for (int i = 0; i < number_of_maps; i++) { - Handle current_map = maps.at(i); + Handle current_map = maps_and_handlers.at(i).first; + MaybeObjectHandle current_handler = maps_and_handlers.at(i).second; if (current_map->is_deprecated()) { // Filter out deprecated maps to ensure their instances get migrated. ++deprecated_maps; @@ -547,7 +574,7 @@ bool IC::UpdatePolymorphicIC(Handle name, // in the lattice and need to go MEGAMORPHIC instead. There's one // exception to this rule, which is when we're in RECOMPUTE_HANDLER // state, there we allow to migrate to a new handler. - if (handler.is_identical_to(handlers[i]) && + if (handler.is_identical_to(current_handler) && state() != RECOMPUTE_HANDLER) { return false; } @@ -575,16 +602,16 @@ bool IC::UpdatePolymorphicIC(Handle name, } else { if (is_keyed() && nexus()->GetName() != *name) return false; if (handler_to_overwrite >= 0) { - handlers[handler_to_overwrite] = handler; - if (!map.is_identical_to(maps.at(handler_to_overwrite))) { - maps[handler_to_overwrite] = map; + maps_and_handlers[handler_to_overwrite].second = handler; + if (!map.is_identical_to( + maps_and_handlers.at(handler_to_overwrite).first)) { + maps_and_handlers[handler_to_overwrite].first = map; } } else { - maps.push_back(map); - handlers.push_back(handler); + maps_and_handlers.push_back(MapAndHandler(map, handler)); } - ConfigureVectorState(name, maps, &handlers); + ConfigureVectorState(name, maps_and_handlers); } return true; @@ -597,11 +624,10 @@ void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler, } void IC::CopyICToMegamorphicCache(Handle name) { - MapHandles maps; - MaybeObjectHandles handlers; - nexus()->ExtractMapsAndHandlers(&maps, &handlers); - for (size_t i = 0; i < maps.size(); ++i) { - UpdateMegamorphicCache(maps.at(i), name, handlers.at(i)); + std::vector maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&maps_and_handlers); + for (const MapAndHandler& map_and_handler : maps_and_handlers) { + UpdateMegamorphicCache(map_and_handler.first, name, map_and_handler.second); } } @@ -1760,9 +1786,9 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, KeyedAccessStoreMode store_mode, Handle new_receiver_map) { - MapHandles target_receiver_maps; - TargetMaps(&target_receiver_maps); - if (target_receiver_maps.empty()) { + std::vector target_maps_and_handlers; + nexus()->ExtractMapsAndHandlers(&target_maps_and_handlers, true); + if (target_maps_and_handlers.empty()) { Handle monomorphic_map = receiver_map; // If we transitioned to a map that is a more general map than incoming // then use the new map. @@ -1773,7 +1799,8 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, return ConfigureVectorState(Handle(), monomorphic_map, handler); } - for (Handle map : target_receiver_maps) { + for (const MapAndHandler& map_and_handler : target_maps_and_handlers) { + Handle map = map_and_handler.first; if (!map.is_null() && map->instance_type() == JS_PRIMITIVE_WRAPPER_TYPE) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); set_slow_stub_reason("JSPrimitiveWrapper"); @@ -1786,7 +1813,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // Handle those here if the receiver map hasn't changed or it has transitioned // to a more general kind. KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); - Handle previous_receiver_map = target_receiver_maps.at(0); + Handle previous_receiver_map = target_maps_and_handlers.at(0).first; if (state() == MONOMORPHIC) { Handle transitioned_receiver_map = new_receiver_map; if (IsTransitionOfMonomorphicTarget(*previous_receiver_map, @@ -1815,11 +1842,11 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, DCHECK(state() != GENERIC); bool map_added = - AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); + AddOneReceiverMapIfMissing(&target_maps_and_handlers, receiver_map); if (IsTransitionOfMonomorphicTarget(*receiver_map, *new_receiver_map)) { map_added |= - AddOneReceiverMapIfMissing(&target_receiver_maps, new_receiver_map); + AddOneReceiverMapIfMissing(&target_maps_and_handlers, new_receiver_map); } if (!map_added) { @@ -1831,7 +1858,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // If the maximum number of receiver maps has been exceeded, use the // megamorphic version of the IC. - if (static_cast(target_receiver_maps.size()) > + if (static_cast(target_maps_and_handlers.size()) > FLAG_max_polymorphic_map_count) { return; } @@ -1852,14 +1879,15 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, // use the megamorphic stub. if (store_mode != STANDARD_STORE) { size_t external_arrays = 0; - for (Handle map : target_receiver_maps) { + for (MapAndHandler map_and_handler : target_maps_and_handlers) { + Handle map = map_and_handler.first; if (map->has_typed_array_elements()) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); external_arrays++; } } if (external_arrays != 0 && - external_arrays != target_receiver_maps.size()) { + external_arrays != target_maps_and_handlers.size()) { DCHECK(!IsStoreInArrayLiteralICKind(kind())); set_slow_stub_reason( "unsupported combination of external and normal arrays"); @@ -1867,21 +1895,21 @@ void KeyedStoreIC::UpdateStoreElement(Handle receiver_map, } } - MaybeObjectHandles handlers; - handlers.reserve(target_receiver_maps.size()); - StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode); - if (target_receiver_maps.size() == 0) { + StoreElementPolymorphicHandlers(&target_maps_and_handlers, store_mode); + if (target_maps_and_handlers.size() == 0) { Handle handler = StoreElementHandler(receiver_map, store_mode); ConfigureVectorState(Handle(), receiver_map, handler); - } else if (target_receiver_maps.size() == 1) { - ConfigureVectorState(Handle(), target_receiver_maps[0], handlers[0]); + } else if (target_maps_and_handlers.size() == 1) { + ConfigureVectorState(Handle(), target_maps_and_handlers[0].first, + target_maps_and_handlers[0].second); } else { - ConfigureVectorState(Handle(), target_receiver_maps, &handlers); + ConfigureVectorState(Handle(), target_maps_and_handlers); } } Handle KeyedStoreIC::StoreElementHandler( - Handle receiver_map, KeyedAccessStoreMode store_mode) { + Handle receiver_map, KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell) { DCHECK_IMPLIES( receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()), IsStoreInArrayLiteralICKind(kind())); @@ -1917,8 +1945,11 @@ Handle KeyedStoreIC::StoreElementHandler( } if (IsStoreInArrayLiteralICKind(kind())) return code; - Handle validity_cell = - Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); + Handle validity_cell; + if (!prev_validity_cell.ToHandle(&validity_cell)) { + validity_cell = + Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); + } if (validity_cell->IsSmi()) { // There's no prototype validity cell to check, so we can just use the stub. return code; @@ -1930,16 +1961,17 @@ Handle KeyedStoreIC::StoreElementHandler( } void KeyedStoreIC::StoreElementPolymorphicHandlers( - MapHandles* receiver_maps, MaybeObjectHandles* handlers, + std::vector* receiver_maps_and_handlers, KeyedAccessStoreMode store_mode) { - // Filter out deprecated maps to ensure their instances get migrated. - receiver_maps->erase( - std::remove_if( - receiver_maps->begin(), receiver_maps->end(), - [](const Handle& map) { return map->is_deprecated(); }), - receiver_maps->end()); + std::vector> receiver_maps; + for (size_t i = 0; i < receiver_maps_and_handlers->size(); i++) { + receiver_maps.push_back(receiver_maps_and_handlers->at(i).first); + } - for (Handle receiver_map : *receiver_maps) { + for (size_t i = 0; i < receiver_maps_and_handlers->size(); i++) { + Handle receiver_map = receiver_maps_and_handlers->at(i).first; + DCHECK(!receiver_map->is_deprecated()); + MaybeObjectHandle old_handler = receiver_maps_and_handlers->at(i).second; Handle handler; Handle transition; @@ -1952,8 +1984,8 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( } else { { - Map tmap = receiver_map->FindElementsKindTransitionedMap( - isolate(), *receiver_maps); + Map tmap = receiver_map->FindElementsKindTransitionedMap(isolate(), + receiver_maps); if (!tmap.is_null()) { if (receiver_map->is_stable()) { receiver_map->NotifyLeafMapLayoutChange(isolate()); @@ -1962,6 +1994,16 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( } } + MaybeHandle validity_cell; + HeapObject old_handler_obj; + if (!old_handler.is_null() && + old_handler->GetHeapObject(&old_handler_obj) && + old_handler_obj.IsDataHandler()) { + validity_cell = MaybeHandle( + DataHandler::cast(old_handler_obj).validity_cell(), isolate()); + } + // TODO(mythria): Do not recompute the handler if we know there is no + // change in the handler. // TODO(mvstanton): The code below is doing pessimistic elements // transitions. I would like to stop doing that and rely on Allocation // Site Tracking to do a better job of ensuring the data types are what @@ -1970,14 +2012,15 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( if (!transition.is_null()) { TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_ElementsTransitionAndStoreStub); - handler = StoreHandler::StoreElementTransition(isolate(), receiver_map, - transition, store_mode); + handler = StoreHandler::StoreElementTransition( + isolate(), receiver_map, transition, store_mode, validity_cell); } else { - handler = StoreElementHandler(receiver_map, store_mode); + handler = StoreElementHandler(receiver_map, store_mode, validity_cell); } } DCHECK(!handler.is_null()); - handlers->push_back(MaybeObjectHandle(handler)); + receiver_maps_and_handlers->at(i) = + MapAndHandler(receiver_map, MaybeObjectHandle(handler)); } } diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h index 6e17517dcce32c..da4b22a2c27df6 100644 --- a/deps/v8/src/ic/ic.h +++ b/deps/v8/src/ic/ic.h @@ -82,6 +82,8 @@ class IC { // Configure the vector for POLYMORPHIC. void ConfigureVectorState(Handle name, MapHandles const& maps, MaybeObjectHandles* handlers); + void ConfigureVectorState( + Handle name, std::vector const& maps_and_handlers); char TransitionMarkFromState(IC::State state); void TraceIC(const char* type, Handle name); @@ -312,12 +314,13 @@ class KeyedStoreIC : public StoreIC { Handle ComputeTransitionedMap(Handle map, TransitionMode transition_mode); - Handle StoreElementHandler(Handle receiver_map, - KeyedAccessStoreMode store_mode); + Handle StoreElementHandler( + Handle receiver_map, KeyedAccessStoreMode store_mode, + MaybeHandle prev_validity_cell = MaybeHandle()); - void StoreElementPolymorphicHandlers(MapHandles* receiver_maps, - MaybeObjectHandles* handlers, - KeyedAccessStoreMode store_mode); + void StoreElementPolymorphicHandlers( + std::vector* receiver_maps_and_handlers, + KeyedAccessStoreMode store_mode); friend class IC; }; diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc index 732c1e9cd5f786..7028d2b0df4be7 100644 --- a/deps/v8/src/objects/feedback-vector.cc +++ b/deps/v8/src/objects/feedback-vector.cc @@ -899,11 +899,9 @@ void FeedbackNexus::ConfigureMonomorphic(Handle name, } } -void FeedbackNexus::ConfigurePolymorphic(Handle name, - MapHandles const& maps, - MaybeObjectHandles* handlers) { - DCHECK_EQ(handlers->size(), maps.size()); - int receiver_count = static_cast(maps.size()); +void FeedbackNexus::ConfigurePolymorphic( + Handle name, std::vector const& maps_and_handlers) { + int receiver_count = static_cast(maps_and_handlers.size()); DCHECK_GT(receiver_count, 1); Handle array; if (name.is_null()) { @@ -916,10 +914,11 @@ void FeedbackNexus::ConfigurePolymorphic(Handle name, } for (int current = 0; current < receiver_count; ++current) { - Handle map = maps[current]; + Handle map = maps_and_handlers[current].first; array->Set(current * 2, HeapObjectReference::Weak(*map)); - DCHECK(IC::IsHandler(*handlers->at(current))); - array->Set(current * 2 + 1, *handlers->at(current)); + MaybeObjectHandle handler = maps_and_handlers[current].second; + DCHECK(IC::IsHandler(*handler)); + array->Set(current * 2 + 1, *handler); } } @@ -965,11 +964,13 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const { return 0; } -int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, - MaybeObjectHandles* handlers) const { - DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) || - IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) || - IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) || +int FeedbackNexus::ExtractMapsAndHandlers( + std::vector, MaybeObjectHandle>>* maps_and_handlers, + bool drop_deprecated) const { + DCHECK(IsLoadICKind(kind()) || + IsStoreICKind(kind()) | IsKeyedLoadICKind(kind()) || + IsKeyedStoreICKind(kind()) || IsStoreOwnICKind(kind()) || + IsStoreDataPropertyInLiteralKind(kind()) || IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind())); DisallowHeapAllocation no_gc; @@ -990,6 +991,7 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, } const int increment = 2; HeapObject heap_object; + maps_and_handlers->reserve(array.length() / increment); for (int i = 0; i < array.length(); i += increment) { DCHECK(array.Get(i)->IsWeakOrCleared()); if (array.Get(i)->GetHeapObjectIfWeak(&heap_object)) { @@ -997,8 +999,9 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, if (!handler->IsCleared()) { DCHECK(IC::IsHandler(handler)); Map map = Map::cast(heap_object); - maps->push_back(handle(map, isolate)); - handlers->push_back(handle(handler, isolate)); + if (drop_deprecated && map.is_deprecated()) continue; + maps_and_handlers->push_back( + MapAndHandler(handle(map, isolate), handle(handler, isolate))); found++; } } @@ -1009,8 +1012,9 @@ int FeedbackNexus::ExtractMapsAndHandlers(MapHandles* maps, if (!handler->IsCleared()) { DCHECK(IC::IsHandler(handler)); Map map = Map::cast(heap_object); - maps->push_back(handle(map, isolate)); - handlers->push_back(handle(handler, isolate)); + if (drop_deprecated && map.is_deprecated()) return 0; + maps_and_handlers->push_back( + MapAndHandler(handle(map, isolate), handle(handler, isolate))); return 1; } } @@ -1082,14 +1086,14 @@ Name FeedbackNexus::GetName() const { KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const { DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedHasICKind(kind())); - MapHandles maps; - MaybeObjectHandles handlers; if (GetKeyType() == PROPERTY) return STANDARD_LOAD; - ExtractMapsAndHandlers(&maps, &handlers); - for (MaybeObjectHandle const& handler : handlers) { - KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler); + std::vector maps_and_handlers; + ExtractMapsAndHandlers(&maps_and_handlers); + for (MapAndHandler map_and_handler : maps_and_handlers) { + KeyedAccessLoadMode mode = + LoadHandler::GetKeyedAccessLoadMode(*map_and_handler.second); if (mode != STANDARD_LOAD) return mode; } @@ -1150,13 +1154,13 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const { DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind())); KeyedAccessStoreMode mode = STANDARD_STORE; - MapHandles maps; - MaybeObjectHandles handlers; if (GetKeyType() == PROPERTY) return mode; - ExtractMapsAndHandlers(&maps, &handlers); - for (const MaybeObjectHandle& maybe_code_handler : handlers) { + std::vector maps_and_handlers; + ExtractMapsAndHandlers(&maps_and_handlers); + for (const MapAndHandler& map_and_handler : maps_and_handlers) { + const MaybeObjectHandle maybe_code_handler = map_and_handler.second; // The first handler that isn't the slow handler will have the bits we need. Handle handler; if (maybe_code_handler.object()->IsStoreHandler()) { diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h index 207ced2a95b0e8..730f6825f4de2f 100644 --- a/deps/v8/src/objects/feedback-vector.h +++ b/deps/v8/src/objects/feedback-vector.h @@ -59,6 +59,8 @@ enum class FeedbackSlotKind { kKindsNumber // Last value indicating number of kinds. }; +using MapAndHandler = std::pair, MaybeObjectHandle>; + inline bool IsCallICKind(FeedbackSlotKind kind) { return kind == FeedbackSlotKind::kCall; } @@ -647,8 +649,8 @@ class V8_EXPORT_PRIVATE FeedbackNexus final { Map GetFirstMap() const; int ExtractMaps(MapHandles* maps) const; - int ExtractMapsAndHandlers(MapHandles* maps, - MaybeObjectHandles* handlers) const; + int ExtractMapsAndHandlers(std::vector* maps_and_handlers, + bool drop_deprecated = false) const; MaybeObjectHandle FindHandlerForMap(Handle map) const; bool IsCleared() const { @@ -672,8 +674,8 @@ class V8_EXPORT_PRIVATE FeedbackNexus final { void ConfigureMonomorphic(Handle name, Handle receiver_map, const MaybeObjectHandle& handler); - void ConfigurePolymorphic(Handle name, MapHandles const& maps, - MaybeObjectHandles* handlers); + void ConfigurePolymorphic( + Handle name, std::vector const& maps_and_handlers); BinaryOperationHint GetBinaryOperationFeedback() const; CompareOperationHint GetCompareOperationFeedback() const; diff --git a/deps/v8/src/objects/js-number-format.cc b/deps/v8/src/objects/js-number-format.cc index 92d3e2fb82eaed..ced408aa173d92 100644 --- a/deps/v8/src/objects/js-number-format.cc +++ b/deps/v8/src/objects/js-number-format.cc @@ -1197,42 +1197,31 @@ MaybeHandle JSNumberFormat::New(Isolate* isolate, } namespace { -Maybe IcuFormatNumber( +Maybe IcuFormatNumber( Isolate* isolate, const icu::number::LocalizedNumberFormatter& number_format, - Handle numeric_obj, icu::FieldPositionIterator* fp_iter) { + Handle numeric_obj, icu::number::FormattedNumber* formatted) { // If it is BigInt, handle it differently. UErrorCode status = U_ZERO_ERROR; - icu::number::FormattedNumber formatted; if (numeric_obj->IsBigInt()) { Handle big_int = Handle::cast(numeric_obj); Handle big_int_string; ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, big_int_string, BigInt::ToString(isolate, big_int), - Nothing()); - formatted = number_format.formatDecimal( + Nothing()); + *formatted = number_format.formatDecimal( {big_int_string->ToCString().get(), big_int_string->length()}, status); } else { double number = numeric_obj->Number(); - formatted = number_format.formatDouble(number, status); + *formatted = number_format.formatDouble(number, status); } if (U_FAILURE(status)) { // This happen because of icu data trimming trim out "unit". // See https://bugs.chromium.org/p/v8/issues/detail?id=8641 - THROW_NEW_ERROR_RETURN_VALUE(isolate, - NewTypeError(MessageTemplate::kIcuError), - Nothing()); - } - if (fp_iter) { - formatted.getAllFieldPositions(*fp_iter, status); + THROW_NEW_ERROR_RETURN_VALUE( + isolate, NewTypeError(MessageTemplate::kIcuError), Nothing()); } - icu::UnicodeString result = formatted.toString(status); - if (U_FAILURE(status)) { - THROW_NEW_ERROR_RETURN_VALUE(isolate, - NewTypeError(MessageTemplate::kIcuError), - Nothing()); - } - return Just(result); + return Just(true); } } // namespace @@ -1243,10 +1232,16 @@ MaybeHandle JSNumberFormat::FormatNumeric( Handle numeric_obj) { DCHECK(numeric_obj->IsNumeric()); - Maybe maybe_format = - IcuFormatNumber(isolate, number_format, numeric_obj, nullptr); + icu::number::FormattedNumber formatted; + Maybe maybe_format = + IcuFormatNumber(isolate, number_format, numeric_obj, &formatted); MAYBE_RETURN(maybe_format, Handle()); - return Intl::ToString(isolate, maybe_format.FromJust()); + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString result = formatted.toString(status); + if (U_FAILURE(status)) { + THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError), String); + } + return Intl::ToString(isolate, result); } namespace { @@ -1359,12 +1354,18 @@ std::vector FlattenRegionsToParts( } namespace { -Maybe ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted, - icu::FieldPositionIterator* fp_iter, +Maybe ConstructParts(Isolate* isolate, + icu::number::FormattedNumber* formatted, Handle result, int start_index, Handle numeric_obj, bool style_is_unit) { + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString formatted_text = formatted->toString(status); + if (U_FAILURE(status)) { + THROW_NEW_ERROR_RETURN_VALUE( + isolate, NewTypeError(MessageTemplate::kIcuError), Nothing()); + } DCHECK(numeric_obj->IsNumeric()); - int32_t length = formatted.length(); + int32_t length = formatted_text.length(); int index = start_index; if (length == 0) return Just(index); @@ -1373,13 +1374,14 @@ Maybe ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted, // other region covers some part of the formatted string. It's possible // there's another field with exactly the same begin and end as this backdrop, // in which case the backdrop's field_id of -1 will give it lower priority. - regions.push_back(NumberFormatSpan(-1, 0, formatted.length())); + regions.push_back(NumberFormatSpan(-1, 0, formatted_text.length())); { - icu::FieldPosition fp; - while (fp_iter->next(fp)) { - regions.push_back(NumberFormatSpan(fp.getField(), fp.getBeginIndex(), - fp.getEndIndex())); + icu::ConstrainedFieldPosition cfp; + cfp.constrainCategory(UFIELD_CATEGORY_NUMBER); + while (formatted->nextPosition(cfp, status)) { + regions.push_back( + NumberFormatSpan(cfp.getField(), cfp.getStart(), cfp.getLimit())); } } @@ -1401,7 +1403,7 @@ Maybe ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted, Handle substring; ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate, substring, - Intl::ToString(isolate, formatted, part.begin_pos, part.end_pos), + Intl::ToString(isolate, formatted_text, part.begin_pos, part.end_pos), Nothing()); Intl::AddElement(isolate, result, index, field_type_string, substring); ++index; @@ -1421,14 +1423,14 @@ MaybeHandle JSNumberFormat::FormatToParts( number_format->icu_number_formatter().raw(); CHECK_NOT_NULL(fmt); - icu::FieldPositionIterator fp_iter; - Maybe maybe_format = - IcuFormatNumber(isolate, *fmt, numeric_obj, &fp_iter); + icu::number::FormattedNumber formatted; + Maybe maybe_format = + IcuFormatNumber(isolate, *fmt, numeric_obj, &formatted); MAYBE_RETURN(maybe_format, Handle()); Handle result = factory->NewJSArray(0); Maybe maybe_format_to_parts = ConstructParts( - isolate, maybe_format.FromJust(), &fp_iter, result, 0, numeric_obj, + isolate, &formatted, result, 0, numeric_obj, number_format->style() == JSNumberFormat::Style::UNIT); MAYBE_RETURN(maybe_format_to_parts, Handle()); diff --git a/deps/v8/test/cctest/parsing/test-scanner-streams.cc b/deps/v8/test/cctest/parsing/test-scanner-streams.cc index 35b7048bb01e3b..28687cef5b4b25 100644 --- a/deps/v8/test/cctest/parsing/test-scanner-streams.cc +++ b/deps/v8/test/cctest/parsing/test-scanner-streams.cc @@ -331,8 +331,8 @@ TEST(Utf8AdvanceUntilOverChunkBoundaries) { for (size_t i = 1; i < len; i++) { // Copy source string into buffer, splitting it at i. // Then add three chunks, 0..i-1, i..strlen-1, empty. - strncpy(buffer, unicode_utf8, i); - strncpy(buffer + i + 1, unicode_utf8 + i, len - i); + memcpy(buffer, unicode_utf8, i); + memcpy(buffer + i + 1, unicode_utf8 + i, len - i); buffer[i] = '\0'; buffer[len + 1] = '\n'; buffer[len + 2] = '\0'; @@ -360,8 +360,8 @@ TEST(Utf8ChunkBoundaries) { for (size_t i = 1; i < len; i++) { // Copy source string into buffer, splitting it at i. // Then add three chunks, 0..i-1, i..strlen-1, empty. - strncpy(buffer, unicode_utf8, i); - strncpy(buffer + i + 1, unicode_utf8 + i, len - i); + memcpy(buffer, unicode_utf8, i); + memcpy(buffer + i + 1, unicode_utf8 + i, len - i); buffer[i] = '\0'; buffer[len + 1] = '\0'; buffer[len + 2] = '\0'; diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js b/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js new file mode 100644 index 00000000000000..61ce2e519143ec --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1053939.js @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --no-lazy-feedback-allocation + + +function foo(a, b) { + a[b] = 1; + return a[b]; +} +v = []; +assertEquals(foo(v, 1), 1); +v.__proto__.__proto__ = new Int32Array(); +assertEquals(foo(Object(), 1), 1); +assertEquals(foo(v, 2), undefined); diff --git a/doc/abi_version_registry.json b/doc/abi_version_registry.json index 98c1522a8dd94e..c4de6b8719b032 100644 --- a/doc/abi_version_registry.json +++ b/doc/abi_version_registry.json @@ -1,6 +1,6 @@ { "NODE_MODULE_VERSION": [ - { "modules": 83, "runtime": "node", "variant": "v8_8.1", "versions": "14.0.0-pre" }, + { "modules": 83, "runtime": "node", "variant": "v8_8.1", "versions": "14.0.0" }, { "modules": 82, "runtime": "electron", "variant": "electron", "versions": "10" }, { "modules": 81, "runtime": "node", "variant": "v8_7.9", "versions": "14.0.0-pre" }, { "modules": 80, "runtime": "electron", "variant": "electron", "versions": "9" }, diff --git a/doc/api/assert.md b/doc/api/assert.md index d5d0a606c2bf46..9731ddaa13f315 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -11,7 +11,9 @@ invariants. * `string` {string} @@ -780,7 +784,9 @@ let err; ## `assert.match(string, regexp[, message])` * `string` {string} diff --git a/doc/api/buffer.md b/doc/api/buffer.md index b839f0cebad093..52e86430ede831 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -1341,7 +1341,9 @@ The `buf.parent` property is a deprecated alias for `buf.buffer`. ### `buf.readBigInt64BE([offset])` ### `buf.readBigInt64LE([offset])` * `offset` {integer} Number of bytes to skip before starting to read. Must @@ -1357,7 +1359,9 @@ Integers read from a `Buffer` are interpreted as two's complement signed values. ### `buf.readBigUInt64BE([offset])` ### `buf.readBigUInt64LE([offset])` * `offset` {integer} Number of bytes to skip before starting to read. Must @@ -2027,7 +2031,9 @@ console.log(`${length} bytes: ${buffer.toString('utf8', 8, 10)}`); ### `buf.writeBigInt64BE(value[, offset])` ### `buf.writeBigInt64LE(value[, offset])` * `value` {bigint} Number to be written to `buf`. @@ -2053,7 +2059,9 @@ console.log(buf); ### `buf.writeBigUInt64BE(value[, offset])` ### `buf.writeBigUInt64LE(value[, offset])` * `value` {bigint} Number to be written to `buf`. diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 4c1bd5891b7012..5657f2014ab7e4 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -329,7 +329,9 @@ arbitrary command execution.** Child processes support a serialization mechanism for IPC that is based on the diff --git a/doc/api/cli.md b/doc/api/cli.md index 0e66b9e574a53a..7b7fbc83524522 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -167,7 +167,9 @@ Currently, overriding `Error.prepareStackTrace` is ignored when the ### `--experimental-import-meta-resolve` Enable experimental `import.meta.resolve()` support. @@ -210,7 +212,9 @@ Enable experimental top-level `await` keyword support in REPL. ### `--experimental-specifier-resolution=mode` Sets the resolution algorithm for resolving ES module specifiers. Valid options @@ -231,7 +235,9 @@ Enable experimental ES Module support in the `vm` module. ### `--experimental-wasi-unstable-preview1` Use an insecure HTTP parser that accepts invalid HTTP headers. This may allow @@ -439,7 +448,9 @@ disappear in a non-semver-major release. ### `--max-http-header-size=size` Log TLS key material to a file. The key material is in NSS `SSLKEYLOGFILE` @@ -746,7 +759,9 @@ traffic. ### `--tls-max-v1.2` Set [`tls.DEFAULT_MAX_VERSION`][] to 'TLSv1.2'. Use to disable support for @@ -762,7 +777,9 @@ for TLSv1.3. ### `--tls-min-v1.0` Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1'. Use for compatibility with @@ -770,7 +787,9 @@ old TLS clients or servers. ### `--tls-min-v1.1` Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.1'. Use for compatibility @@ -778,7 +797,9 @@ with old TLS clients or servers. ### `--tls-min-v1.2` Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.2'. This is the default for @@ -825,7 +846,9 @@ Enables the collection of trace event tracing information. ### `--trace-exit` Prints a stack trace whenever an environment is exited proactively, @@ -882,7 +905,9 @@ Track heap object allocations for heap snapshots. ### `--unhandled-rejections=mode` By default all unhandled rejections trigger a warning plus a deprecation warning @@ -1273,7 +1298,9 @@ to an empty string (`''` or `' '`) disables persistent REPL history. ### `NODE_REPL_EXTERNAL_MODULE=file` Path to a Node.js module which will be loaded in place of the built-in REPL. diff --git a/doc/api/cluster.md b/doc/api/cluster.md index a1eb0859c87d8f..c12c9758b94c9f 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -724,7 +724,9 @@ values are `'rr'` and `'none'`. @@ -2651,6 +2653,19 @@ written twice. This introduces a race condition between threads, and is a potential security vulnerability. There is no safe, cross-platform alternative API. + +### DEP0140: Use `request.destroy()` instead of `request.abort()` + + +Type: Documentation-only + +Use [`request.destroy()`][] instead of [`request.abort()`][]. + [`--pending-deprecation`]: cli.html#cli_pending_deprecation [`--throw-deprecation`]: cli.html#cli_throw_deprecation [`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size @@ -2712,8 +2727,10 @@ API. [`punycode`]: punycode.html [`require.extensions`]: modules.html#modules_require_extensions [`require.main`]: modules.html#modules_accessing_the_main_module +[`request.abort()`]: http.html#http_request_abort [`request.socket`]: http.html#http_request_socket [`request.connection`]: http.html#http_request_connection +[`request.destroy()`]: http.html#http_request_destroy_error [`response.socket`]: http.html#http_response_socket [`response.connection`]: http.html#http_response_connection [`response.end()`]: http.html#http_response_end_data_encoding_callback diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 57a38e3895f018..71c363e4a116cb 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -128,7 +128,9 @@ if (cluster.isMaster) { ### `socket.addSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])` * `sourceAddress` {string} * `groupAddress` {string} @@ -317,7 +319,9 @@ drop membership on all valid interfaces. ### `socket.dropSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])` * `sourceAddress` {string} diff --git a/doc/api/errors.md b/doc/api/errors.md index 7ed5e5b0bd9ece..5b1599febea9b7 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1194,7 +1194,7 @@ is set for the `Http2Stream`. ### `ERR_INTERNAL_ASSERTION` There was a bug in Node.js or incorrect usage of Node.js internals. -To fix the error, open an issue at https://github.com/nodejs/node/issues. +To fix the error, open an issue at . ### `ERR_INCOMPATIBLE_OPTION_PAIR` @@ -2145,7 +2145,9 @@ Creation of a [`zlib`][] object failed due to incorrect configuration. ### `HPE_HEADER_OVERFLOW` @@ -2310,7 +2312,7 @@ added: v9.0.0 removed: v14.0.0 --> -Data could be sent on a socket. +Data could not be sent on a socket. ### `ERR_STDERR_CLOSE` diff --git a/doc/api/esm.md b/doc/api/esm.md index 97124486cc2bf5..49c467effbc3cd 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1661,13 +1661,15 @@ The resolver can throw the following errors: > loop on any _Package Path Not Exported_ error. > 1. Throw a _Package Path Not Exported_ error. > 1. Otherwise, if _target_ is an Array, then -> 1. If _target.length is zero, throw an _Invalid Package Target_ error. +> 1. If _target.length is zero, throw a _Package Path Not Exported_ error. > 1. For each item _targetValue_ in _target_, do > 1. If _targetValue_ is an Array, continue the loop. > 1. Return the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, > _targetValue_, _subpath_, _env_), continuing the loop on any > _Package Path Not Exported_ or _Invalid Package Target_ error. > 1. Throw the last fallback resolution error. +> 1. Otherwise, if _target_ is _null_, throw a _Package Path Not Exported_ +> error. > 1. Otherwise throw an _Invalid Package Target_ error. **ESM_FORMAT**(_url_) diff --git a/doc/api/events.md b/doc/api/events.md index b23da5a523ea40..a30e2abb01353c 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -224,7 +224,9 @@ recommendation is to **not use `async` functions as `'error'` event handlers**. @@ -362,7 +364,9 @@ Its `name` property is set to `'MaxListenersExceededWarning'`. ### `EventEmitter.errorMonitor` This symbol shall be used to install a listener for only monitoring `'error'` @@ -783,7 +787,9 @@ emitter.emit('log'); ### `emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])` > Stability: 1 - captureRejections is experimental. @@ -819,7 +825,9 @@ class MyClass extends EventEmitter { ## `events.once(emitter, name)` * `emitter` {EventEmitter} @@ -865,7 +873,9 @@ run(); ## `events.captureRejections` > Stability: 1 - captureRejections is experimental. @@ -876,7 +886,9 @@ Change the default `captureRejections` option on all new `EventEmitter` objects. ## `events.captureRejectionSymbol` > Stability: 1 - captureRejections is experimental. @@ -887,7 +899,9 @@ See how to write a custom [rejection handler][rejection]. ## `events.on(emitter, eventName)` * `emitter` {EventEmitter} diff --git a/doc/api/fs.md b/doc/api/fs.md index 7bbb5cf75a7356..4291e120eeadf4 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -430,8 +430,9 @@ included in the iteration results. added: v10.10.0 --> -A representation of a directory entry, as returned by reading from an -[`fs.Dir`][]. +A representation of a directory entry, which can be a file or a subdirectory +within the directory, as returned by reading from an [`fs.Dir`][]. The +directory entry is a combination of the file name and file type pairs. Additionally, when [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with the `withFileTypes` option set to `true`, the resulting array is filled with @@ -636,7 +637,9 @@ argument to `fs.createReadStream()`. If `path` is passed as a string, then ### `readStream.pending` * {boolean} @@ -2459,11 +2462,11 @@ changes: Asynchronously creates a directory. The callback is given a possible exception and, if `recursive` is `true`, the -first folder path created, `(err, [path])`. +first directory path created, `(err, [path])`. The optional `options` argument can be an integer specifying `mode` (permission and sticky bits), or an object with a `mode` property and a `recursive` -property indicating whether parent folders should be created. Calling +property indicating whether parent directories should be created. Calling `fs.mkdir()` when `path` is a directory that exists results in an error only when `recursive` is false. @@ -2509,7 +2512,7 @@ changes: * Returns: {string|undefined} Synchronously creates a directory. Returns `undefined`, or if `recursive` is -`true`, the first folder path created. +`true`, the first directory path created. This is the synchronous version of [`fs.mkdir()`][]. See also: mkdir(2). @@ -2536,7 +2539,7 @@ changes: * `encoding` {string} **Default:** `'utf8'` * `callback` {Function} * `err` {Error} - * `folder` {string} + * `directory` {string} Creates a unique temporary directory. @@ -2546,16 +2549,16 @@ inconsistencies, avoid trailing `X` characters in `prefix`. Some platforms, notably the BSDs, can return more than six random characters, and replace trailing `X` characters in `prefix` with random characters. -The created folder path is passed as a string to the callback's second +The created directory path is passed as a string to the callback's second parameter. The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use. ```js -fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, folder) => { +fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, directory) => { if (err) throw err; - console.log(folder); + console.log(directory); // Prints: /tmp/foo-itXde2 or C:\Users\...\AppData\Local\Temp\foo-itXde2 }); ``` @@ -2571,9 +2574,9 @@ must end with a trailing platform-specific path separator const tmpDir = os.tmpdir(); // This method is *INCORRECT*: -fs.mkdtemp(tmpDir, (err, folder) => { +fs.mkdtemp(tmpDir, (err, directory) => { if (err) throw err; - console.log(folder); + console.log(directory); // Will print something similar to `/tmpabc123`. // A new temporary directory is created at the file system root // rather than *within* the /tmp directory. @@ -2581,9 +2584,9 @@ fs.mkdtemp(tmpDir, (err, folder) => { // This method is *CORRECT*: const { sep } = require('path'); -fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => { +fs.mkdtemp(`${tmpDir}${sep}`, (err, directory) => { if (err) throw err; - console.log(folder); + console.log(directory); // Will print something similar to `/tmp/abc123`. // A new temporary directory is created within // the /tmp directory. @@ -2600,7 +2603,7 @@ added: v5.10.0 * `encoding` {string} **Default:** `'utf8'` * Returns: {string} -Returns the created folder path. +Returns the created directory path. For detailed information, see the documentation of the asynchronous version of this API: [`fs.mkdtemp()`][]. @@ -2652,7 +2655,9 @@ Functions based on `fs.open()` exhibit this behavior as well: @@ -2679,7 +2684,9 @@ directory and subsequent read operations. @@ -3331,7 +3338,9 @@ Synchronous rename(2). Returns `undefined`. @@ -5199,7 +5212,9 @@ upon success. Marks the request as aborting. Calling this will cause remaining data @@ -623,10 +624,37 @@ If `data` is specified, it is equivalent to calling If `callback` is specified, it will be called when the request stream is finished. +### `request.destroy([error])` + + +* `error` {Error} Optional, an error to emit with `'error'` event. +* Returns: {this} + +Destroy the request. Optionally emit an `'error'` event, +and emit a `'close'` event. Calling this will cause remaining data +in the response to be dropped and the socket to be destroyed. + +See [`writable.destroy()`][] for further details. + +#### `request.destroyed` + + +* {boolean} + +Is `true` after [`request.destroy()`][] has been called. + +See [`writable.destroyed`][] for further details. + ### `request.finished` > Stability: 0 - Deprecated. Use [`request.writableEnded`][]. @@ -703,9 +731,10 @@ request.removeHeader('Content-Type'); ``` ### `request.reusedSocket` - * {boolean} Whether the request is send through a reused socket. @@ -1107,7 +1136,9 @@ Stops the server from accepting new connections. See [`net.Server.close()`][]. ### `server.headersTimeout` * {number} **Default:** `60000` @@ -1279,7 +1310,9 @@ See [`response.socket`][]. ### `response.cork()` See [`writable.cork()`][]. @@ -1311,7 +1344,9 @@ is finished. ### `response.finished` > Stability: 0 - Deprecated. Use [`response.writableEnded`][]. @@ -1578,7 +1613,9 @@ status message which was sent out. ### `response.uncork()` See [`writable.uncork()`][]. @@ -1654,7 +1691,9 @@ the request body should be sent. See the [`'checkContinue'`][] event on @@ -2032,7 +2073,10 @@ Found'`. * {number} @@ -2163,7 +2209,10 @@ This can be overridden for servers and client requests by passing the * {number} @@ -1988,10 +1990,14 @@ value only affects new connections to the server, not any existing connections. > Stability: 0 - Deprecated. Use [`response.writableEnded`][]. @@ -3429,7 +3441,9 @@ should be sent. See the [`'checkContinue'`][] event on `Http2Server` and * `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format. @@ -238,6 +240,9 @@ Global instance of [`https.Agent`][] for all HTTPS client requests. @@ -401,7 +404,9 @@ by the previous call, it will not be called. ### napi_get_instance_data @@ -457,6 +462,7 @@ typedef enum { napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, + napi_would_deadlock, } napi_status; ``` @@ -1663,7 +1669,9 @@ the `napi_value` in question is of the JavaScript type expected by the API. ### Enum types #### napi_key_collection_mode @@ -1684,7 +1692,9 @@ of the objects's prototype chain as well. #### napi_key_filter @@ -1703,7 +1713,9 @@ Property filter bits. They can be or'ed to build a composite filter. #### napi_key_conversion @@ -1900,7 +1912,9 @@ structure, in most cases using a `TypedArray` will suffice. #### napi_create_date @@ -2581,7 +2595,9 @@ This API returns various properties of a `DataView`. #### napi_get_date_value @@ -3199,7 +3215,9 @@ This API checks if the `Object` passed in is a buffer. ### napi_is_date @@ -3295,7 +3313,9 @@ defined in [Section 7.2.14][] of the ECMAScript Language Specification. ### napi_detach_arraybuffer > Stability: 1 - Experimental @@ -3321,7 +3341,9 @@ defined in [Section 24.1.1.3][] of the ECMAScript Language Specification. ### napi_is_detached_arraybuffer > Stability: 1 - Experimental @@ -3590,7 +3612,9 @@ included. #### napi_get_all_property_names @@ -5095,6 +5119,19 @@ preventing data from being successfully added to the queue. If set to `napi_call_threadsafe_function()` never blocks if the thread-safe function was created with a maximum queue size of 0. +As a special case, when `napi_call_threadsafe_function()` is called from a +JavaScript thread, it will return `napi_would_deadlock` if the queue is full +and it was called with `napi_tsfn_blocking`. The reason for this is that the +JavaScript thread is responsible for removing items from the queue, thereby +reducing their number. Thus, if it waits for room to become available on the +queue, then it will deadlock. + +`napi_call_threadsafe_function()` will also return `napi_would_deadlock` if the +thread-safe function created on one JavaScript thread is called from another +JavaScript thread. The reason for this is to prevent a deadlock arising from the +possibility that the two JavaScript threads end up waiting on one another, +thereby both deadlocking. + The actual call into JavaScript is controlled by the callback given via the `call_js_cb` parameter. `call_js_cb` is invoked on the main thread once for each value that was placed into the queue by a successful call to @@ -5166,7 +5203,9 @@ prevent the event loop from exiting. The APIs `napi_ref_threadsafe_function` and added: v10.6.0 napiVersion: 4 changes: - - version: v12.6.0 + - version: + - v12.6.0 + - v10.17.0 pr-url: https://github.com/nodejs/node/pull/27791 description: Made `func` parameter optional with custom `call_js_cb`. --> @@ -5231,6 +5270,12 @@ This API may be called from any thread which makes use of `func`. ```C @@ -5248,9 +5293,13 @@ napi_call_threadsafe_function(napi_threadsafe_function func, `napi_tsfn_nonblocking` to indicate that the call should return immediately with a status of `napi_queue_full` whenever the queue is full. +This API will return `napi_would_deadlock` if called with `napi_tsfn_blocking` +from the main thread and the queue is full. + This API will return `napi_closing` if `napi_release_threadsafe_function()` was -called with `abort` set to `napi_tsfn_abort` from any thread. The value is only -added to the queue if the API returns `napi_ok`. +called with `abort` set to `napi_tsfn_abort` from any thread. + +The value is only added to the queue if the API returns `napi_ok`. This API may be called from any thread which makes use of `func`. diff --git a/doc/api/net.md b/doc/api/net.md index aa2b918ecdac12..28842d0abe9b90 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -787,7 +787,9 @@ Useful to throttle back an upload. ### `socket.pending` * {boolean} diff --git a/doc/api/os.md b/doc/api/os.md index 27a7c3d549f78b..e2cce1f8a5580f 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -290,7 +290,7 @@ Returns the operating system as a string. On POSIX systems, the operating system release is determined by calling [uname(3)][]. On Windows, `GetVersionExW()` is used. See -https://en.wikipedia.org/wiki/Uname#Examples for more information. + for more information. ## `os.setPriority([pid, ]priority)` diff --git a/doc/api/readline.md b/doc/api/readline.md index f36f0db9db73b1..272481a9f155c3 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -315,9 +315,13 @@ The `rl.write()` method will write the data to the `readline` `Interface`'s ### `rl[Symbol.asyncIterator]()` @@ -401,7 +405,9 @@ as well as the column where the terminal caret will be rendered. ### `rl.getCursorPos()` * Returns: {Object} diff --git a/doc/api/report.md b/doc/api/report.md index 6fa8d92a9bf4b4..7807063fdc5725 100644 --- a/doc/api/report.md +++ b/doc/api/report.md @@ -580,7 +580,9 @@ Specific API documentation can be found under ## Interaction with Workers diff --git a/doc/api/stream.md b/doc/api/stream.md index 4f155512ac4750..e8993849090199 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -519,7 +519,9 @@ does not indicate whether the data has been flushed, for this use ##### `writable.writableCorked` * {integer} @@ -1503,6 +1505,21 @@ further errors except from `_destroy` may be emitted as `'error'`. ### `stream.finished(stream[, options], callback)` * `stream` {Stream} A readable and/or writable stream. @@ -1580,6 +1597,12 @@ changes: - version: v13.10.0 pr-url: https://github.com/nodejs/node/pull/31223 description: Add support for async generators. + - version: v14.0.0 + pr-url: https://github.com/nodejs/node/pull/32158 + description: The `pipeline(..., cb)` will wait for the `'close'` event + before invoking the callback. The implementation tries to + detect legacy streams and only apply this behavior to streams + which are expected to emit `'close'`. --> * `source` {Stream|Iterable|AsyncIterable|Function} @@ -1788,17 +1811,19 @@ method. #### Constructor: `new stream.Writable([options])` * `options` {Object} @@ -2072,7 +2097,9 @@ constructor and implement the `readable._read()` method. #### `new stream.Readable([options])` * `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format. @@ -692,7 +694,9 @@ Construct a new `tls.TLSSocket` object from an existing TCP socket. ### Event: `'keylog'` * `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format. @@ -857,13 +861,15 @@ socket has been destroyed, `null` will be returned. * Returns: {Object} @@ -1274,7 +1280,12 @@ being issued by trusted CA (`options.ca`). * `count` {integer} The number of colors that are requested (minimum 2). diff --git a/doc/api/url.md b/doc/api/url.md index 49f56509fe41e9..6950c92f0980c8 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -105,6 +105,13 @@ const myURL = new URL('/foo', 'https://example.org/'); // https://example.org/foo ``` +The URL constructor is accessible as a property on the global object. +It can also be imported from the built-in url module: + +```js +console.log(URL === require('url').URL); // Prints 'true'. +``` + A `TypeError` will be thrown if the `input` or `base` are not valid URLs. Note that an effort will be made to coerce the given values into strings. For instance: diff --git a/doc/api/util.md b/doc/api/util.md index 616542f6daf1ce..757c6a48f6ece9 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -401,7 +401,9 @@ changes: - version: v14.0.0 pr-url: https://github.com/nodejs/node/pull/32392 description: The `maxStringLength` option is supported now. - - version: v13.5.0 + - version: + - v13.5.0 + - v12.16.0 pr-url: https://github.com/nodejs/node/pull/30768 description: User defined prototype properties are inspected in case `showHidden` is `true`. @@ -1002,7 +1004,9 @@ throw an error. diff --git a/doc/api/vm.md b/doc/api/vm.md index ec731ffd36c6a0..f45b5373683029 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -88,7 +88,7 @@ changes: This option is part of the experimental modules API, and should not be considered stable. * `specifier` {string} specifier passed to `import()` - * `module` {vm.Module} + * `script` {vm.Script} * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is recommended in order to take advantage of error tracking, and to avoid issues with namespaces that contain `then` function exports. @@ -347,7 +347,9 @@ vm.measureMemory({ mode: 'detailed' }, context) ## Class: `vm.Module` > Stability: 1 - Experimental @@ -696,7 +698,9 @@ const module2 = new vm.SourceTextModule('const a = 1;', { cachedData }); ## Class: `vm.SyntheticModule` > Stability: 1 - Experimental @@ -725,7 +729,9 @@ const module = new vm.SyntheticModule(['default'], function() { ### Constructor: `new vm.SyntheticModule(exportNames, evaluateCallback[, options])` * `exportNames` {string[]} Array of names that will be exported from the module. @@ -745,7 +751,9 @@ the module to access information outside the specified `context`. Use ### `syntheticModule.setExport(name, value)` * `name` {string} Name of the export to set. @@ -773,6 +781,10 @@ const vm = require('vm'); ## `vm.compileFunction(code[, params[, options]])` * `code` {string} The body of the function to compile. @@ -795,6 +807,16 @@ added: v10.10.0 * `contextExtensions` {Object[]} An array containing a collection of context extensions (objects wrapping the current scope) to be applied while compiling. **Default:** `[]`. + * `importModuleDynamically` {Function} Called during evaluation of this module + when `import()` is called. If this option is not specified, calls to + `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. + This option is part of the experimental modules API, and should not be + considered stable. + * `specifier` {string} specifier passed to `import()` + * `function` {Function} + * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is + recommended in order to take advantage of error tracking, and to avoid + issues with namespaces that contain `then` function exports. * Returns: {Function} Compiles the given code into the provided context (if no context is diff --git a/doc/api/wasi.md b/doc/api/wasi.md index 27dceaa014f7e8..1fe78aeecd6a1f 100644 --- a/doc/api/wasi.md +++ b/doc/api/wasi.md @@ -1,6 +1,6 @@ # WebAssembly System Interface (WASI) - + > Stability: 1 - Experimental @@ -34,7 +34,9 @@ CLI arguments are needed for the previous example to run. ## Class: `WASI` The `WASI` class provides the WASI system call API and additional convenience @@ -45,7 +47,9 @@ sandbox directory structure configured explicitly. ### `new WASI([options])` * `options` {Object} @@ -65,7 +69,9 @@ added: v13.3.0 ### `wasi.start(instance)` * `instance` {WebAssembly.Instance} @@ -80,7 +86,9 @@ is present on `instance`, then `start()` does nothing. ### `wasi.wasiImport` * {Object} diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index d3b15155d5a6c3..2d6c3c23940cf2 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -165,7 +165,9 @@ When this function is used, no `'message'` event will be emitted and the ## `worker.resourceLimits` * {Object} @@ -520,10 +522,14 @@ changes: pr-url: https://github.com/nodejs/node/pull/31664 description: The `filename` parameter can be a WHATWG `URL` object using `file:` protocol. - - version: v13.2.0 + - version: + - v13.2.0 + - v12.16.0 pr-url: https://github.com/nodejs/node/pull/26628 description: The `resourceLimits` option was introduced. - - version: v13.4.0 + - version: + - v13.4.0 + - v12.16.0 pr-url: https://github.com/nodejs/node/pull/30559 description: The `argv` option was introduced. --> @@ -564,6 +570,10 @@ changes: occur as described in the [HTML structured clone algorithm][], and an error will be thrown if the object cannot be cloned (e.g. because it contains `function`s). + * `transferList` {Object[]} If one or more `MessagePort`-like objects + are passed in `workerData`, a `transferList` is required for those + items or [`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`][] will be thrown. + See [`port.postMessage()`][] for more information. * `resourceLimits` {Object} An optional set of resource limits for the new JS engine instance. Reaching these limits will lead to termination of the `Worker` instance. These limits only affect the JS engine, and no external @@ -660,7 +670,9 @@ no effect. ### `worker.resourceLimits` * {Object} @@ -751,6 +763,7 @@ active handle in the event system. If the worker is already `unref()`ed calling [`'exit'` event]: #worker_threads_event_exit [`AsyncResource`]: async_hooks.html#async_hooks_class_asyncresource [`Buffer`]: buffer.html +[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: errors.html#errors_err_missing_message_port_in_transfer_list [`ERR_WORKER_NOT_RUNNING`]: errors.html#ERR_WORKER_NOT_RUNNING [`EventEmitter`]: events.html [`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget diff --git a/doc/api/zlib.md b/doc/api/zlib.md index 04465c11352269..079efeb6a10cf9 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -166,7 +166,7 @@ request.on('response', (response) => { pipeline(response, zlib.createGunzip(), output, onError); break; case 'deflate': - pipeline(response, zlib.createInflate(), outout, onError); + pipeline(response, zlib.createInflate(), output, onError); break; default: pipeline(response, output, onError); @@ -411,7 +411,9 @@ Compression strategy. ### Brotli constants There are several options and other constants available for Brotli-based @@ -545,14 +547,18 @@ const stream = zlib.createBrotliCompress({ ## Class: `zlib.BrotliCompress` Compress data using the Brotli algorithm. ## Class: `zlib.BrotliDecompress` Decompress data using the Brotli algorithm. @@ -633,7 +639,9 @@ the header. @@ -727,7 +735,9 @@ Provides an object enumerating Zlib-related constants. ## `zlib.createBrotliCompress([options])` * `options` {brotli options} @@ -736,7 +746,9 @@ Creates and returns a new [`BrotliCompress`][] object. ## `zlib.createBrotliDecompress([options])` * `options` {brotli options} @@ -828,7 +840,9 @@ without a callback. ### `zlib.brotliCompress(buffer[, options], callback)` * `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string} @@ -837,7 +851,9 @@ added: v11.7.0 ### `zlib.brotliCompressSync(buffer[, options])` * `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string} @@ -847,7 +863,9 @@ Compress a chunk of data with [`BrotliCompress`][]. ### `zlib.brotliDecompress(buffer[, options], callback)` * `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string} @@ -856,7 +874,9 @@ added: v11.7.0 ### `zlib.brotliDecompressSync(buffer[, options])` * `buffer` {Buffer|TypedArray|DataView|ArrayBuffer|string} diff --git a/doc/changelogs/CHANGELOG_ARCHIVE.md b/doc/changelogs/CHANGELOG_ARCHIVE.md index ff94c455586e34..55302c99402b76 100644 --- a/doc/changelogs/CHANGELOG_ARCHIVE.md +++ b/doc/changelogs/CHANGELOG_ARCHIVE.md @@ -2,6 +2,7 @@ + diff --git a/doc/changelogs/CHANGELOG_IOJS.md b/doc/changelogs/CHANGELOG_IOJS.md index e736a70dedfef2..0a650253182b6d 100644 --- a/doc/changelogs/CHANGELOG_IOJS.md +++ b/doc/changelogs/CHANGELOG_IOJS.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V010.md b/doc/changelogs/CHANGELOG_V010.md index 65b6bef55bbd20..d4b579e6b5b88b 100644 --- a/doc/changelogs/CHANGELOG_V010.md +++ b/doc/changelogs/CHANGELOG_V010.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V012.md b/doc/changelogs/CHANGELOG_V012.md index 8a5ebf3e429fa6..d0485ffc58f652 100644 --- a/doc/changelogs/CHANGELOG_V012.md +++ b/doc/changelogs/CHANGELOG_V012.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V10.md b/doc/changelogs/CHANGELOG_V10.md index e347b51619e6d8..8a3baae0a53c57 100644 --- a/doc/changelogs/CHANGELOG_V10.md +++ b/doc/changelogs/CHANGELOG_V10.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V11.md b/doc/changelogs/CHANGELOG_V11.md index 960276df5e0293..be1cd8102e74a5 100644 --- a/doc/changelogs/CHANGELOG_V11.md +++ b/doc/changelogs/CHANGELOG_V11.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V12.md b/doc/changelogs/CHANGELOG_V12.md index 28e0c6ec306316..e3a457c39f18c6 100644 --- a/doc/changelogs/CHANGELOG_V12.md +++ b/doc/changelogs/CHANGELOG_V12.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V13.md b/doc/changelogs/CHANGELOG_V13.md index 5790e30d1d0a1b..a7853de9d4576b 100644 --- a/doc/changelogs/CHANGELOG_V13.md +++ b/doc/changelogs/CHANGELOG_V13.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V14.md b/doc/changelogs/CHANGELOG_V14.md index 37a678820fcdd7..7b389b9322c5a2 100644 --- a/doc/changelogs/CHANGELOG_V14.md +++ b/doc/changelogs/CHANGELOG_V14.md @@ -9,6 +9,7 @@ @@ -30,6 +31,118 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2020-04-29, Version 14.1.0 (Current), @BethGriggs + +### Notable Changes + +* **deps**: upgrade openssl sources to 1.1.1g (Hassaan Pasha) [#32971](https://github.com/nodejs/node/pull/32971) +* **doc**: add juanarbol as collaborator (Juan José Arboleda) [#32906](https://github.com/nodejs/node/pull/32906) +* **http**: doc deprecate abort and improve docs (Robert Nagy) [#32807](https://github.com/nodejs/node/pull/32807) +* **module**: do not warn when accessing `__esModule` of unfinished exports (Anna Henningsen) [#33048](https://github.com/nodejs/node/pull/33048) +* **n-api**: detect deadlocks in thread-safe function (Gabriel Schulhof) [#32860](https://github.com/nodejs/node/pull/32860) +* **src**: deprecate embedder APIs with replacements (Anna Henningsen) [#32858](https://github.com/nodejs/node/pull/32858) +* **stream**: + * don't emit end after close (Robert Nagy) [#33076](https://github.com/nodejs/node/pull/33076) + * don't wait for close on legacy streams (Robert Nagy) [#33058](https://github.com/nodejs/node/pull/33058) + * pipeline should only destroy un-finished streams (Robert Nagy) [#32968](https://github.com/nodejs/node/pull/32968) +* **vm**: add importModuleDynamically option to compileFunction (Gus Caplan) [#32985](https://github.com/nodejs/node/pull/32985) + +### Commits + +* [[`1af08e1c5e`](https://github.com/nodejs/node/commit/1af08e1c5e)] - **buffer,n-api**: fix double ArrayBuffer::Detach() during cleanup (Anna Henningsen) [#33039](https://github.com/nodejs/node/pull/33039) +* [[`91e30e35a1`](https://github.com/nodejs/node/commit/91e30e35a1)] - **build**: fix vcbuild error for missing Visual Studio (Thomas) [#32658](https://github.com/nodejs/node/pull/32658) +* [[`4035cbe631`](https://github.com/nodejs/node/commit/4035cbe631)] - **cluster**: removed unused addressType argument from constructor (Yash Ladha) [#32963](https://github.com/nodejs/node/pull/32963) +* [[`56f50aeff0`](https://github.com/nodejs/node/commit/56f50aeff0)] - **deps**: patch V8 to 8.1.307.31 (Michaël Zasso) [#33080](https://github.com/nodejs/node/pull/33080) +* [[`fad188fe23`](https://github.com/nodejs/node/commit/fad188fe23)] - **deps**: update archs files for OpenSSL-1.1.1g (Hassaan Pasha) [#32971](https://github.com/nodejs/node/pull/32971) +* [[`b12f1630fc`](https://github.com/nodejs/node/commit/b12f1630fc)] - **deps**: upgrade openssl sources to 1.1.1g (Hassaan Pasha) [#32971](https://github.com/nodejs/node/pull/32971) +* [[`b50333e001`](https://github.com/nodejs/node/commit/b50333e001)] - **deps**: V8: backport 3f8dc4b2e5ba (Ujjwal Sharma) [#32993](https://github.com/nodejs/node/pull/32993) +* [[`bbed1e56cd`](https://github.com/nodejs/node/commit/bbed1e56cd)] - **deps**: V8: cherry-pick e1eac1b16c96 (Milad Farazmand) [#32974](https://github.com/nodejs/node/pull/32974) +* [[`3fed735099`](https://github.com/nodejs/node/commit/3fed735099)] - **doc**: fix LTS replaceme tags (Anna Henningsen) [#33041](https://github.com/nodejs/node/pull/33041) +* [[`343c6ac639`](https://github.com/nodejs/node/commit/343c6ac639)] - **doc**: assign missing deprecation code (Richard Lau) [#33109](https://github.com/nodejs/node/pull/33109) +* [[`794b8796dd`](https://github.com/nodejs/node/commit/794b8796dd)] - **doc**: improve WHATWG url constructor code example (Liran Tal) [#32782](https://github.com/nodejs/node/pull/32782) +* [[`14e559df87`](https://github.com/nodejs/node/commit/14e559df87)] - **doc**: make openssl maintenance position independent (Sam Roberts) [#32977](https://github.com/nodejs/node/pull/32977) +* [[`8a4de2ef25`](https://github.com/nodejs/node/commit/8a4de2ef25)] - **doc**: improve release documentation (Michaël Zasso) [#33042](https://github.com/nodejs/node/pull/33042) +* [[`401ab610e7`](https://github.com/nodejs/node/commit/401ab610e7)] - **doc**: document major finished changes in v14 (Robert Nagy) [#33065](https://github.com/nodejs/node/pull/33065) +* [[`a534d8282c`](https://github.com/nodejs/node/commit/a534d8282c)] - **doc**: add documentation for transferList arg at worker threads (Juan José Arboleda) [#32881](https://github.com/nodejs/node/pull/32881) +* [[`f116825d56`](https://github.com/nodejs/node/commit/f116825d56)] - **doc**: avoid tautology in README (Ishaan Jain) [#33005](https://github.com/nodejs/node/pull/33005) +* [[`7e9f88e005`](https://github.com/nodejs/node/commit/7e9f88e005)] - **doc**: updated directory entry information (Eileen) [#32791](https://github.com/nodejs/node/pull/32791) +* [[`bf331b4e21`](https://github.com/nodejs/node/commit/bf331b4e21)] - **doc**: ignore no-literal-urls in README (Nick Schonning) [#32676](https://github.com/nodejs/node/pull/32676) +* [[`f92b398c76`](https://github.com/nodejs/node/commit/f92b398c76)] - **doc**: convert bare email addresses to mailto links (Nick Schonning) [#32676](https://github.com/nodejs/node/pull/32676) +* [[`2bde11607d`](https://github.com/nodejs/node/commit/2bde11607d)] - **doc**: ignore no-literal-urls in changelogs (Nick Schonning) [#32676](https://github.com/nodejs/node/pull/32676) +* [[`71f90234f9`](https://github.com/nodejs/node/commit/71f90234f9)] - **doc**: add angle brackets around implicit links (Nick Schonning) [#32676](https://github.com/nodejs/node/pull/32676) +* [[`aec7bc754e`](https://github.com/nodejs/node/commit/aec7bc754e)] - **doc**: remove repeated word in modules.md (Prosper Opara) [#32931](https://github.com/nodejs/node/pull/32931) +* [[`005c2bab29`](https://github.com/nodejs/node/commit/005c2bab29)] - **doc**: elevate diagnostic report to tier1 (Gireesh Punathil) [#32732](https://github.com/nodejs/node/pull/32732) +* [[`4dd3a7ddc9`](https://github.com/nodejs/node/commit/4dd3a7ddc9)] - **doc**: set module version 83 to node 14 (Gerhard Stoebich) [#32975](https://github.com/nodejs/node/pull/32975) +* [[`b5b3efeb90`](https://github.com/nodejs/node/commit/b5b3efeb90)] - **doc**: add more info to v14 changelog (Gus Caplan) [#32979](https://github.com/nodejs/node/pull/32979) +* [[`f6be140222`](https://github.com/nodejs/node/commit/f6be140222)] - **doc**: fix typo in security-release-process.md (Edward Elric) [#32926](https://github.com/nodejs/node/pull/32926) +* [[`fa710732bf`](https://github.com/nodejs/node/commit/fa710732bf)] - **doc**: corrected ERR\_SOCKET\_CANNOT\_SEND message (William Armiros) [#32847](https://github.com/nodejs/node/pull/32847) +* [[`68b7c80a44`](https://github.com/nodejs/node/commit/68b7c80a44)] - **doc**: fix usage of folder and directory terms in fs.md (karan singh virdi) [#32919](https://github.com/nodejs/node/pull/32919) +* [[`57c170c75c`](https://github.com/nodejs/node/commit/57c170c75c)] - **doc**: fix typo in zlib.md (雨夜带刀) [#32901](https://github.com/nodejs/node/pull/32901) +* [[`a8ed8f5d0a`](https://github.com/nodejs/node/commit/a8ed8f5d0a)] - **doc**: synch SECURITY.md with website (Rich Trott) [#32903](https://github.com/nodejs/node/pull/32903) +* [[`ccf6d3e5ed`](https://github.com/nodejs/node/commit/ccf6d3e5ed)] - **doc**: add `tsc-agenda` to onboarding labels list (Rich Trott) [#32832](https://github.com/nodejs/node/pull/32832) +* [[`fc71a85c49`](https://github.com/nodejs/node/commit/fc71a85c49)] - **doc**: add N-API version 6 to table (Michael Dawson) [#32829](https://github.com/nodejs/node/pull/32829) +* [[`87605f0ed3`](https://github.com/nodejs/node/commit/87605f0ed3)] - **doc**: add juanarbol as collaborator (Juan José Arboleda) [#32906](https://github.com/nodejs/node/pull/32906) +* [[`4c643c0d42`](https://github.com/nodejs/node/commit/4c643c0d42)] - **fs**: update validateOffsetLengthRead in utils.js (daemon1024) [#32896](https://github.com/nodejs/node/pull/32896) +* [[`baa8231728`](https://github.com/nodejs/node/commit/baa8231728)] - **fs**: extract kWriteFileMaxChunkSize constant (rickyes) [#32640](https://github.com/nodejs/node/pull/32640) +* [[`03d02d74f3`](https://github.com/nodejs/node/commit/03d02d74f3)] - **fs**: remove unnecessary else statement (Jesus Hernandez) [#32662](https://github.com/nodejs/node/pull/32662) +* [[`31c797cb11`](https://github.com/nodejs/node/commit/31c797cb11)] - **http**: doc deprecate abort and improve docs (Robert Nagy) [#32807](https://github.com/nodejs/node/pull/32807) +* [[`4ef91a640e`](https://github.com/nodejs/node/commit/4ef91a640e)] - **http2**: wait for secureConnect before initializing (Benjamin Coe) [#32958](https://github.com/nodejs/node/pull/32958) +* [[`6fc4d174b5`](https://github.com/nodejs/node/commit/6fc4d174b5)] - **http2**: refactor and cleanup http2 (James M Snell) [#32884](https://github.com/nodejs/node/pull/32884) +* [[`4b6aa077fe`](https://github.com/nodejs/node/commit/4b6aa077fe)] - **inspector**: only write coverage in fully bootstrapped Environments (Joyee Cheung) [#32960](https://github.com/nodejs/node/pull/32960) +* [[`737bd6205b`](https://github.com/nodejs/node/commit/737bd6205b)] - **lib**: unnecessary const assignment for class (Yash Ladha) [#32962](https://github.com/nodejs/node/pull/32962) +* [[`98b30b06ff`](https://github.com/nodejs/node/commit/98b30b06ff)] - **lib**: simplify function process.emitWarning (himself65) [#32992](https://github.com/nodejs/node/pull/32992) +* [[`b957895ff7`](https://github.com/nodejs/node/commit/b957895ff7)] - **lib**: remove unnecesary else block (David Daza) [#32644](https://github.com/nodejs/node/pull/32644) +* [[`cb4d8ce889`](https://github.com/nodejs/node/commit/cb4d8ce889)] - **module**: refactor condition (Myles Borins) [#32989](https://github.com/nodejs/node/pull/32989) +* [[`4abc45a4b9`](https://github.com/nodejs/node/commit/4abc45a4b9)] - **module**: do not warn when accessing `__esModule` of unfinished exports (Anna Henningsen) [#33048](https://github.com/nodejs/node/pull/33048) +* [[`21d314e7fc`](https://github.com/nodejs/node/commit/21d314e7fc)] - **module**: exports not exported for null resolutions (Guy Bedford) [#32838](https://github.com/nodejs/node/pull/32838) +* [[`eaf841d585`](https://github.com/nodejs/node/commit/eaf841d585)] - **module**: improve error for invalid package targets (Myles Borins) [#32052](https://github.com/nodejs/node/pull/32052) +* [[`8663fd5f88`](https://github.com/nodejs/node/commit/8663fd5f88)] - **module**: partial doc removal of --experimental-modules (Myles Borins) [#32915](https://github.com/nodejs/node/pull/32915) +* [[`68656cf588`](https://github.com/nodejs/node/commit/68656cf588)] - **n-api**: fix false assumption on napi\_async\_context structures (legendecas) [#32928](https://github.com/nodejs/node/pull/32928) +* [[`861eb39307`](https://github.com/nodejs/node/commit/861eb39307)] - **(SEMVER-MINOR)** **n-api**: detect deadlocks in thread-safe function (Gabriel Schulhof) [#32860](https://github.com/nodejs/node/pull/32860) +* [[`a133ac17eb`](https://github.com/nodejs/node/commit/a133ac17eb)] - **perf_hooks**: remove unnecessary assignment when name is undefined (rickyes) [#32910](https://github.com/nodejs/node/pull/32910) +* [[`59b64adb79`](https://github.com/nodejs/node/commit/59b64adb79)] - **src**: add AsyncWrapObject constructor template factory (Stephen Belanger) [#33051](https://github.com/nodejs/node/pull/33051) +* [[`23eda417b6`](https://github.com/nodejs/node/commit/23eda417b6)] - **src**: do not compare against wide characters (Christopher Beeson) [#32921](https://github.com/nodejs/node/pull/32921) +* [[`d10c2c6968`](https://github.com/nodejs/node/commit/d10c2c6968)] - **src**: fix empty-named env var assertion failure (Christopher Beeson) [#32921](https://github.com/nodejs/node/pull/32921) +* [[`44c157e45d`](https://github.com/nodejs/node/commit/44c157e45d)] - **src**: assignment to valid type (Yash Ladha) [#32879](https://github.com/nodejs/node/pull/32879) +* [[`d82c3c28de`](https://github.com/nodejs/node/commit/d82c3c28de)] - **src**: delete MicroTaskPolicy namespace (Juan José Arboleda) [#32853](https://github.com/nodejs/node/pull/32853) +* [[`bc755fc4c2`](https://github.com/nodejs/node/commit/bc755fc4c2)] - **src**: fix compiler warnings in node\_http2.cc (Daniel Bevenius) [#33014](https://github.com/nodejs/node/pull/33014) +* [[`30c2b0f798`](https://github.com/nodejs/node/commit/30c2b0f798)] - **(SEMVER-MINOR)** **src**: deprecate embedder APIs with replacements (Anna Henningsen) [#32858](https://github.com/nodejs/node/pull/32858) +* [[`95e897edfc`](https://github.com/nodejs/node/commit/95e897edfc)] - **src**: use using NewStringType (rickyes) [#32843](https://github.com/nodejs/node/pull/32843) +* [[`4221b1c8c9`](https://github.com/nodejs/node/commit/4221b1c8c9)] - **src**: fix null deref in AllocatedBuffer::clear (Matt Kulukundis) [#32892](https://github.com/nodejs/node/pull/32892) +* [[`f9b8988df6`](https://github.com/nodejs/node/commit/f9b8988df6)] - **src**: remove validation of unreachable code (Juan José Arboleda) [#32818](https://github.com/nodejs/node/pull/32818) +* [[`307e43da4d`](https://github.com/nodejs/node/commit/307e43da4d)] - **src**: elevate v8 namespaces (Nimit) [#32872](https://github.com/nodejs/node/pull/32872) +* [[`ca7e0a226e`](https://github.com/nodejs/node/commit/ca7e0a226e)] - **src**: remove redundant v8::HeapSnapshot namespace (Juan José Arboleda) [#32854](https://github.com/nodejs/node/pull/32854) +* [[`ae157b8ca7`](https://github.com/nodejs/node/commit/ae157b8ca7)] - **(SEMVER-MINOR)** **stream**: don't emit end after close (Robert Nagy) [#33076](https://github.com/nodejs/node/pull/33076) +* [[`184e80a144`](https://github.com/nodejs/node/commit/184e80a144)] - **stream**: don't wait for close on legacy streams (Robert Nagy) [#33058](https://github.com/nodejs/node/pull/33058) +* [[`e07c4ffc39`](https://github.com/nodejs/node/commit/e07c4ffc39)] - **stream**: fix sync write perf regression (Robert Nagy) [#33032](https://github.com/nodejs/node/pull/33032) +* [[`2bb4ac409b`](https://github.com/nodejs/node/commit/2bb4ac409b)] - **stream**: avoid drain for sync streams (Robert Nagy) [#32887](https://github.com/nodejs/node/pull/32887) +* [[`c21f1f03c5`](https://github.com/nodejs/node/commit/c21f1f03c5)] - **stream**: removes unnecessary params (Jesus Hernandez) [#32936](https://github.com/nodejs/node/pull/32936) +* [[`4c10b5f378`](https://github.com/nodejs/node/commit/4c10b5f378)] - **stream**: consistent punctuation (Robert Nagy) [#32934](https://github.com/nodejs/node/pull/32934) +* [[`1a2b3eb3a4`](https://github.com/nodejs/node/commit/1a2b3eb3a4)] - **stream**: fix broken pipeline test (Robert Nagy) [#33030](https://github.com/nodejs/node/pull/33030) +* [[`7abc61f668`](https://github.com/nodejs/node/commit/7abc61f668)] - **stream**: refactor Writable buffering (Robert Nagy) [#31046](https://github.com/nodejs/node/pull/31046) +* [[`180b935b58`](https://github.com/nodejs/node/commit/180b935b58)] - **stream**: pipeline should only destroy un-finished streams (Robert Nagy) [#32968](https://github.com/nodejs/node/pull/32968) +* [[`7647860000`](https://github.com/nodejs/node/commit/7647860000)] - **stream**: finished should complete with read-only Duplex (Robert Nagy) [#32967](https://github.com/nodejs/node/pull/32967) +* [[`36a4f54d69`](https://github.com/nodejs/node/commit/36a4f54d69)] - **stream**: close iterator in Readable.from (Vadzim Zieńka) [#32844](https://github.com/nodejs/node/pull/32844) +* [[`7f498125e4`](https://github.com/nodejs/node/commit/7f498125e4)] - **stream**: inline unbuffered \_write (Robert Nagy) [#32886](https://github.com/nodejs/node/pull/32886) +* [[`2ab4ebc8bf`](https://github.com/nodejs/node/commit/2ab4ebc8bf)] - **stream**: simplify Writable.end() (Robert Nagy) [#32882](https://github.com/nodejs/node/pull/32882) +* [[`11ea13f96c`](https://github.com/nodejs/node/commit/11ea13f96c)] - **test**: refactor test-async-hooks-constructor (himself65) [#33063](https://github.com/nodejs/node/pull/33063) +* [[`8fad112d93`](https://github.com/nodejs/node/commit/8fad112d93)] - **test**: remove timers-blocking-callback (Jeremiah Senkpiel) [#32870](https://github.com/nodejs/node/pull/32870) +* [[`988c2fe287`](https://github.com/nodejs/node/commit/988c2fe287)] - **test**: better error validations for event-capture (Adrian Estrada) [#32771](https://github.com/nodejs/node/pull/32771) +* [[`45e188b2e3`](https://github.com/nodejs/node/commit/45e188b2e3)] - **test**: refactor events tests for invalid listeners (Adrian Estrada) [#32769](https://github.com/nodejs/node/pull/32769) +* [[`b4ef06267d`](https://github.com/nodejs/node/commit/b4ef06267d)] - **test**: test-async-wrap-constructor prefer forEach (Daniel Estiven Rico Posada) [#32631](https://github.com/nodejs/node/pull/32631) +* [[`c9ae385abf`](https://github.com/nodejs/node/commit/c9ae385abf)] - **test**: mark test-child-process-fork-args as flaky on Windows (Andrey Pechkurov) [#32950](https://github.com/nodejs/node/pull/32950) +* [[`b12204e27e`](https://github.com/nodejs/node/commit/b12204e27e)] - **test**: changed function to arrow function (Nimit) [#32875](https://github.com/nodejs/node/pull/32875) +* [[`323da6f251`](https://github.com/nodejs/node/commit/323da6f251)] - **tls**: add highWaterMark option for connect (rickyes) [#32786](https://github.com/nodejs/node/pull/32786) +* [[`308681307f`](https://github.com/nodejs/node/commit/308681307f)] - **tls**: move getAllowUnauthorized to internal/options (James M Snell) [#32917](https://github.com/nodejs/node/pull/32917) +* [[`6a8e266a3b`](https://github.com/nodejs/node/commit/6a8e266a3b)] - **tools**: update ESLint to 7.0.0-rc.0 (himself65) [#33062](https://github.com/nodejs/node/pull/33062) +* [[`fa7d969237`](https://github.com/nodejs/node/commit/fa7d969237)] - **tools**: remove unused code in doc generation tool (Rich Trott) [#32913](https://github.com/nodejs/node/pull/32913) +* [[`ca5ebcfb67`](https://github.com/nodejs/node/commit/ca5ebcfb67)] - **tools**: fix mkcodecache when run with ASAN (Anna Henningsen) [#32850](https://github.com/nodejs/node/pull/32850) +* [[`22ccf2ba1f`](https://github.com/nodejs/node/commit/22ccf2ba1f)] - **tools**: decrease timeout in test.py (Anna Henningsen) [#32868](https://github.com/nodejs/node/pull/32868) +* [[`c82c08416f`](https://github.com/nodejs/node/commit/c82c08416f)] - **util,readline**: NFC-normalize strings before getStringWidth (Anna Henningsen) [#33052](https://github.com/nodejs/node/pull/33052) +* [[`4143c747fc`](https://github.com/nodejs/node/commit/4143c747fc)] - **(SEMVER-MINOR)** **vm**: add importModuleDynamically option to compileFunction (Gus Caplan) [#32985](https://github.com/nodejs/node/pull/32985) +* [[`c84d802449`](https://github.com/nodejs/node/commit/c84d802449)] - **worker**: fix process.env var empty key access (Christopher Beeson) [#32921](https://github.com/nodejs/node/pull/32921) + ## 2020-04-21, Version 14.0.0 (Current), @BethGriggs @@ -79,6 +192,10 @@ interact with `std::shared_ptr`. This is expected to be fixed in a later version #### Update to V8 8.1 * **(SEMVER-MAJOR)** **deps**: update V8 to 8.1.307.20 (Matheus Marchini) [#32116](https://github.com/nodejs/node/pull/32116) + * Enables Optional Chaining by default ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining), [v8.dev](https://v8.dev/features/optional-chaining)) + * Enables Nullish Coalescing by default ([MDN](https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_Coalescing_Operator), [v8.dev](https://v8.dev/features/nullish-coalescing)) + * Enables `Intl.DisplayNames` by default ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DisplayNames), [v8.dev](https://v8.dev/features/intl-displaynames)) + * Enables `calendar` and `numberingSystem` options for `Intl.DateTimeFormat` by default ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat)) #### Other Notable Changes: diff --git a/doc/changelogs/CHANGELOG_V4.md b/doc/changelogs/CHANGELOG_V4.md index 2f5c81319025c7..69f36cf2cea9d9 100644 --- a/doc/changelogs/CHANGELOG_V4.md +++ b/doc/changelogs/CHANGELOG_V4.md @@ -2,6 +2,7 @@ +
+14.1.0
14.0.0
diff --git a/doc/changelogs/CHANGELOG_V5.md b/doc/changelogs/CHANGELOG_V5.md index ac338886c858c6..c9cd28d692bfaf 100644 --- a/doc/changelogs/CHANGELOG_V5.md +++ b/doc/changelogs/CHANGELOG_V5.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 763ff802884781..20c9370ff0d5ab 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V7.md b/doc/changelogs/CHANGELOG_V7.md index 5a06890f58685b..a64b973c8c2192 100644 --- a/doc/changelogs/CHANGELOG_V7.md +++ b/doc/changelogs/CHANGELOG_V7.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V8.md b/doc/changelogs/CHANGELOG_V8.md index 33fa32948389b6..41e38efcf57206 100644 --- a/doc/changelogs/CHANGELOG_V8.md +++ b/doc/changelogs/CHANGELOG_V8.md @@ -2,6 +2,7 @@ +
diff --git a/doc/changelogs/CHANGELOG_V9.md b/doc/changelogs/CHANGELOG_V9.md index f58341bb34b52d..e4cdf50a9381b6 100644 --- a/doc/changelogs/CHANGELOG_V9.md +++ b/doc/changelogs/CHANGELOG_V9.md @@ -2,6 +2,7 @@ +
diff --git a/doc/guides/cve-management-process.md b/doc/guides/cve-management-process.md index 1b87215ac722f2..eba94484b53877 100644 --- a/doc/guides/cve-management-process.md +++ b/doc/guides/cve-management-process.md @@ -3,7 +3,7 @@ The Node.js project acts as a [Common Vulnerabilities and Exposures (CVE) Numbering Authority (CNA)](https://cve.mitre.org/cve/cna.html). The current scope is for all actively developed versions of software -developed under the Node.js project (ie. https://github.com/nodejs). +developed under the Node.js project (ie. ). This means that the Node.js team reviews CVE requests and if appropriate assigns CVE numbers to vulnerabilities. The scope currently **does not** include third party modules. @@ -18,17 +18,17 @@ of contact points. Email aliases have been setup for these as follows: * **Public contact points**. Email address to which people will be directed by Mitre when they are asked for a way to contact the Node.js team about - CVE-related issues. **cve-request@iojs.org** + CVE-related issues. **[cve-request@iojs.org][]** * **Private contact points**. Administrative contacts that Mitre can reach out to directly in case there are issues that require immediate attention. - **cve-mitre-contact@iojs.org** + **[cve-mitre-contact@iojs.org][]** * **Email addresses to add to the CNA email discussion list**. This address has been added to a closed mailing list that is used for announcements, sharing documents, or discussion relevant to the CNA community. The list rarely has more than ten messages a week. - **cna-discussion-list@iojs.org** + **[cna-discussion-list@iojs.org][]** ## CNA management processes @@ -56,7 +56,7 @@ as outlined in the section titled `CVE Management process`. In addition, when moving a CVE from Available such that there are less than two remaining CVEs a new block must be requested as follows: -* Use the Mitre request form https://cveform.mitre.org/ with the +* Use the Mitre request form with the option `Request a Block of IDs` to request a new block. * The new block will be sent to the requester through email. * Once the new block has been received, the requester will add them @@ -72,7 +72,7 @@ of CVEs should then be requested using the steps listed above. ### External CVE request process -When a request for a CVE is received via the cve-request@iojs.org +When a request for a CVE is received via the [cve-request@iojs.org][] email alias the following process will be followed (likely updated after we get HackerOne up and running). @@ -135,3 +135,7 @@ following steps are used to assign, announce and report a CVE. * Move the CVE from the Pending section to the Announced section along with a link to the Node.js blog post announcing that releases are available. + +[cve-request@iojs.org]: mailto:cve-request@iojs.org +[cve-mitre-contact@iojs.org]: mailto:cve-mitre-contact@iojs.org +[cna-discussion-list@iojs.org]: mailto:cna-discussion-list@iojs.org diff --git a/doc/guides/diagnostic-tooling-support-tiers.md b/doc/guides/diagnostic-tooling-support-tiers.md index 62bca48e1b7af7..254f90ecadd5fd 100644 --- a/doc/guides/diagnostic-tooling-support-tiers.md +++ b/doc/guides/diagnostic-tooling-support-tiers.md @@ -95,7 +95,8 @@ The tools are currently assigned to Tiers as follows: | Tool Type | Tool/API Name | Regular Testing in Node.js CI | Integrated with Node.js | Target Tier | |-----------|---------------------------|-------------------------------|-------------------------|-------------| - | | | | | | + | FFDC | diagnostic report | Yes | Yes | 1 | + | | | | | | ## Tier 2 diff --git a/doc/guides/maintaining-openssl.md b/doc/guides/maintaining-openssl.md index 5be6a5f5e2cd10..af59486b0f3219 100644 --- a/doc/guides/maintaining-openssl.md +++ b/doc/guides/maintaining-openssl.md @@ -5,7 +5,7 @@ This document describes how to update `deps/openssl/`. ## Requirements * Linux environment * `perl` Only Perl version 5 is tested. -* `nasm` (http://www.nasm.us/) The version of 2.11 or higher is needed. +* `nasm` () The version of 2.11 or higher is needed. * GNU `as` in binutils. The version of 2.26 or higher is needed. ## 0. Check Requirements @@ -27,7 +27,7 @@ NASM version 2.11.08 ## 1. Obtain and extract new OpenSSL sources -Get a new source from https://www.openssl.org/source/ and extract +Get a new source from and extract all files into `deps/openssl/openssl`. Then add all files and commit them. ```sh @@ -57,7 +57,7 @@ This updates all sources in deps/openssl/openssl by: Use `make` to regenerate all platform dependent files in `deps/openssl/config/archs/`: ```sh -% cd deps/openssl/config; make +% make -C deps/openssl/config ``` ## 3. Check diffs @@ -66,8 +66,7 @@ Check diffs if updates are right. Even if no updates in openssl sources, `buildinf.h` files will be updated for they have a timestamp data in them. ```sh -% cd deps/openssl/config -% git diff +% git diff -- deps/openssl ``` *Note*: On Windows, OpenSSL Configure generates `makefile` that can be @@ -95,8 +94,7 @@ The commit message can be (with the openssl version set to the relevant value): After an OpenSSL source update, all the config files need to be regenerated and committed by: - $ cd deps/openssl/config - $ make + $ make -C deps/openssl/config $ git add deps/openssl/config/archs $ git add deps/openssl/openssl/include/crypto/bn_conf.h $ git add deps/openssl/openssl/include/crypto/dso_conf.h diff --git a/doc/guides/offboarding.md b/doc/guides/offboarding.md index 3db892b0f3de3d..13f602bb0f8286 100644 --- a/doc/guides/offboarding.md +++ b/doc/guides/offboarding.md @@ -13,4 +13,4 @@ Emeritus or leaves the project. * Some teams may also require a pull request to remove the Collaborator from a team listing. For example, if someone is removed from @nodejs/build, they should also be removed from the Build WG README.md file in the - https://github.com/nodejs/build repository. + repository. diff --git a/doc/guides/onboarding-extras.md b/doc/guides/onboarding-extras.md index a44a55987fc50a..26060a48022221 100644 --- a/doc/guides/onboarding-extras.md +++ b/doc/guides/onboarding-extras.md @@ -21,6 +21,8 @@ request. * `feature request` - Any issue that requests a new feature (usually not PRs) * `good first issue` - Issues suitable for newcomers to process * `meta` - For issues whose topic is governance, policies, procedures, etc. +* `tsc-agenda` - Open issues and pull requests with this label will be added to + the Technical Steering Committee meeting agenda -- diff --git a/doc/guides/releases.md b/doc/guides/releases.md index 2068a46dc111e4..68f4d0b8bacc6f 100644 --- a/doc/guides/releases.md +++ b/doc/guides/releases.md @@ -25,13 +25,15 @@ official release builds for Node.js, hosted on . * [10. Test the Build](#10-test-the-build) * [11. Tag and Sign the Release Commit](#11-tag-and-sign-the-release-commit) * [12. Set Up For the Next Release](#12-set-up-for-the-next-release) - * [13. Promote and Sign the Release Builds](#13-promote-and-sign-the-release-builds) - * [14. Check the Release](#14-check-the-release) - * [15. Create a Blog Post](#15-create-a-blog-post) - * [16. Create the release on GitHub](#16-create-the-release-on-github) - * [17. Cleanup](#17-cleanup) - * [18. Announce](#18-announce) - * [19. Celebrate](#19-celebrate) + * [13. Cherry-pick the Release Commit to `master`](#13-cherry-pick-the-release-commit-to-master) + * [14. Push the release tag](#14-push-the-release-tag) + * [15. Promote and Sign the Release Builds](#15-promote-and-sign-the-release-builds) + * [16. Check the Release](#16-check-the-release) + * [17. Create a Blog Post](#17-create-a-blog-post) + * [18. Create the release on GitHub](#18-create-the-release-on-github) + * [19. Cleanup](#19-cleanup) + * [20. Announce](#20-announce) + * [21. Celebrate](#21-celebrate) * [LTS Releases](#lts-releases) * [Major Releases](#major-releases) @@ -528,15 +530,31 @@ $ git rebase v1.x $ git push upstream v1.x-staging ``` -Cherry-pick the release commit to `master`. After cherry-picking, edit -`src/node_version.h` to ensure the version macros contain whatever values were -previously on `master`. `NODE_VERSION_IS_RELEASE` should be `0`. **Do not** -cherry-pick the "Working on vx.y.z" commit to `master`. +### 13. Cherry-pick the Release Commit to `master` -Run `make lint` before pushing to `master`, to make sure the Changelog -formatting passes the lint rules on `master`. +```console +$ git checkout master +$ git cherry-pick v1.x^ +``` + +Git should stop to let you fix conflicts. Revert all changes that were made to +`src/node_version.h`. If there are conflicts in `doc` due to updated `REPLACEME` +placeholders (that happens when a change previously landed on another release +branch), keep both version numbers. Convert the YAML field to an array if it is +not already one. + +Then finish cherry-picking and push the commit upstream: + +```console +$ git add src/node_version.h doc +$ git cherry-pick --continue +$ make lint +$ git push upstream master +``` + +**Do not** cherry-pick the "Working on vx.y.z" commit to `master`. -### 13. Push the release tag +### 14. Push the release tag Push the tag to the repo before you promote the builds. If you haven't pushed your tag first, then build promotion won't work properly. Push the tag using the @@ -549,7 +567,7 @@ $ git push *Note*: Please do not push the tag unless you are ready to complete the remainder of the release steps. -### 14. Promote and Sign the Release Builds +### 15. Promote and Sign the Release Builds **The same individual who signed the release tag must be the one to promote the builds as the `SHASUMS256.txt` file needs to be signed with the @@ -622,7 +640,7 @@ be prompted to re-sign `SHASUMS256.txt`. **It is possible to only sign a release by running `./tools/release.sh -s vX.Y.Z`.** -### 15. Check the Release +### 16. Check the Release Your release should be available at `https://nodejs.org/dist/vx.y.z/` and . Check that the appropriate files are in @@ -631,7 +649,7 @@ have the right internal version strings. Check that the API docs are available at . Check that the release catalog files are correct at and . -### 16. Create a Blog Post +### 17. Create a Blog Post There is an automatic build that is kicked off when you promote new builds, so within a few minutes nodejs.org will be listing your new version as the latest @@ -664,7 +682,7 @@ This script will use the promoted builds and changelog to generate the post. Run * Changes to `master` on the [nodejs.org repository][] will trigger a new build of nodejs.org so your changes should appear a few minutes after pushing. -### 17. Create the release on GitHub +### 18. Create the release on GitHub * Go to the [New release page](https://github.com/nodejs/node/releases/new). * Select the tag version you pushed earlier. @@ -672,17 +690,17 @@ This script will use the promoted builds and changelog to generate the post. Run * For the description, copy the rest of the changelog entry. * Click on the "Publish release" button. -### 18. Cleanup +### 19. Cleanup Close your release proposal PR and delete the proposal branch. -### 19. Announce +### 20. Announce The nodejs.org website will automatically rebuild and include the new version. To announce the build on Twitter through the official @nodejs account, email [pr@nodejs.org](mailto:pr@nodejs.org) with a message such as: -> v5.8.0 of @nodejs is out: https://nodejs.org/en/blog/release/v5.8.0/ +> v5.8.0 of @nodejs is out: > … > something here about notable changes @@ -693,7 +711,7 @@ announcements. Ping the IRC ops and the other [Partner Communities][] liaisons. -### 20. Celebrate +### 21. Celebrate _In whatever form you do this..._ diff --git a/doc/guides/security-release-process.md b/doc/guides/security-release-process.md index 55951f94d4ae1f..acf6b56558e3ae 100644 --- a/doc/guides/security-release-process.md +++ b/doc/guides/security-release-process.md @@ -2,7 +2,7 @@ The security release process covers the steps required to plan/implement a security release. This document is copied into the description of the Next -Security Release, and used to track progess on the release. It contains ***TEXT +Security Release, and used to track progress on the release. It contains ***TEXT LIKE THIS*** which will be replaced during the release process with the information described. @@ -88,6 +88,6 @@ information described. * [ ] Make sure the PRs for the vulnerabilities are closed. [H1 CVE requests]: https://hackerone.com/nodejs/cve_requests -[docker-node]: https://github.com/nodejs/docker-node/issues) -[nodejs/build]: https://github.com/nodejs/build/issues) +[docker-node]: https://github.com/nodejs/docker-node/issues +[nodejs/build]: https://github.com/nodejs/build/issues [email]: https://groups.google.com/forum/#!forum/nodejs-sec diff --git a/doc/guides/using-symbols.md b/doc/guides/using-symbols.md index b4bf9cd67f4081..2bc32862b7169e 100644 --- a/doc/guides/using-symbols.md +++ b/doc/guides/using-symbols.md @@ -9,7 +9,7 @@ Symbol-keyed properties of an object are not included in the output of default. Learn more about symbols at -https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol. +. ## `Symbol(string)` diff --git a/doc/guides/writing-and-running-benchmarks.md b/doc/guides/writing-and-running-benchmarks.md index 0075023ce80fa8..eca55bf4edf2ea 100644 --- a/doc/guides/writing-and-running-benchmarks.md +++ b/doc/guides/writing-and-running-benchmarks.md @@ -54,7 +54,7 @@ from [nghttp2.org][] or built from source. ### Benchmark Analysis Requirements To analyze the results, `R` should be installed. Use one of the available -package managers or download it from https://www.r-project.org/. +package managers or download it from . The R packages `ggplot2` and `plyr` are also used and can be installed using the R REPL. @@ -68,7 +68,7 @@ install.packages("plyr") In the event that a message is reported stating that a CRAN mirror must be selected first, specify a mirror by adding in the repo parameter. -If we used the "http://cran.us.r-project.org" mirror, it could look something +If we used the "" mirror, it could look something like this: ```R diff --git a/doc/guides/writing-tests.md b/doc/guides/writing-tests.md index 7022bf8f938f78..385e3813fdbd69 100644 --- a/doc/guides/writing-tests.md +++ b/doc/guides/writing-tests.md @@ -430,7 +430,7 @@ To generate a test coverage report, see the [Test Coverage section of the Building guide][]. Nightly coverage reports for the Node.js master branch are available at -https://coverage.nodejs.org/. +. [ASCII]: http://man7.org/linux/man-pages/man7/ascii.7.html [Google Test]: https://github.com/google/googletest diff --git a/doc/node.1 b/doc/node.1 index 9bb344fdf27b2d..ec2642170aee6f 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -132,9 +132,6 @@ Specify the .Ar module to use as a custom module loader. . -.It Fl -experimental-modules -Enable experimental latest experimental modules features. -. .It Fl -experimental-policy Use the specified file as a security policy. . diff --git a/glossary.md b/glossary.md index a48fd6083b407f..a2954635a5ce93 100644 --- a/glossary.md +++ b/glossary.md @@ -1,4 +1,4 @@ -You may also need to check https://chromium.googlesource.com/chromiumos/docs/+/master/glossary.md. +You may also need to check . * LGTM: "Looks good to me", commonly used to approve a code review. * PTAL: Please take a look. diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index fe2281df471dc7..07a16175ffcd73 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -83,7 +83,7 @@ ObjectDefineProperties(Duplex.prototype, { }, set(value) { // Backward compatibility, the user is explicitly - // managing destroyed + // managing destroyed. if (this._readableState && this._writableState) { this._readableState.destroyed = value; this._writableState.destroyed = value; diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index ef847c110edc23..ec9f86d7eacf4a 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -94,7 +94,7 @@ function ReadableState(options, stream, isDuplex) { isDuplex = stream instanceof Stream.Duplex; // Object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away + // make all the buffer merging and length checks go away. this.objectMode = !!(options && options.objectMode); if (isDuplex) @@ -109,7 +109,7 @@ function ReadableState(options, stream, isDuplex) { // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than - // array.shift() + // array.shift(). this.buffer = new BufferList(); this.length = 0; this.pipes = []; @@ -132,16 +132,16 @@ function ReadableState(options, stream, isDuplex) { this.resumeScheduled = false; this[kPaused] = null; - // True if the error was already emitted and should not be thrown again + // True if the error was already emitted and should not be thrown again. this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true. this.emitClose = !options || options.emitClose !== false; - // Should .destroy() be called after 'end' (and potentially 'finish') + // Should .destroy() be called after 'end' (and potentially 'finish'). this.autoDestroy = !options || options.autoDestroy !== false; - // Has it been destroyed + // Has it been destroyed. this.destroyed = false; // Indicates whether the stream has errored. @@ -150,17 +150,21 @@ function ReadableState(options, stream, isDuplex) { // Indicates whether the stream has finished destroying. this.closed = false; + // True if close has been emitted or would have been emitted + // depending on emitClose. + this.closeEmitted = false; + // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = (options && options.defaultEncoding) || 'utf8'; // Ref the piped dest which we need a drain event on it - // type: null | Writable | Set + // type: null | Writable | Set. this.awaitDrainWriters = null; this.multiAwaitDrain = false; - // If true, a maybeReadMore has been scheduled + // If true, a maybeReadMore has been scheduled. this.readingMore = false; this.decoder = null; @@ -179,7 +183,7 @@ function Readable(options) { return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside - // the ReadableState constructor, at least with V8 6.5 + // the ReadableState constructor, at least with V8 6.5. const isDuplex = this instanceof Stream.Duplex; this._readableState = new ReadableState(options, this, isDuplex); @@ -213,7 +217,7 @@ Readable.prototype.push = function(chunk, encoding) { return readableAddChunk(this, chunk, encoding, false); }; -// Unshift should *always* be something directly out of read() +// Unshift should *always* be something directly out of read(). Readable.prototype.unshift = function(chunk, encoding) { return readableAddChunk(this, chunk, encoding, true); }; @@ -228,7 +232,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { encoding = encoding || state.defaultEncoding; if (addToFront && state.encoding && state.encoding !== encoding) { // When unshifting, if state.encoding is set, we have to save - // the string in the BufferList with the state encoding + // the string in the BufferList with the state encoding. chunk = Buffer.from(chunk, encoding).toString(state.encoding); } else if (encoding !== state.encoding) { chunk = Buffer.from(chunk, encoding); @@ -319,7 +323,7 @@ Readable.prototype.setEncoding = function(enc) { StringDecoder = require('string_decoder').StringDecoder; const decoder = new StringDecoder(enc); this._readableState.decoder = decoder; - // If setEncoding(null), decoder.encoding equals utf8 + // If setEncoding(null), decoder.encoding equals utf8. this._readableState.encoding = this._readableState.decoder.encoding; const buffer = this._readableState.buffer; @@ -335,7 +339,7 @@ Readable.prototype.setEncoding = function(enc) { return this; }; -// Don't raise the hwm > 1GB +// Don't raise the hwm > 1GB. const MAX_HWM = 0x40000000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { @@ -343,7 +347,7 @@ function computeNewHighWaterMark(n) { n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts + // tiny amounts. n--; n |= n >>> 1; n |= n >>> 2; @@ -363,7 +367,7 @@ function howMuchToRead(n, state) { if (state.objectMode) return 1; if (NumberIsNaN(n)) { - // Only flow one buffer at a time + // Only flow one buffer at a time. if (state.flowing && state.length) return state.buffer.first().length; else @@ -446,7 +450,7 @@ Readable.prototype.read = function(n) { let doRead = state.needReadable; debug('need readable', doRead); - // If we currently have less than the highWaterMark, then also read some + // If we currently have less than the highWaterMark, then also read some. if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); @@ -524,7 +528,7 @@ function onEofChunk(stream, state) { if (state.sync) { // If we are sync, wait until next tick to emit the data. // Otherwise we risk emitting data in the flow() - // the readable code triggers during a read() call + // the readable code triggers during a read() call. emitReadable(stream); } else { // Emit 'readable' now to make sure it gets picked up. @@ -558,7 +562,7 @@ function emitReadable_(stream) { state.emittedReadable = false; } - // The stream needs another readable event if + // The stream needs another readable event if: // 1. It is not flowing, as the flow mechanism will take // care of it. // 2. It is not ended. @@ -677,7 +681,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { let cleanedUp = false; function cleanup() { debug('cleanup'); - // Cleanup event handlers once the pipe is broken + // Cleanup event handlers once the pipe is broken. dest.removeListener('close', onclose); dest.removeListener('finish', onfinish); if (ondrain) { @@ -771,7 +775,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) { src.unpipe(dest); } - // Tell the dest that it's being piped to + // Tell the dest that it's being piped to. dest.emit('pipe', src); // Start the flow if it hasn't been started already. @@ -841,7 +845,7 @@ Readable.prototype.unpipe = function(dest) { }; // Set up data events if they are asked for -// Ensure readable listeners eventually get something +// Ensure readable listeners eventually get something. Readable.prototype.on = function(ev, fn) { const res = Stream.prototype.on.call(this, ev, fn); const state = this._readableState; @@ -851,7 +855,7 @@ Readable.prototype.on = function(ev, fn) { // a few lines down. This is needed to support once('readable'). state.readableListening = this.listenerCount('readable') > 0; - // Try start flowing on next tick if stream isn't explicitly paused + // Try start flowing on next tick if stream isn't explicitly paused. if (state.flowing !== false) this.resume(); } else if (ev === 'readable') { @@ -914,7 +918,7 @@ function updateReadableListening(self) { // the upcoming resume will not flow. state.flowing = true; - // Crude way to check if we should resume + // Crude way to check if we should resume. } else if (self.listenerCount('data') > 0) { self.resume(); } else if (!state.readableListening) { @@ -935,7 +939,7 @@ Readable.prototype.resume = function() { debug('resume'); // We flow only if there is no one listening // for readable, but we still have to call - // resume() + // resume(). state.flowing = !state.readableListening; resume(this, state); } @@ -1003,7 +1007,7 @@ Readable.prototype.wrap = function(stream) { if (state.decoder) chunk = state.decoder.write(chunk); - // Don't skip over falsy values in objectMode + // Don't skip over falsy values in objectMode. if (state.objectMode && (chunk === null || chunk === undefined)) return; else if (!state.objectMode && (!chunk || !chunk.length)) @@ -1055,7 +1059,7 @@ Readable.prototype[SymbolAsyncIterator] = function() { // Making it explicit these properties are not enumerable // because otherwise some prototype manipulation in -// userland will fail +// userland will fail. ObjectDefineProperties(Readable.prototype, { readable: { get() { @@ -1132,13 +1136,13 @@ ObjectDefineProperties(Readable.prototype, { }, set(value) { // We ignore the value if the stream - // has not been initialized yet + // has not been initialized yet. if (!this._readableState) { return; } // Backward compatibility, the user is explicitly - // managing destroyed + // managing destroyed. this._readableState.destroyed = value; } }, @@ -1175,7 +1179,7 @@ Readable._fromList = fromList; // This function is designed to be inlinable, so please take care when making // changes to the function body. function fromList(n, state) { - // nothing buffered + // nothing buffered. if (state.length === 0) return null; @@ -1183,7 +1187,7 @@ function fromList(n, state) { if (state.objectMode) ret = state.buffer.shift(); else if (!n || n >= state.length) { - // Read it all, truncate the list + // Read it all, truncate the list. if (state.decoder) ret = state.buffer.join(''); else if (state.buffer.length === 1) @@ -1192,7 +1196,7 @@ function fromList(n, state) { ret = state.buffer.concat(state.length); state.buffer.clear(); } else { - // read part of list + // read part of list. ret = state.buffer.consume(n, state.decoder); } @@ -1213,7 +1217,8 @@ function endReadableNT(state, stream) { debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. - if (!state.errorEmitted && !state.endEmitted && state.length === 0) { + if (!state.errorEmitted && !state.closeEmitted && + !state.endEmitted && state.length === 0) { state.endEmitted = true; stream.emit('end'); @@ -1221,7 +1226,7 @@ function endReadableNT(state, stream) { process.nextTick(endWritableNT, state, stream); } else if (state.autoDestroy) { // In case of duplex streams we need a way to detect - // if the writable side is ready for autoDestroy as well + // if the writable side is ready for autoDestroy as well. const wState = stream._writableState; const autoDestroy = !wState || ( wState.autoDestroy && diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 14a7ede27611c4..4b353a52665efa 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -26,7 +26,6 @@ 'use strict'; const { - Array, FunctionPrototype, ObjectDefineProperty, ObjectDefineProperties, @@ -84,21 +83,21 @@ function WritableState(options, stream, isDuplex) { // The point at which write() starts returning false // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() + // the entire buffer is not flushed immediately on write(). this.highWaterMark = options ? getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex) : getDefaultHighWaterMark(false); - // if _final has been called + // if _final has been called. this.finalCalled = false; // drain event flag. this.needDrain = false; // At the start of calling end() this.ending = false; - // When end() has been called, and returned + // When end() has been called, and returned. this.ended = false; - // When 'finish' is emitted + // When 'finish' is emitted. this.finished = false; // Has it been destroyed @@ -123,7 +122,7 @@ function WritableState(options, stream, isDuplex) { // A flag to see when we're in the middle of a write. this.writing = false; - // When true all writes will be buffered until .uncork() call + // When true all writes will be buffered until .uncork() call. this.corked = 0; // A flag to be able to tell if the onwrite cb is called immediately, @@ -137,10 +136,10 @@ function WritableState(options, stream, isDuplex) { // end up in an overlapped onwrite situation. this.bufferProcessing = false; - // The callback that's passed to _write(chunk,cb) + // The callback that's passed to _write(chunk, cb). this.onwrite = onwrite.bind(undefined, stream); - // The callback that the user supplies to write(chunk,encoding,cb) + // The callback that the user supplies to write(chunk, encoding, cb). this.writecb = null; // The amount that is being written when _write is called. @@ -150,24 +149,23 @@ function WritableState(options, stream, isDuplex) { // synchronous _write() completion. this.afterWriteTickInfo = null; - this.bufferedRequest = null; - this.lastBufferedRequest = null; + resetBuffer(this); // Number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted + // this must be 0 before 'finish' can be emitted. this.pendingcb = 0; // Emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams + // This is relevant for synchronous Transform streams. this.prefinished = false; - // True if the error was already emitted and should not be thrown again + // True if the error was already emitted and should not be thrown again. this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true. this.emitClose = !options || options.emitClose !== false; - // Should .destroy() be called after 'finish' (and potentially 'end') + // Should .destroy() be called after 'finish' (and potentially 'end'). this.autoDestroy = !options || options.autoDestroy !== false; // Indicates whether the stream has errored. When true all write() calls @@ -177,27 +175,25 @@ function WritableState(options, stream, isDuplex) { // Indicates whether the stream has finished destroying. this.closed = false; +} - // Count buffered requests - this.bufferedRequestCount = 0; - - // Allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - const corkReq = { next: null, entry: null, finish: undefined }; - corkReq.finish = onCorkedFinish.bind(undefined, corkReq, this); - this.corkedRequestsFree = corkReq; +function resetBuffer(state) { + state.buffered = []; + state.bufferedIndex = 0; + state.allBuffers = true; + state.allNoop = true; } WritableState.prototype.getBuffer = function getBuffer() { - let current = this.bufferedRequest; - const out = []; - while (current) { - out.push(current); - current = current.next; - } - return out; + return this.buffered.slice(this.bufferedIndex); }; +ObjectDefineProperty(WritableState.prototype, 'bufferedRequestCount', { + get() { + return this.buffered.length - this.bufferedIndex; + } +}); + // Test _writableState for inheritance to account for Duplex streams, // whose prototype chain only points to Readable. let realHasInstance; @@ -229,7 +225,7 @@ function Writable(options) { // `_writableState` that would lead to infinite recursion. // Checking for a Stream.Duplex instance is faster here instead of inside - // the WritableState constructor, at least with V8 6.5 + // the WritableState constructor, at least with V8 6.5. const isDuplex = (this instanceof Stream.Duplex); if (!isDuplex && !realHasInstance.call(Writable, this)) @@ -318,10 +314,7 @@ Writable.prototype.uncork = function() { if (state.corked) { state.corked--; - if (!state.writing && - !state.corked && - !state.bufferProcessing && - state.bufferedRequest) + if (!state.writing) clearBuffer(this, state); } }; @@ -339,34 +332,34 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { // If we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, cb) { +function writeOrBuffer(stream, state, chunk, encoding, callback) { const len = state.objectMode ? 1 : chunk.length; state.length += len; - const ret = state.length < state.highWaterMark; - // We must ensure that previous needDrain will not be reset to false. - if (!ret) - state.needDrain = true; - if (state.writing || state.corked || state.errored) { - const last = state.lastBufferedRequest; - state.lastBufferedRequest = { - chunk, - encoding, - callback: cb, - next: null - }; - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; + state.buffered.push({ chunk, encoding, callback }); + if (state.allBuffers && encoding !== 'buffer') { + state.allBuffers = false; + } + if (state.allNoop && callback !== nop) { + state.allNoop = false; } - state.bufferedRequestCount += 1; } else { - doWrite(stream, state, false, len, chunk, encoding, cb); + state.writelen = len; + state.writecb = callback; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; } + const ret = state.length < state.highWaterMark; + + // We must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + // Return false if errored or destroyed in order to break // any synchronous while(stream.write(data)) loops. return ret && !state.errored && !state.destroyed; @@ -422,21 +415,15 @@ function onwrite(stream, er) { onwriteError(stream, state, er, cb); } } else { - // Check if we're actually ready to finish, but don't emit yet - const finished = needFinish(state) || stream.destroyed; - - if (!finished && - !state.corked && - !state.bufferProcessing && - state.bufferedRequest) { + if (state.buffered.length > state.bufferedIndex) { clearBuffer(stream, state); } if (sync) { // It is a common case that the callback passed to .write() is always - // the same. In that case, we do not schedule a new nextTick(), but rather - // just increase a counter, to improve performance and avoid memory - // allocations. + // the same. In that case, we do not schedule a new nextTick(), but + // rather just increase a counter, to improve performance and avoid + // memory allocations. if (state.afterWriteTickInfo !== null && state.afterWriteTickInfo.cb === cb) { state.afterWriteTickInfo.count++; @@ -477,83 +464,69 @@ function afterWrite(stream, state, count, cb) { // If there's something in the buffer waiting, then invoke callbacks. function errorBuffer(state, err) { - if (state.writing || !state.bufferedRequest) { + if (state.writing) { return; } - for (let entry = state.bufferedRequest; entry; entry = entry.next) { - const len = state.objectMode ? 1 : entry.chunk.length; + for (let n = state.bufferedIndex; n < state.buffered.length; ++n) { + const { chunk, callback } = state.buffered[n]; + const len = state.objectMode ? 1 : chunk.length; state.length -= len; - entry.callback(err); + callback(err); } - state.bufferedRequest = null; - state.lastBufferedRequest = null; - state.bufferedRequestCount = 0; + + resetBuffer(state); } -// If there's something in the buffer waiting, then process it +// If there's something in the buffer waiting, then process it. function clearBuffer(stream, state) { + if (state.corked || state.bufferProcessing || state.destroyed) { + return; + } + + const { buffered, bufferedIndex, objectMode } = state; + const bufferedLength = buffered.length - bufferedIndex; + + if (!bufferedLength) { + return; + } + + let i = bufferedIndex; + state.bufferProcessing = true; - let entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - const l = state.bufferedRequestCount; - const buffer = new Array(l); - const holder = state.corkedRequestsFree; - holder.entry = entry; - - let count = 0; - let allBuffers = true; - while (entry) { - buffer[count] = entry; - if (entry.encoding !== 'buffer') - allBuffers = false; - entry = entry.next; - count += 1; - } - buffer.allBuffers = allBuffers; + if (bufferedLength > 1 && stream._writev) { + state.pendingcb -= bufferedLength - 1; - doWrite(stream, state, true, state.length, buffer, '', holder.finish); + const callback = state.allNoop ? nop : (err) => { + for (let n = i; n < buffered.length; ++n) { + buffered[n].callback(err); + } + }; + // Make a copy of `buffered` if it's going to be used by `callback` above, + // since `doWrite` will mutate the array. + const chunks = state.allNoop && i === 0 ? buffered : buffered.slice(i); + chunks.allBuffers = state.allBuffers; - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - const corkReq = { next: null, entry: null, finish: undefined }; - corkReq.finish = onCorkedFinish.bind(undefined, corkReq, state); - state.corkedRequestsFree = corkReq; - } - state.bufferedRequestCount = 0; + doWrite(stream, state, true, state.length, chunks, '', callback); + + resetBuffer(state); } else { - // Slow case, write chunks one-by-one - while (entry) { - const chunk = entry.chunk; - const encoding = entry.encoding; - const cb = entry.callback; - const len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - state.bufferedRequestCount--; - // If we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - break; - } + do { + const { chunk, encoding, callback } = buffered[i]; + buffered[i++] = null; + const len = objectMode ? 1 : chunk.length; + doWrite(stream, state, false, len, chunk, encoding, callback); + } while (i < buffered.length && !state.writing); + + if (i === buffered.length) { + resetBuffer(state); + } else if (i > 256) { + buffered.splice(0, i); + state.bufferedIndex = 0; + } else { + state.bufferedIndex = i; } - - if (entry === null) - state.lastBufferedRequest = null; } - - state.bufferedRequest = entry; state.bufferProcessing = false; } @@ -582,27 +555,32 @@ Writable.prototype.end = function(chunk, encoding, cb) { if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); - // .end() fully uncorks + // .end() fully uncorks. if (state.corked) { state.corked = 1; this.uncork(); } - if (typeof cb !== 'function') - cb = nop; - // This is forgiving in terms of unnecessary calls to end() and can hide // logic errors. However, usually such errors are harmless and causing a // hard error can be disproportionately destructive. It is not always // trivial for the user to determine whether end() needs to be called or not. + let err; if (!state.errored && !state.ending) { - endWritable(this, state, cb); + state.ending = true; + finishMaybe(this, state, true); + state.ended = true; } else if (state.finished) { - process.nextTick(cb, new ERR_STREAM_ALREADY_FINISHED('end')); + err = new ERR_STREAM_ALREADY_FINISHED('end'); } else if (state.destroyed) { - process.nextTick(cb, new ERR_STREAM_DESTROYED('end')); - } else if (cb !== nop) { - onFinished(this, state, cb); + err = new ERR_STREAM_DESTROYED('end'); + } + + if (typeof cb === 'function') { + if (err || state.finished) + process.nextTick(cb, err); + else + onFinished(this, cb); } return this; @@ -612,7 +590,7 @@ function needFinish(state) { return (state.ending && state.length === 0 && !state.errored && - state.bufferedRequest === null && + state.buffered.length === 0 && !state.finished && !state.writing); } @@ -669,7 +647,7 @@ function finish(stream, state) { if (state.autoDestroy) { // In case of duplex streams we need a way to detect - // if the readable side is ready for autoDestroy as well + // if the readable side is ready for autoDestroy as well. const rState = stream._readableState; const autoDestroy = !rState || ( rState.autoDestroy && @@ -683,34 +661,8 @@ function finish(stream, state) { } } -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state, true); - if (cb !== nop) { - if (state.finished) - process.nextTick(cb); - else - onFinished(stream, state, cb); - } - state.ended = true; -} - -function onCorkedFinish(corkReq, state, err) { - let entry = corkReq.entry; - corkReq.entry = null; - while (entry) { - const cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - - // Reuse the free corkReq. - state.corkedRequestsFree.next = corkReq; -} - // TODO(ronag): Avoid using events to implement internal logic. -function onFinished(stream, state, cb) { +function onFinished(stream, cb) { function onerror(err) { stream.removeListener('finish', onfinish); stream.removeListener('error', onerror); @@ -736,7 +688,7 @@ ObjectDefineProperties(Writable.prototype, { return this._writableState ? this._writableState.destroyed : false; }, set(value) { - // Backward compatibility, the user is explicitly managing destroyed + // Backward compatibility, the user is explicitly managing destroyed. if (this._writableState) { this._writableState.destroyed = value; } diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cf1d2c27b89fd4..1937f3984d71bc 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -70,7 +70,10 @@ const { ERR_TLS_INVALID_STATE } = codes; const { onpskexchange: kOnPskExchange } = internalBinding('symbols'); -const { getOptionValue } = require('internal/options'); +const { + getOptionValue, + getAllowUnauthorized, +} = require('internal/options'); const { validateString, validateBuffer, @@ -464,6 +467,7 @@ function TLSSocket(socket, opts) { this._securePending = false; this._newSessionPending = false; this._controlReleased = false; + this.secureConnecting = true; this._SNICallback = null; this.servername = null; this.alpnProtocol = null; @@ -494,7 +498,8 @@ function TLSSocket(socket, opts) { handle: this._wrapHandle(wrap), allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen, pauseOnCreate: tlsOptions.pauseOnConnect, - manualStart: true + manualStart: true, + highWaterMark: tlsOptions.highWaterMark, }); // Proxy for API compatibility @@ -1026,6 +1031,7 @@ function onServerSocketSecure() { if (!this.destroyed && this._releaseControl()) { debug('server emit secureConnection'); + this.secureConnecting = false; this._tlsOptions.server.emit('secureConnection', this); } } @@ -1533,22 +1539,12 @@ function onConnectEnd() { } } -let warnOnAllowUnauthorized = true; - // Arguments: [port,] [host,] [options,] [cb] exports.connect = function connect(...args) { args = normalizeConnectArgs(args); let options = args[0]; const cb = args[1]; - const allowUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0'; - - if (allowUnauthorized && warnOnAllowUnauthorized) { - warnOnAllowUnauthorized = false; - process.emitWarning('Setting the NODE_TLS_REJECT_UNAUTHORIZED ' + - 'environment variable to \'0\' makes TLS connections ' + - 'and HTTPS requests insecure by disabling ' + - 'certificate verification.'); - } + const allowUnauthorized = getAllowUnauthorized(); options = { rejectUnauthorized: !allowUnauthorized, @@ -1582,6 +1578,7 @@ exports.connect = function connect(...args) { requestOCSP: options.requestOCSP, enableTrace: options.enableTrace, pskCallback: options.pskCallback, + highWaterMark: options.highWaterMark, }); tlssock[kConnectOptions] = options; diff --git a/lib/internal/child_process/serialization.js b/lib/internal/child_process/serialization.js index 9f03a8e8446c43..df8a6ca67236c5 100644 --- a/lib/internal/child_process/serialization.js +++ b/lib/internal/child_process/serialization.js @@ -25,10 +25,9 @@ class ChildProcessSerializer extends v8.DefaultSerializer { if (isArrayBufferView(object)) { this.writeUint32(kArrayBufferViewTag); return super._writeHostObject(object); - } else { - this.writeUint32(kNotArrayBufferViewTag); - this.writeValue({ ...object }); } + this.writeUint32(kNotArrayBufferViewTag); + this.writeValue({ ...object }); } } diff --git a/lib/internal/cluster/master.js b/lib/internal/cluster/master.js index dc8efc1f98e56b..9d6d4df6316956 100644 --- a/lib/internal/cluster/master.js +++ b/lib/internal/cluster/master.js @@ -297,12 +297,7 @@ function queryServer(worker, message) { constructor = SharedHandle; } - handle = new constructor(key, - address, - message.port, - message.addressType, - message.fd, - message.flags); + handle = new constructor(key, address, message); handles.set(key, handle); } diff --git a/lib/internal/cluster/round_robin_handle.js b/lib/internal/cluster/round_robin_handle.js index 213b72c19f4273..492fd725c82f1d 100644 --- a/lib/internal/cluster/round_robin_handle.js +++ b/lib/internal/cluster/round_robin_handle.js @@ -13,7 +13,7 @@ const { constants } = internalBinding('tcp_wrap'); module.exports = RoundRobinHandle; -function RoundRobinHandle(key, address, port, addressType, fd, flags) { +function RoundRobinHandle(key, address, { port, fd, flags }) { this.key = key; this.all = new Map(); this.free = new Map(); diff --git a/lib/internal/cluster/shared_handle.js b/lib/internal/cluster/shared_handle.js index 20c028ce313d40..656b1292988948 100644 --- a/lib/internal/cluster/shared_handle.js +++ b/lib/internal/cluster/shared_handle.js @@ -6,7 +6,7 @@ const net = require('net'); module.exports = SharedHandle; -function SharedHandle(key, address, port, addressType, fd, flags) { +function SharedHandle(key, address, { port, addressType, fd, flags }) { this.key = key; this.workers = new Map(); this.handle = null; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index e0668e2f827e5f..e9e11bf0fb195b 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -20,6 +20,7 @@ const { ObjectDefineProperty, ObjectKeys, StringPrototypeSlice, + StringPrototypeStartsWith, Symbol, SymbolFor, WeakMap, @@ -1104,18 +1105,27 @@ E('ERR_INVALID_PACKAGE_CONFIG', (path, message, hasMessage = true) => { }, Error); E('ERR_INVALID_PACKAGE_TARGET', (pkgPath, key, subpath, target, base = undefined) => { + const relError = typeof target === 'string' && + target.length && !StringPrototypeStartsWith(target, './'); if (key === null) { if (subpath !== '') { return `Invalid "exports" target ${JSONStringify(target)} defined ` + `for '${subpath}' in the package config ${pkgPath} imported from ` + - base; + `${base}.${relError ? '; targets must start with "./"' : ''}`; } else { return `Invalid "exports" main target ${target} defined in the ` + - `package config ${pkgPath} imported from ${base}.`; + `package config ${pkgPath} imported from ${base}${relError ? + '; targets must start with "./"' : ''}`; } } else if (key === '.') { return `Invalid "exports" main target ${JSONStringify(target)} defined ` + - `in the package config ${pkgPath}${sep}package.json`; + `in the package config ${pkgPath}${sep}package.json${relError ? + '; targets must start with "./"' : ''}`; + } else if (relError) { + return `Invalid "exports" target ${JSONStringify(target)} defined for '${ + StringPrototypeSlice(key, 0, -subpath.length || key.length)}' in the ` + + `package config ${pkgPath}${sep}package.json; ` + + 'targets must start with "./"'; } else { return `Invalid "exports" target ${JSONStringify(target)} defined for '${ StringPrototypeSlice(key, 0, -subpath.length || key.length)}' in the ` + diff --git a/lib/internal/fixed_queue.js b/lib/internal/fixed_queue.js index d3ffbc2a1e154e..f6f3110d8ec5d4 100644 --- a/lib/internal/fixed_queue.js +++ b/lib/internal/fixed_queue.js @@ -56,7 +56,7 @@ const kMask = kSize - 1; // `top + 1 === bottom` it's full. This wastes a single space of storage // but allows much quicker checks. -const FixedCircularBuffer = class FixedCircularBuffer { +class FixedCircularBuffer { constructor() { this.bottom = 0; this.top = 0; @@ -85,7 +85,7 @@ const FixedCircularBuffer = class FixedCircularBuffer { this.bottom = (this.bottom + 1) & kMask; return nextItem; } -}; +} module.exports = class FixedQueue { constructor() { diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index c93d89461ffa8a..05d82991552bad 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -4,6 +4,11 @@ // See https://github.com/libuv/libuv/pull/1501. const kIoMaxLength = 2 ** 31 - 1; +// Note: This is different from kReadFileBufferLength used for non-promisified +// fs.readFile. +const kReadFileMaxChunkSize = 2 ** 14; +const kWriteFileMaxChunkSize = 2 ** 14; + const { MathMax, MathMin, @@ -150,16 +155,12 @@ async function writeFileHandle(filehandle, data) { do { const { bytesWritten } = await write(filehandle, data, 0, - MathMin(16384, data.length)); + MathMin(kWriteFileMaxChunkSize, data.length)); remaining -= bytesWritten; data = data.slice(bytesWritten); } while (remaining > 0); } -// Note: This is different from kReadFileBufferLength used for non-promisified -// fs.readFile. -const kReadFileMaxChunkSize = 16384; - async function readFileHandle(filehandle, options) { const statFields = await binding.fstat(filehandle.fd, false, kUsePromises); @@ -188,11 +189,8 @@ async function readFileHandle(filehandle, options) { } while (!endOfFile); const result = Buffer.concat(chunks); - if (options.encoding) { - return result.toString(options.encoding); - } else { - return result; - } + + return options.encoding ? result.toString(options.encoding) : result; } // All of the functions are defined as async in order to ensure that errors diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 763a940f6e98a7..b91eaa006c44cf 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -539,13 +539,15 @@ function toUnixTimestamp(time, name = 'time') { const validateOffsetLengthRead = hideStackFrames( (offset, length, bufferLength) => { - if (offset < 0 || offset >= bufferLength) { - throw new ERR_OUT_OF_RANGE('offset', - `>= 0 && <= ${bufferLength}`, offset); + if (offset < 0) { + throw new ERR_OUT_OF_RANGE('offset', '>= 0', offset); } - if (length < 0 || offset + length > bufferLength) { + if (length < 0) { + throw new ERR_OUT_OF_RANGE('length', '>= 0', length); + } + if (offset + length > bufferLength) { throw new ERR_OUT_OF_RANGE('length', - `>= 0 && <= ${bufferLength - offset}`, length); + `<= ${bufferLength - offset}`, length); } } ); diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 204e84556b0b3b..e673be6c349673 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -1152,7 +1152,7 @@ class Http2Session extends EventEmitter { socket.disableRenegotiation(); const setupFn = setupHandle.bind(this, socket, type, options); - if (socket.connecting) { + if (socket.connecting || socket.secureConnecting) { const connectEvent = socket instanceof tls.TLSSocket ? 'secureConnect' : 'connect'; socket.once(connectEvent, () => { diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 9db2b1e6c1c317..f2715d07cb44fb 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -77,7 +77,6 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const manifest = getOptionValue('--experimental-policy') ? require('internal/process/policy').manifest : null; -const { compileFunction } = internalBinding('contextify'); // Whether any user-provided CJS modules had been loaded (executed). // Used for internal assertions. @@ -552,21 +551,22 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) { , 0, -1), mappingKey); } else if (ArrayIsArray(target)) { if (target.length === 0) - throw new ERR_INVALID_PACKAGE_TARGET(StringPrototypeSlice(baseUrl.pathname - , 0, -1), mappingKey, subpath, target); + throw new ERR_PACKAGE_PATH_NOT_EXPORTED( + StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath); + let lastException; for (const targetValue of target) { try { return resolveExportsTarget(baseUrl, targetValue, subpath, mappingKey); } catch (e) { + lastException = e; if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED' && e.code !== 'ERR_INVALID_PACKAGE_TARGET') throw e; } } // Throw last fallback error - resolveExportsTarget(baseUrl, target[target.length - 1], subpath, - mappingKey); - assert(false); + assert(lastException !== undefined); + throw lastException; } else if (typeof target === 'object' && target !== null) { const keys = ObjectKeys(target); if (keys.some(isArrayIndex)) { @@ -595,6 +595,9 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) { } throw new ERR_PACKAGE_PATH_NOT_EXPORTED( StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath); + } else if (target === null) { + throw new ERR_PACKAGE_PATH_NOT_EXPORTED( + StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey + subpath); } throw new ERR_INVALID_PACKAGE_TARGET( StringPrototypeSlice(baseUrl.pathname, 0, -1), mappingKey, subpath, target); @@ -821,13 +824,16 @@ function emitCircularRequireWarning(prop) { // warns when non-existend properties are accessed. const CircularRequirePrototypeWarningProxy = new Proxy({}, { get(target, prop) { - if (prop in target) return target[prop]; + // Allow __esModule access in any case because it is used in the output + // of transpiled code to determine whether something comes from an + // ES module, and is not used as a regular key of `module.exports`. + if (prop in target || prop === '__esModule') return target[prop]; emitCircularRequireWarning(prop); return undefined; }, getOwnPropertyDescriptor(target, prop) { - if (ObjectPrototypeHasOwnProperty(target, prop)) + if (ObjectPrototypeHasOwnProperty(target, prop) || prop === '__esModule') return ObjectGetOwnPropertyDescriptor(target, prop); emitCircularRequireWarning(prop); return undefined; @@ -1096,40 +1102,25 @@ function wrapSafe(filename, content, cjsModuleInstance) { }, }); } - let compiled; try { - compiled = compileFunction( - content, + return vm.compileFunction(content, [ + 'exports', + 'require', + 'module', + '__filename', + '__dirname', + ], { filename, - 0, - 0, - undefined, - false, - undefined, - [], - [ - 'exports', - 'require', - 'module', - '__filename', - '__dirname', - ] - ); + importModuleDynamically(specifier) { + const loader = asyncESM.ESMLoader; + return loader.import(specifier, normalizeReferrerURL(filename)); + }, + }); } catch (err) { if (process.mainModule === cjsModuleInstance) enrichCJSError(err); throw err; } - - const { callbackMap } = internalBinding('module_wrap'); - callbackMap.set(compiled.cacheKey, { - importModuleDynamically: async (specifier) => { - const loader = asyncESM.ESMLoader; - return loader.import(specifier, normalizeReferrerURL(filename)); - } - }); - - return compiled.function; } // Run the file contents in the correct scope or sandbox. Expose diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 04c6abe54269f6..5bb2f37e53eeb5 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -16,7 +16,7 @@ const { StringPrototypeStartsWith, StringPrototypeSubstr, } = primordials; - +const assert = require('internal/assert'); const internalFS = require('internal/fs/utils'); const { NativeModule } = require('internal/bootstrap/loaders'); const { @@ -345,7 +345,7 @@ function resolveExportsTarget( return finalizeResolution(resolved, base); } else if (ArrayIsArray(target)) { if (target.length === 0) - throwExportsInvalid(packageSubpath, target, packageJSONUrl, base); + throwExportsNotFound(packageSubpath, packageJSONUrl, base); let lastException; for (let i = 0; i < target.length; i++) { @@ -366,6 +366,7 @@ function resolveExportsTarget( return finalizeResolution(resolved, base); } + assert(lastException !== undefined); throw lastException; } else if (typeof target === 'object' && target !== null) { const keys = ObjectGetOwnPropertyNames(target); @@ -392,6 +393,8 @@ function resolveExportsTarget( } } throwExportsNotFound(packageSubpath, packageJSONUrl, base); + } else if (target === null) { + throwExportsNotFound(packageSubpath, packageJSONUrl, base); } throwExportsInvalid(packageSubpath, target, packageJSONUrl, base); } diff --git a/lib/internal/options.js b/lib/internal/options.js index e494787b96c088..03586f9dae6d76 100644 --- a/lib/internal/options.js +++ b/lib/internal/options.js @@ -3,6 +3,8 @@ const { getOptions } = internalBinding('options'); const { options, aliases } = getOptions(); +let warnOnAllowUnauthorized = true; + function getOptionValue(option) { const result = options.get(option); if (!result) { @@ -11,8 +13,23 @@ function getOptionValue(option) { return result.value; } +function getAllowUnauthorized() { + const allowUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0'; + + if (allowUnauthorized && warnOnAllowUnauthorized) { + warnOnAllowUnauthorized = false; + process.emitWarning( + 'Setting the NODE_TLS_REJECT_UNAUTHORIZED ' + + 'environment variable to \'0\' makes TLS connections ' + + 'and HTTPS requests insecure by disabling ' + + 'certificate verification.'); + } + return allowUnauthorized; +} + module.exports = { options, aliases, - getOptionValue + getOptionValue, + getAllowUnauthorized, }; diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 383bbd7e0fe79f..ebf4c932fa9c57 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -55,7 +55,7 @@ function writeToFile(message) { } function doEmitWarning(warning) { - return () => process.emit('warning', warning); + process.emit('warning', warning); } let traceWarningHelperShown = false; @@ -129,7 +129,7 @@ function emitWarning(warning, type, code, ctor) { if (process.throwDeprecation) throw warning; } - process.nextTick(doEmitWarning(warning)); + process.nextTick(doEmitWarning, warning); } function emitWarningSync(warning) { diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index 207074a0c2c134..f7f282ec5079f3 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -73,6 +73,10 @@ function emitCloseNT(self) { const r = self._readableState; const w = self._writableState; + if (r) { + r.closeEmitted = true; + } + if ((w && w.emitClose) || (r && r.emitClose)) { self.emit('close'); } @@ -102,12 +106,13 @@ function undestroy() { if (r) { r.closed = false; + r.closeEmitted = false; r.destroyed = false; r.errored = false; + r.errorEmitted = false; r.reading = false; r.ended = false; r.endEmitted = false; - r.errorEmitted = false; } if (w) { diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 4742391fd71a7a..7d5689ddadb7fc 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -72,17 +72,24 @@ function eos(stream, opts, callback) { // TODO (ronag): Improve soft detection to include core modules and // common ecosystem modules that do properly emit 'close' but fail // this generic check. - const willEmitClose = ( + let willEmitClose = ( state && state.autoDestroy && state.emitClose && - state.closed === false + state.closed === false && + isReadable(stream) === readable && + isWritable(stream) === writable ); let writableFinished = stream.writableFinished || (wState && wState.finished); const onfinish = () => { writableFinished = true; + // Stream should not be destroyed here. If it is that + // means that user space is doing something differently and + // we cannot trust willEmitClose. + if (stream.destroyed) willEmitClose = false; + if (willEmitClose && (!stream.readable || readable)) return; if (!readable || readableEnded) callback.call(stream); }; @@ -91,6 +98,11 @@ function eos(stream, opts, callback) { (rState && rState.endEmitted); const onend = () => { readableEnded = true; + // Stream should not be destroyed here. If it is that + // means that user space is doing something differently and + // we cannot trust willEmitClose. + if (stream.destroyed) willEmitClose = false; + if (willEmitClose && (!stream.writable || writable)) return; if (!writable || writableFinished) callback.call(stream); }; diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index ab6db00a125a0b..ca567914bbf0fe 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -34,21 +34,51 @@ function from(Readable, iterable, opts) { objectMode: true, ...opts }); + // Reading boolean to protect against _read // being called before last iteration completion. let reading = false; + + // needToClose boolean if iterator needs to be explicitly closed + let needToClose = false; + readable._read = function() { if (!reading) { reading = true; next(); } }; + + readable._destroy = function(error, cb) { + if (needToClose) { + needToClose = false; + close().then( + () => process.nextTick(cb, error), + (e) => process.nextTick(cb, error || e), + ); + } else { + cb(error); + } + }; + + async function close() { + if (typeof iterator.return === 'function') { + const { value } = await iterator.return(); + await value; + } + } + async function next() { try { + needToClose = false; const { value, done } = await iterator.next(); + needToClose = !done; + const resolved = await value; if (done) { readable.push(null); - } else if (readable.push(await value)) { + } else if (readable.destroyed) { + await close(); + } else if (readable.push(resolved)) { next(); } else { reading = false; diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index cdd5bcb791f451..cf9d7868916a9e 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -25,43 +25,18 @@ let EE; let PassThrough; let createReadableStreamAsyncIterator; -function isIncoming(stream) { - return ( - stream.socket && - typeof stream.complete === 'boolean' && - ArrayIsArray(stream.rawTrailers) && - ArrayIsArray(stream.rawHeaders) - ); -} - -function isOutgoing(stream) { - return ( - stream.socket && - typeof stream.setHeader === 'function' - ); -} - -function destroyer(stream, reading, writing, final, callback) { - const _destroy = once((err) => { - if (!err && (isIncoming(stream) || isOutgoing(stream))) { - // http/1 request objects have a coupling to their response and should - // not be prematurely destroyed. Assume they will handle their own - // lifecycle. - return callback(); - } +function destroyer(stream, reading, writing, callback) { + callback = once(callback); - if (!err && reading && !writing && stream.writable) { - return callback(); - } - - if (err || !final || !stream.readable) { - destroyImpl.destroyer(stream, err); - } - callback(err); + let finished = false; + stream.on('close', () => { + finished = true; }); if (eos === undefined) eos = require('internal/streams/end-of-stream'); eos(stream, { readable: reading, writable: writing }, (err) => { + finished = !err; + const rState = stream._readableState; if ( err && @@ -78,14 +53,19 @@ function destroyer(stream, reading, writing, final, callback) { // eos will only fail with premature close on the reading side for // duplex streams. stream - .once('end', _destroy) - .once('error', _destroy); + .once('end', callback) + .once('error', callback); } else { - _destroy(err); + callback(err); } }); - return (err) => _destroy(err || new ERR_STREAM_DESTROYED('pipe')); + return (err) => { + if (finished) return; + finished = true; + destroyImpl.destroyer(stream, err); + callback(err || new ERR_STREAM_DESTROYED('pipe')); + }; } function popCallback(streams) { @@ -204,7 +184,7 @@ function pipeline(...streams) { if (isStream(stream)) { finishCount++; - destroys.push(destroyer(stream, reading, writing, !reading, finish)); + destroys.push(destroyer(stream, reading, writing, finish)); } if (i === 0) { @@ -262,7 +242,7 @@ function pipeline(...streams) { ret = pt; finishCount++; - destroys.push(destroyer(ret, false, true, true, finish)); + destroys.push(destroyer(ret, false, true, finish)); } } else if (isStream(stream)) { if (isReadable(ret)) { diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index f59e7db3a9782c..7b1e7eca0e61af 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1922,6 +1922,13 @@ function formatWithOptionsInternal(inspectOptions, ...args) { return str; } +function prepareStringForGetStringWidth(str, removeControlChars) { + str = str.normalize('NFC'); + if (removeControlChars) + str = stripVTControlCharacters(str); + return str; +} + if (internalBinding('config').hasIntl) { const icu = internalBinding('icu'); // icu.getStringWidth(string, ambiguousAsFullWidth, expandEmojiSequence) @@ -1931,8 +1938,8 @@ if (internalBinding('config').hasIntl) { // the receiving end supports. getStringWidth = function getStringWidth(str, removeControlChars = true) { let width = 0; - if (removeControlChars) - str = stripVTControlCharacters(str); + + str = prepareStringForGetStringWidth(str, removeControlChars); for (let i = 0; i < str.length; i++) { // Try to avoid calling into C++ by first handling the ASCII portion of // the string. If it is fully ASCII, we skip the C++ part. @@ -1952,9 +1959,7 @@ if (internalBinding('config').hasIntl) { getStringWidth = function getStringWidth(str, removeControlChars = true) { let width = 0; - if (removeControlChars) - str = stripVTControlCharacters(str); - + str = prepareStringForGetStringWidth(str, removeControlChars); for (const char of str) { const code = char.codePointAt(0); if (isFullWidthCodePoint(code)) { diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js index 11a9b5eba6a343..efc92ca8c4aee4 100644 --- a/lib/perf_hooks.js +++ b/lib/perf_hooks.js @@ -407,8 +407,8 @@ class Performance { } clearMarks(name) { - name = name !== undefined ? `${name}` : name; if (name !== undefined) { + name = `${name}`; this[kIndex][kMarks].delete(name); _clearMark(name); } else { diff --git a/lib/vm.js b/lib/vm.js index c2d8908703b396..cffca355720dae 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -313,6 +313,7 @@ function compileFunction(code, params, options = {}) { produceCachedData = false, parsingContext = undefined, contextExtensions = [], + importModuleDynamically, } = options; validateString(filename, 'options.filename'); @@ -360,6 +361,22 @@ function compileFunction(code, params, options = {}) { result.function.cachedData = result.cachedData; } + if (importModuleDynamically !== undefined) { + if (typeof importModuleDynamically !== 'function') { + throw new ERR_INVALID_ARG_TYPE('options.importModuleDynamically', + 'function', + importModuleDynamically); + } + const { importModuleDynamicallyWrap } = + require('internal/vm/module'); + const { callbackMap } = internalBinding('module_wrap'); + const wrapped = importModuleDynamicallyWrap(importModuleDynamically); + const func = result.function; + callbackMap.set(result.cacheKey, { + importModuleDynamically: (s, _k) => wrapped(s, func), + }); + } + return result.function; } diff --git a/onboarding.md b/onboarding.md index 4f1346f2d06600..31b8353ef41ec5 100644 --- a/onboarding.md +++ b/onboarding.md @@ -165,7 +165,7 @@ onboarding session. * It is not automatically run. You need to start it manually. * Log in on CI is integrated with GitHub. Try to log in now! * You will be using `node-test-pull-request` most of the time. Go there now! - * Consider bookmarking it: https://ci.nodejs.org/job/node-test-pull-request/ + * Consider bookmarking it: * To get to the form to start a job, click on `Build with Parameters`. (If you don't see it, that probably means you are not logged in!) Click it now! * To start CI testing from this screen, you need to fill in two elements on @@ -200,7 +200,7 @@ needs to be pointed out separately during the onboarding. ## Exercise: Make a PR adding yourself to the README * Example: - https://github.com/nodejs/node/commit/ce986de829457c39257cd205067602e765768fb0 + * For raw commit message: `git log ce986de829457c39257cd205067602e765768fb0 -1` * Collaborators are in alphabetical order by GitHub username. diff --git a/src/api/environment.cc b/src/api/environment.cc index 0d845344d4050e..b9ca6ca7451926 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -23,7 +23,6 @@ using v8::HandleScope; using v8::Isolate; using v8::Local; using v8::MaybeLocal; -using v8::MicrotasksPolicy; using v8::Null; using v8::Object; using v8::ObjectTemplate; diff --git a/src/async_wrap.cc b/src/async_wrap.cc index b24c160156c280..42837e09818ec2 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -80,6 +80,20 @@ struct AsyncWrapObject : public AsyncWrap { inline AsyncWrapObject(Environment* env, Local object, ProviderType type) : AsyncWrap(env, object, type) {} + static Local GetConstructorTemplate(Environment* env) { + Local tmpl = env->async_wrap_object_ctor_template(); + if (tmpl.IsEmpty()) { + tmpl = env->NewFunctionTemplate(AsyncWrapObject::New); + tmpl->SetClassName( + FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap")); + tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env)); + tmpl->InstanceTemplate()->SetInternalFieldCount( + AsyncWrapObject::kInternalFieldCount); + env->set_async_wrap_object_ctor_template(tmpl); + } + return tmpl; + } + SET_NO_MEMORY_INFO() SET_MEMORY_INFO_NAME(AsyncWrapObject) SET_SELF_SIZE(AsyncWrapObject) @@ -559,21 +573,10 @@ void AsyncWrap::Initialize(Local target, env->set_async_hooks_promise_resolve_function(Local()); env->set_async_hooks_binding(target); - // TODO(addaleax): This block might better work as a - // AsyncWrapObject::Initialize() or AsyncWrapObject::GetConstructorTemplate() - // function. - { - auto class_name = FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"); - auto function_template = env->NewFunctionTemplate(AsyncWrapObject::New); - function_template->SetClassName(class_name); - function_template->Inherit(AsyncWrap::GetConstructorTemplate(env)); - auto instance_template = function_template->InstanceTemplate(); - instance_template->SetInternalFieldCount(AsyncWrap::kInternalFieldCount); - auto function = - function_template->GetFunction(env->context()).ToLocalChecked(); - target->Set(env->context(), class_name, function).Check(); - env->set_async_wrap_object_ctor_template(function_template); - } + target->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"), + AsyncWrapObject::GetConstructorTemplate(env) + ->GetFunction(env->context()).ToLocalChecked()).Check(); } diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index ff050cc2dc9502..8d1e3bc8794dfe 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -66,6 +66,7 @@ using v8::Int32; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; @@ -1929,7 +1930,7 @@ void CanonicalizeIP(const FunctionCallbackInfo& args) { const int af = (rc == 4 ? AF_INET : AF_INET6); CHECK_EQ(0, uv_inet_ntop(af, &result, canonical_ip, sizeof(canonical_ip))); Local val = String::NewFromUtf8(isolate, canonical_ip, - v8::NewStringType::kNormal).ToLocalChecked(); + NewStringType::kNormal).ToLocalChecked(); args.GetReturnValue().Set(val); } diff --git a/src/env-inl.h b/src/env-inl.h index 853c74f3e5b0f1..9ba5bebe00cb27 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -995,7 +995,10 @@ inline AllocatedBuffer::~AllocatedBuffer() { inline void AllocatedBuffer::clear() { uv_buf_t buf = release(); - env_->Free(buf.base, buf.len); + if (buf.base != nullptr) { + CHECK_NOT_NULL(env_); + env_->Free(buf.base, buf.len); + } } // It's a bit awkward to define this Buffer::New() overload here, but it diff --git a/src/env.cc b/src/env.cc index 444d9c0368ed78..f966bfba1ee7e6 100644 --- a/src/env.cc +++ b/src/env.cc @@ -174,10 +174,10 @@ void IsolateData::CreateProperties() { #define V(Provider) \ async_wrap_providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \ isolate_, \ - v8::String::NewFromOneByte( \ + String::NewFromOneByte( \ isolate_, \ reinterpret_cast(#Provider), \ - v8::NewStringType::kInternalized, \ + NewStringType::kInternalized, \ sizeof(#Provider) - 1).ToLocalChecked()); NODE_ASYNC_PROVIDER_TYPES(V) #undef V diff --git a/src/heap_utils.cc b/src/heap_utils.cc index c21ff8c80062a8..efdd68fde9d160 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -328,7 +328,7 @@ inline bool WriteSnapshot(Isolate* isolate, const char* filename) { } // namespace -void DeleteHeapSnapshot(const v8::HeapSnapshot* snapshot) { +void DeleteHeapSnapshot(const HeapSnapshot* snapshot) { const_cast(snapshot)->Delete(); } diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index cc4c3091757683..03cf2f6e5ca76b 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -209,6 +209,16 @@ void V8CoverageConnection::WriteProfile(Local message) { HandleScope handle_scope(isolate); Context::Scope context_scope(context); + // This is only set up during pre-execution (when the environment variables + // becomes available in the JS land). If it's empty, we don't have coverage + // directory path (which is resolved in JS land at the moment) either, so + // the best we could to is to just discard the profile and do nothing. + // This should only happen in half-baked Environments created using the + // embedder API. + if (env_->source_map_cache_getter().IsEmpty()) { + return; + } + // Get message.result from the response. Local result; if (!ParseProfile(env_, message, type()).ToLocal(&result)) { diff --git a/src/js_native_api_types.h b/src/js_native_api_types.h index 7a49fc9f719b30..c32c71c4d39334 100644 --- a/src/js_native_api_types.h +++ b/src/js_native_api_types.h @@ -82,11 +82,15 @@ typedef enum { napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, + napi_would_deadlock } napi_status; // Note: when adding a new enum value to `napi_status`, please also update -// `const int last_status` in `napi_get_last_error_info()' definition, -// in file js_native_api_v8.cc. Please also update the definition of -// `napi_status` in doc/api/n-api.md to reflect the newly added value(s). +// * `const int last_status` in the definition of `napi_get_last_error_info()' +// in file js_native_api_v8.cc. +// * `const char* error_messages[]` in file js_native_api_v8.cc with a brief +// message explaining the error. +// * the definition of `napi_status` in doc/api/n-api.md to reflect the newly +// added value(s). typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info); diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index 422eff6d7c5b68..4255c3e7ec3fff 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -392,10 +392,12 @@ class ArrayBufferReference final : public Reference { inline void Finalize(bool is_env_teardown) override { if (is_env_teardown) { v8::HandleScope handle_scope(_env->isolate); - v8::Local ab = Get(); - CHECK(!ab.IsEmpty()); - CHECK(ab->IsArrayBuffer()); - ab.As()->Detach(); + v8::Local obj = Get(); + CHECK(!obj.IsEmpty()); + CHECK(obj->IsArrayBuffer()); + v8::Local ab = obj.As(); + if (ab->IsDetachable()) + ab->Detach(); } Reference::Finalize(is_env_teardown); @@ -740,6 +742,7 @@ const char* error_messages[] = {nullptr, "A date was expected", "An arraybuffer was expected", "A detachable arraybuffer was expected", + "Main thread would deadlock", }; napi_status napi_get_last_error_info(napi_env env, @@ -751,7 +754,7 @@ napi_status napi_get_last_error_info(napi_env env, // message in the `napi_status` enum each time a new error message is added. // We don't have a napi_status_last as this would result in an ABI // change each time a message was added. - const int last_status = napi_detachable_arraybuffer_expected; + const int last_status = napi_would_deadlock; static_assert( NAPI_ARRAYSIZE(error_messages) == last_status + 1, diff --git a/src/node.h b/src/node.h index 16d30e89d2a8b7..7fbbdb7ea23601 100644 --- a/src/node.h +++ b/src/node.h @@ -227,15 +227,14 @@ NODE_EXTERN int Start(int argc, char* argv[]); // in the loop and / or actively executing JavaScript code). NODE_EXTERN int Stop(Environment* env); -// TODO(addaleax): Officially deprecate this and replace it with something -// better suited for a public embedder API. // It is recommended to use InitializeNodeWithArgs() instead as an embedder. // Init() calls InitializeNodeWithArgs() and exits the process with the exit // code returned from it. -NODE_EXTERN void Init(int* argc, - const char** argv, - int* exec_argc, - const char*** exec_argv); +NODE_DEPRECATED("Use InitializeNodeWithArgs() instead", + NODE_EXTERN void Init(int* argc, + const char** argv, + int* exec_argc, + const char*** exec_argv)); // Set up per-process state needed to run Node.js. This will consume arguments // from argv, fill exec_argv, and possibly add errors resulting from parsing // the arguments to `errors`. The return value is a suggested exit code for the @@ -428,12 +427,13 @@ struct InspectorParentHandle { // Returns nullptr when the Environment cannot be created e.g. there are // pending JavaScript exceptions. // It is recommended to use the second variant taking a flags argument. -NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data, - v8::Local context, - int argc, - const char* const* argv, - int exec_argc, - const char* const* exec_argv); +NODE_DEPRECATED("Use overload taking a flags argument", + NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data, + v8::Local context, + int argc, + const char* const* argv, + int exec_argc, + const char* const* exec_argv)); NODE_EXTERN Environment* CreateEnvironment( IsolateData* isolate_data, v8::Local context, @@ -463,8 +463,8 @@ struct StartExecutionCallbackInfo { using StartExecutionCallback = std::function(const StartExecutionCallbackInfo&)>; -// TODO(addaleax): Deprecate this in favour of the MaybeLocal<> overload. -NODE_EXTERN void LoadEnvironment(Environment* env); +NODE_DEPRECATED("Use variants returning MaybeLocal<> instead", + NODE_EXTERN void LoadEnvironment(Environment* env)); // The `InspectorParentHandle` arguments here are ignored and not used. // For passing `InspectorParentHandle`, use `CreateEnvironment()`. NODE_EXTERN v8::MaybeLocal LoadEnvironment( @@ -495,18 +495,18 @@ NODE_EXTERN Environment* GetCurrentEnvironment(v8::Local context); // This returns the MultiIsolatePlatform used in the main thread of Node.js. // If NODE_USE_V8_PLATFORM has not been defined when Node.js was built, // it returns nullptr. -// TODO(addaleax): Deprecate in favour of GetMultiIsolatePlatform(). -NODE_EXTERN MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform(); +NODE_DEPRECATED("Use GetMultiIsolatePlatform(env) instead", + NODE_EXTERN MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform()); // This returns the MultiIsolatePlatform used for an Environment or IsolateData // instance, if one exists. NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env); NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env); // Legacy variants of MultiIsolatePlatform::Create(). -// TODO(addaleax): Deprecate in favour of the v8::TracingController variant. -NODE_EXTERN MultiIsolatePlatform* CreatePlatform( - int thread_pool_size, - node::tracing::TracingController* tracing_controller); +NODE_DEPRECATED("Use variant taking a v8::TracingController* pointer instead", + NODE_EXTERN MultiIsolatePlatform* CreatePlatform( + int thread_pool_size, + node::tracing::TracingController* tracing_controller)); NODE_EXTERN MultiIsolatePlatform* CreatePlatform( int thread_pool_size, v8::TracingController* tracing_controller); diff --git a/src/node_api.cc b/src/node_api.cc index fad9cf72a972c2..cb8bd4b482365e 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -155,6 +155,29 @@ class ThreadSafeFunction : public node::AsyncResource { if (mode == napi_tsfn_nonblocking) { return napi_queue_full; } + + // Here we check if there is a Node.js event loop running on this thread. + // If there is, and our queue is full, we return `napi_would_deadlock`. We + // do this for two reasons: + // + // 1. If this is the thread on which our own event loop runs then we + // cannot wait here because that will prevent our event loop from + // running and emptying the very queue on which we are waiting. + // + // 2. If this is not the thread on which our own event loop runs then we + // still cannot wait here because that allows the following sequence of + // events: + // + // 1. JSThread1 calls JSThread2 and blocks while its queue is full and + // because JSThread2's queue is also full. + // + // 2. JSThread2 calls JSThread1 before it's had a chance to remove an + // item from its own queue and blocks because JSThread1's queue is + // also full. + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + if (isolate != nullptr && node::GetCurrentEventLoop(isolate) != nullptr) + return napi_would_deadlock; + cond->Wait(lock); } diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 77120d6af4a811..1ff60ad721753e 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -152,7 +152,8 @@ void CallbackInfo::CleanupHook(void* data) { HandleScope handle_scope(self->env_->isolate()); Local ab = self->persistent_.Get(self->env_->isolate()); CHECK(!ab.IsEmpty()); - ab->Detach(); + if (ab->IsDetachable()) + ab->Detach(); } self->WeakCallback(self->env_->isolate()); diff --git a/src/node_env_var.cc b/src/node_env_var.cc index 5f543a5e76a1f9..8eaf79538a26e7 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -121,7 +121,7 @@ void RealEnvStore::Set(Isolate* isolate, node::Utf8Value val(isolate, value); #ifdef _WIN32 - if (key[0] == L'=') return; + if (key.length() > 0 && key[0] == '=') return; #endif uv_os_setenv(*key, *val); DateTimeConfigurationChangeNotification(isolate, key); @@ -139,7 +139,7 @@ int32_t RealEnvStore::Query(const char* key) const { } #ifdef _WIN32 - if (key[0] == L'=') { + if (key[0] == '=') { return static_cast(v8::ReadOnly) | static_cast(v8::DontDelete) | static_cast(v8::DontEnum); @@ -227,7 +227,7 @@ void MapKVStore::Set(Isolate* isolate, Local key, Local value) { Mutex::ScopedLock lock(mutex_); Utf8Value key_str(isolate, key); Utf8Value value_str(isolate, value); - if (*key_str != nullptr && *value_str != nullptr) { + if (*key_str != nullptr && key_str.length() > 0 && *value_str != nullptr) { map_[std::string(*key_str, key_str.length())] = std::string(*value_str, value_str.length()); } diff --git a/src/node_http2.cc b/src/node_http2.cc index 7477bfbb6d8c10..189f1d50a29a0d 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -21,6 +21,7 @@ using v8::ArrayBuffer; using v8::ArrayBufferView; using v8::Boolean; using v8::Context; +using v8::EscapableHandleScope; using v8::Float64Array; using v8::Function; using v8::FunctionCallbackInfo; @@ -30,7 +31,6 @@ using v8::Integer; using v8::Isolate; using v8::Local; using v8::MaybeLocal; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::ObjectTemplate; @@ -48,15 +48,9 @@ namespace { const char zero_bytes_256[256] = {}; -inline Http2Stream* GetStream(Http2Session* session, - int32_t id, - nghttp2_data_source* source) { - Http2Stream* stream = static_cast(source->ptr); - if (stream == nullptr) - stream = session->FindStream(id); - CHECK_NOT_NULL(stream); - CHECK_EQ(id, stream->id()); - return stream; +bool HasHttp2Observer(Environment* env) { + AliasedUint32Array& observers = env->performance_state()->observers; + return observers[performance::NODE_PERFORMANCE_ENTRY_TYPE_HTTP2] != 0; } } // anonymous namespace @@ -75,36 +69,27 @@ const Http2Session::Callbacks Http2Session::callback_struct_saved[2] = { // For example: // // Http2Scope h2scope(session); -// nghttp2_submit_ping(**session, ... ); +// nghttp2_submit_ping(session->session(), ... ); // // When the Http2Scope passes out of scope and is deconstructed, it will // call Http2Session::MaybeScheduleWrite(). Http2Scope::Http2Scope(Http2Stream* stream) : Http2Scope(stream->session()) {} -Http2Scope::Http2Scope(Http2Session* session) { - if (session == nullptr) - return; +Http2Scope::Http2Scope(Http2Session* session) : session_(session) { + if (!session_) return; - if (session->flags_ & (SESSION_STATE_HAS_SCOPE | - SESSION_STATE_WRITE_SCHEDULED)) { - // There is another scope further below on the stack, or it is already - // known that a write is scheduled. In either case, there is nothing to do. + // If there is another scope further below on the stack, or + // a write is already scheduled, there's nothing to do. + if (session_->is_in_scope() || session_->is_write_scheduled()) { + session_.reset(); return; } - session->flags_ |= SESSION_STATE_HAS_SCOPE; - session_ = session; - - // Always keep the session object alive for at least as long as - // this scope is active. - session_handle_ = session->object(); - CHECK(!session_handle_.IsEmpty()); + session_->set_in_scope(); } Http2Scope::~Http2Scope() { - if (session_ == nullptr) - return; - - session_->flags_ &= ~SESSION_STATE_HAS_SCOPE; + if (!session_) return; + session_->set_in_scope(false); session_->MaybeScheduleWrite(); } @@ -112,7 +97,7 @@ Http2Scope::~Http2Scope() { // instances to configure an appropriate nghttp2_options struct. The class // uses a single TypedArray instance that is shared with the JavaScript side // to more efficiently pass values back and forth. -Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { +Http2Options::Http2Options(Http2State* http2_state, SessionType type) { nghttp2_option* option; CHECK_EQ(nghttp2_option_new(&option), 0); CHECK_NOT_NULL(option); @@ -171,10 +156,10 @@ Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { // this is set on a per-session basis, but eventually we may switch to // a per-stream setting, giving users greater control if (flags & (1 << IDX_OPTIONS_PADDING_STRATEGY)) { - padding_strategy_type strategy = - static_cast( + PaddingStrategy strategy = + static_cast( buffer.GetValue(IDX_OPTIONS_PADDING_STRATEGY)); - SetPaddingStrategy(strategy); + set_padding_strategy(strategy); } // The max header list pairs option controls the maximum number of @@ -182,7 +167,7 @@ Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { // if the remote peer sends more than this amount, the stream will be // automatically closed with an RST_STREAM. if (flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS)) - SetMaxHeaderPairs(buffer[IDX_OPTIONS_MAX_HEADER_LIST_PAIRS]); + set_max_header_pairs(buffer[IDX_OPTIONS_MAX_HEADER_LIST_PAIRS]); // The HTTP2 specification places no limits on the number of HTTP2 // PING frames that can be sent. In order to prevent PINGS from being @@ -190,7 +175,7 @@ Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { // on the number of unacknowledged PINGS that can be sent at any given // time. if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_PINGS)) - SetMaxOutstandingPings(buffer[IDX_OPTIONS_MAX_OUTSTANDING_PINGS]); + set_max_outstanding_pings(buffer[IDX_OPTIONS_MAX_OUTSTANDING_PINGS]); // The HTTP2 specification places no limits on the number of HTTP2 // SETTINGS frames that can be sent. In order to prevent PINGS from being @@ -198,7 +183,7 @@ Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { // on the number of unacknowledged SETTINGS that can be sent at any given // time. if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS)) - SetMaxOutstandingSettings(buffer[IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS]); + set_max_outstanding_settings(buffer[IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS]); // The HTTP2 specification places no limits on the amount of memory // that a session can consume. In order to prevent abuse, we place a @@ -209,131 +194,133 @@ Http2Options::Http2Options(Http2State* http2_state, nghttp2_session_type type) { // Important: The maxSessionMemory option in javascript is expressed in // terms of MB increments (i.e. the value 1 == 1 MB) if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY)) - SetMaxSessionMemory(buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1000000); + set_max_session_memory(buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1000000); } -void Http2Session::Http2Settings::Init(Http2State* http2_state) { +#define GRABSETTING(entries, count, name) \ + do { \ + if (flags & (1 << IDX_SETTINGS_ ## name)) { \ + uint32_t val = buffer[IDX_SETTINGS_ ## name]; \ + entries[count++] = \ + nghttp2_settings_entry {NGHTTP2_SETTINGS_ ## name, val}; \ + } } while (0) + +size_t Http2Settings::Init( + Http2State* http2_state, + nghttp2_settings_entry* entries) { AliasedUint32Array& buffer = http2_state->settings_buffer; uint32_t flags = buffer[IDX_SETTINGS_COUNT]; - size_t n = 0; - -#define GRABSETTING(N, trace) \ - if (flags & (1 << IDX_SETTINGS_##N)) { \ - uint32_t val = buffer[IDX_SETTINGS_##N]; \ - if (session_ != nullptr) \ - Debug(session_, "setting " trace ": %d\n", val); \ - entries_[n++] = \ - nghttp2_settings_entry {NGHTTP2_SETTINGS_##N, val}; \ - } + size_t count = 0; - GRABSETTING(HEADER_TABLE_SIZE, "header table size"); - GRABSETTING(MAX_CONCURRENT_STREAMS, "max concurrent streams"); - GRABSETTING(MAX_FRAME_SIZE, "max frame size"); - GRABSETTING(INITIAL_WINDOW_SIZE, "initial window size"); - GRABSETTING(MAX_HEADER_LIST_SIZE, "max header list size"); - GRABSETTING(ENABLE_PUSH, "enable push"); - GRABSETTING(ENABLE_CONNECT_PROTOCOL, "enable connect protocol"); - -#undef GRABSETTING +#define V(name) GRABSETTING(entries, count, name); + HTTP2_SETTINGS(V) +#undef V - count_ = n; + return count; } +#undef GRABSETTING // The Http2Settings class is used to configure a SETTINGS frame that is // to be sent to the connected peer. The settings are set using a TypedArray // that is shared with the JavaScript side. -Http2Session::Http2Settings::Http2Settings(Http2State* http2_state, - Http2Session* session, - Local obj, - uint64_t start_time) - : AsyncWrap(http2_state->env(), obj, PROVIDER_HTTP2SETTINGS), +Http2Settings::Http2Settings(Http2Session* session, + Local obj, + Local callback, + uint64_t start_time) + : AsyncWrap(session->env(), obj, PROVIDER_HTTP2SETTINGS), session_(session), startTime_(start_time) { - Init(http2_state); + callback_.Reset(env()->isolate(), callback); + count_ = Init(session->http2_state(), entries_); +} + +Local Http2Settings::callback() const { + return callback_.Get(env()->isolate()); +} + +void Http2Settings::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("callback", callback_); } // Generates a Buffer that contains the serialized payload of a SETTINGS // frame. This can be used, for instance, to create the Base64-encoded // content of an Http2-Settings header field. -Local Http2Session::Http2Settings::Pack() { - const size_t len = count_ * 6; - Local buf = Buffer::New(env(), len).ToLocalChecked(); +Local Http2Settings::Pack() { + return Pack(session_->env(), count_, entries_); +} + +Local Http2Settings::Pack(Http2State* state) { + nghttp2_settings_entry entries[IDX_SETTINGS_COUNT]; + size_t count = Init(state, entries); + return Pack(state->env(), count, entries); +} + +Local Http2Settings::Pack( + Environment* env, + size_t count, + const nghttp2_settings_entry* entries) { + EscapableHandleScope scope(env->isolate()); + const size_t size = count * 6; + AllocatedBuffer buffer = env->AllocateManaged(size); ssize_t ret = nghttp2_pack_settings_payload( - reinterpret_cast(Buffer::Data(buf)), len, - &entries_[0], count_); - if (ret >= 0) - return buf; - else - return Undefined(env()->isolate()); + reinterpret_cast(buffer.data()), + size, + entries, + count); + Local buf = Undefined(env->isolate()); + if (ret >= 0) buf = buffer.ToBuffer().ToLocalChecked(); + return scope.Escape(buf); } // Updates the shared TypedArray with the current remote or local settings for // the session. -void Http2Session::Http2Settings::Update(Http2Session* session, - get_setting fn) { +void Http2Settings::Update(Http2Session* session, get_setting fn) { AliasedUint32Array& buffer = session->http2_state()->settings_buffer; - buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] = - fn(**session, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE); - buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] = - fn(**session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); - buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] = - fn(**session, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE); - buffer[IDX_SETTINGS_MAX_FRAME_SIZE] = - fn(**session, NGHTTP2_SETTINGS_MAX_FRAME_SIZE); - buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] = - fn(**session, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE); - buffer[IDX_SETTINGS_ENABLE_PUSH] = - fn(**session, NGHTTP2_SETTINGS_ENABLE_PUSH); - buffer[IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL] = - fn(**session, NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL); + +#define V(name) \ + buffer[IDX_SETTINGS_ ## name] = \ + fn(session->session(), NGHTTP2_SETTINGS_ ## name); + HTTP2_SETTINGS(V) +#undef V } // Initializes the shared TypedArray with the default settings values. -void Http2Session::Http2Settings::RefreshDefaults(Http2State* http2_state) { +void Http2Settings::RefreshDefaults(Http2State* http2_state) { AliasedUint32Array& buffer = http2_state->settings_buffer; + uint32_t flags = 0; + +#define V(name) \ + do { \ + buffer[IDX_SETTINGS_ ## name] = DEFAULT_SETTINGS_ ## name; \ + flags |= 1 << IDX_SETTINGS_ ## name; \ + } while (0); + HTTP2_SETTINGS(V) +#undef V + + buffer[IDX_SETTINGS_COUNT] = flags; +} - buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] = - DEFAULT_SETTINGS_HEADER_TABLE_SIZE; - buffer[IDX_SETTINGS_ENABLE_PUSH] = - DEFAULT_SETTINGS_ENABLE_PUSH; - buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] = - DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS; - buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] = - DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE; - buffer[IDX_SETTINGS_MAX_FRAME_SIZE] = - DEFAULT_SETTINGS_MAX_FRAME_SIZE; - buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] = - DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE; - buffer[IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL] = - DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL; - buffer[IDX_SETTINGS_COUNT] = - (1 << IDX_SETTINGS_HEADER_TABLE_SIZE) | - (1 << IDX_SETTINGS_ENABLE_PUSH) | - (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS) | - (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE) | - (1 << IDX_SETTINGS_MAX_FRAME_SIZE) | - (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE) | - (1 << IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL); -} - - -void Http2Session::Http2Settings::Send() { - Http2Scope h2scope(session_); - CHECK_EQ(nghttp2_submit_settings(**session_, NGHTTP2_FLAG_NONE, - &entries_[0], count_), 0); -} - -void Http2Session::Http2Settings::Done(bool ack) { + +void Http2Settings::Send() { + Http2Scope h2scope(session_.get()); + CHECK_EQ(nghttp2_submit_settings( + session_->session(), + NGHTTP2_FLAG_NONE, + &entries_[0], + count_), 0); +} + +void Http2Settings::Done(bool ack) { uint64_t end = uv_hrtime(); double duration = (end - startTime_) / 1e6; Local argv[] = { - Boolean::New(env()->isolate(), ack), + ack ? v8::True(env()->isolate()) : v8::False(env()->isolate()), Number::New(env()->isolate(), duration) }; - MakeCallback(env()->ondone_string(), arraysize(argv), argv); + MakeCallback(callback(), arraysize(argv), argv); } // The Http2Priority class initializes an appropriate nghttp2_priority_spec @@ -364,34 +351,32 @@ const char* Http2Session::TypeName() const { } } -Origins::Origins(Isolate* isolate, - Local context, - Local origin_string, - size_t origin_count) : count_(origin_count) { +Origins::Origins( + Environment* env, + Local origin_string, + size_t origin_count) + : count_(origin_count) { int origin_string_len = origin_string->Length(); if (count_ == 0) { CHECK_EQ(origin_string_len, 0); return; } - // Allocate a single buffer with count_ nghttp2_nv structs, followed - // by the raw header data as passed from JS. This looks like: - // | possible padding | nghttp2_nv | nghttp2_nv | ... | header contents | - buf_.AllocateSufficientStorage((alignof(nghttp2_origin_entry) - 1) + - count_ * sizeof(nghttp2_origin_entry) + - origin_string_len); + buf_ = env->AllocateManaged((alignof(nghttp2_origin_entry) - 1) + + count_ * sizeof(nghttp2_origin_entry) + + origin_string_len); // Make sure the start address is aligned appropriately for an nghttp2_nv*. char* start = reinterpret_cast( - RoundUp(reinterpret_cast(*buf_), + RoundUp(reinterpret_cast(buf_.data()), alignof(nghttp2_origin_entry))); char* origin_contents = start + (count_ * sizeof(nghttp2_origin_entry)); nghttp2_origin_entry* const nva = reinterpret_cast(start); - CHECK_LE(origin_contents + origin_string_len, *buf_ + buf_.length()); + CHECK_LE(origin_contents + origin_string_len, buf_.data() + buf_.size()); CHECK_EQ(origin_string->WriteOneByte( - isolate, + env->isolate(), reinterpret_cast(origin_contents), 0, origin_string_len, @@ -469,7 +454,7 @@ void Http2Session::DecreaseAllocatedSize(size_t size) { Http2Session::Http2Session(Http2State* http2_state, Local wrap, - nghttp2_session_type type) + SessionType type) : AsyncWrap(http2_state->env(), wrap, AsyncWrap::PROVIDER_HTTP2SESSION), js_fields_(http2_state->env()->isolate()), session_type_(type), @@ -480,18 +465,18 @@ Http2Session::Http2Session(Http2State* http2_state, // Capture the configuration options for this session Http2Options opts(http2_state, type); - max_session_memory_ = opts.GetMaxSessionMemory(); + max_session_memory_ = opts.max_session_memory(); - uint32_t maxHeaderPairs = opts.GetMaxHeaderPairs(); + uint32_t maxHeaderPairs = opts.max_header_pairs(); max_header_pairs_ = type == NGHTTP2_SESSION_SERVER ? GetServerMaxHeaderPairs(maxHeaderPairs) : GetClientMaxHeaderPairs(maxHeaderPairs); - max_outstanding_pings_ = opts.GetMaxOutstandingPings(); - max_outstanding_settings_ = opts.GetMaxOutstandingSettings(); + max_outstanding_pings_ = opts.max_outstanding_pings(); + max_outstanding_settings_ = opts.max_outstanding_settings(); - padding_strategy_ = opts.GetPaddingStrategy(); + padding_strategy_ = opts.padding_strategy(); bool hasGetPaddingCallback = padding_strategy_ != PADDING_STRATEGY_NONE; @@ -525,7 +510,7 @@ Http2Session::Http2Session(Http2State* http2_state, } Http2Session::~Http2Session() { - CHECK_EQ(flags_ & SESSION_STATE_HAS_SCOPE, 0); + CHECK(!is_in_scope()); Debug(this, "freeing nghttp2 session"); // Explicitly reset session_ so the subsequent // current_nghttp2_memory_ check passes. @@ -533,16 +518,23 @@ Http2Session::~Http2Session() { CHECK_EQ(current_nghttp2_memory_, 0); } +void Http2Session::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("streams", streams_); + tracker->TrackField("outstanding_pings", outstanding_pings_); + tracker->TrackField("outstanding_settings", outstanding_settings_); + tracker->TrackField("outgoing_buffers", outgoing_buffers_); + tracker->TrackFieldWithSize("stream_buf", stream_buf_.len); + tracker->TrackFieldWithSize("outgoing_storage", outgoing_storage_.size()); + tracker->TrackFieldWithSize("pending_rst_streams", + pending_rst_streams_.size() * sizeof(int32_t)); + tracker->TrackFieldWithSize("nghttp2_memory", current_nghttp2_memory_); +} + std::string Http2Session::diagnostic_name() const { return std::string("Http2Session ") + TypeName() + " (" + std::to_string(static_cast(get_async_id())) + ")"; } -inline bool HasHttp2Observer(Environment* env) { - AliasedUint32Array& observers = env->performance_state()->observers; - return observers[performance::NODE_PERFORMANCE_ENTRY_TYPE_HTTP2] != 0; -} - void Http2Stream::EmitStatistics() { CHECK_NOT_NULL(session()); if (!HasHttp2Observer(env())) @@ -615,13 +607,13 @@ void Http2Session::EmitStatistics() { void Http2Session::Close(uint32_t code, bool socket_closed) { Debug(this, "closing session"); - if (flags_ & SESSION_STATE_CLOSING) + if (is_closing()) return; - flags_ |= SESSION_STATE_CLOSING; + set_closing(); // Stop reading on the i/o stream if (stream_ != nullptr) { - flags_ |= SESSION_STATE_READING_STOPPED; + set_reading_stopped(); stream_->ReadStop(); } @@ -637,10 +629,10 @@ void Http2Session::Close(uint32_t code, bool socket_closed) { stream_->RemoveStreamListener(this); } - flags_ |= SESSION_STATE_CLOSED; + set_destroyed(); // If we are writing we will get to make the callback in OnStreamAfterWrite. - if ((flags_ & SESSION_STATE_WRITE_IN_PROGRESS) == 0) { + if (!is_write_in_progress()) { Debug(this, "make done session callback"); HandleScope scope(env()->isolate()); MakeCallback(env()->ondone_string(), 0, nullptr); @@ -663,12 +655,12 @@ void Http2Session::Close(uint32_t code, bool socket_closed) { // Locates an existing known stream by ID. nghttp2 has a similar method // but this is faster and does not fail if the stream is not found. -inline Http2Stream* Http2Session::FindStream(int32_t id) { +BaseObjectPtr Http2Session::FindStream(int32_t id) { auto s = streams_.find(id); - return s != streams_.end() ? s->second : nullptr; + return s != streams_.end() ? s->second : BaseObjectPtr(); } -inline bool Http2Session::CanAddStream() { +bool Http2Session::CanAddStream() { uint32_t maxConcurrentStreams = nghttp2_session_get_local_settings( session_.get(), NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); @@ -677,12 +669,12 @@ inline bool Http2Session::CanAddStream() { // We can add a new stream so long as we are less than the current // maximum on concurrent streams and there's enough available memory return streams_.size() < maxSize && - IsAvailableSessionMemory(sizeof(Http2Stream)); + has_available_session_memory(sizeof(Http2Stream)); } -inline void Http2Session::AddStream(Http2Stream* stream) { +void Http2Session::AddStream(Http2Stream* stream) { CHECK_GE(++statistics_.stream_count, 0); - streams_[stream->id()] = stream; + streams_[stream->id()] = BaseObjectPtr(stream); size_t size = streams_.size(); if (size > statistics_.max_concurrent_streams) statistics_.max_concurrent_streams = size; @@ -690,11 +682,16 @@ inline void Http2Session::AddStream(Http2Stream* stream) { } -inline void Http2Session::RemoveStream(Http2Stream* stream) { - if (streams_.empty() || stream == nullptr) - return; // Nothing to remove, item was never added? - streams_.erase(stream->id()); - DecrementCurrentSessionMemory(sizeof(*stream)); +BaseObjectPtr Http2Session::RemoveStream(int32_t id) { + BaseObjectPtr stream; + if (streams_.empty()) + return stream; + stream = FindStream(id); + if (stream) { + streams_.erase(id); + DecrementCurrentSessionMemory(sizeof(*stream)); + } + return stream; } // Used as one of the Padding Strategy functions. Will attempt to ensure @@ -738,7 +735,7 @@ ssize_t Http2Session::ConsumeHTTP2Data() { Debug(this, "receiving %d bytes [wants data? %d]", read_len, nghttp2_session_want_read(session_.get())); - flags_ &= ~SESSION_STATE_NGHTTP2_RECV_PAUSED; + set_receive_paused(false); ssize_t ret = nghttp2_session_mem_recv(session_.get(), reinterpret_cast(stream_buf_.base) + @@ -746,8 +743,8 @@ ssize_t Http2Session::ConsumeHTTP2Data() { read_len); CHECK_NE(ret, NGHTTP2_ERR_NOMEM); - if (flags_ & SESSION_STATE_NGHTTP2_RECV_PAUSED) { - CHECK_NE(flags_ & SESSION_STATE_READING_STOPPED, 0); + if (is_receive_paused()) { + CHECK(is_reading_stopped()); CHECK_GT(ret, 0); CHECK_LE(static_cast(ret), read_len); @@ -770,14 +767,14 @@ ssize_t Http2Session::ConsumeHTTP2Data() { return ret; // Send any data that was queued up while processing the received data. - if (!IsDestroyed()) { + if (!is_destroyed()) { SendPendingData(); } return ret; } -inline int32_t GetFrameID(const nghttp2_frame* frame) { +int32_t GetFrameID(const nghttp2_frame* frame) { // If this is a push promise, we want to grab the id of the promised stream return (frame->hd.type == NGHTTP2_PUSH_PROMISE) ? frame->push_promise.promised_stream_id : @@ -796,10 +793,10 @@ int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle, int32_t id = GetFrameID(frame); Debug(session, "beginning headers for stream %d", id); - Http2Stream* stream = session->FindStream(id); + BaseObjectPtr stream = session->FindStream(id); // The common case is that we're creating a new stream. The less likely // case is that we're receiving a set of trailers - if (LIKELY(stream == nullptr)) { + if (LIKELY(!stream)) { if (UNLIKELY(!session->CanAddStream() || Http2Stream::New(session, id, frame->headers.cat) == nullptr)) { @@ -807,13 +804,16 @@ int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle, session->js_fields_->max_rejected_streams) return NGHTTP2_ERR_CALLBACK_FAILURE; // Too many concurrent streams being opened - nghttp2_submit_rst_stream(**session, NGHTTP2_FLAG_NONE, id, - NGHTTP2_ENHANCE_YOUR_CALM); + nghttp2_submit_rst_stream( + session->session(), + NGHTTP2_FLAG_NONE, + id, + NGHTTP2_ENHANCE_YOUR_CALM); return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } session->rejected_stream_count_ = 0; - } else if (!stream->IsDestroyed()) { + } else if (!stream->is_destroyed()) { stream->StartHeaders(frame->headers.cat); } return 0; @@ -830,15 +830,15 @@ int Http2Session::OnHeaderCallback(nghttp2_session* handle, void* user_data) { Http2Session* session = static_cast(user_data); int32_t id = GetFrameID(frame); - Http2Stream* stream = session->FindStream(id); + BaseObjectPtr stream = session->FindStream(id); // If stream is null at this point, either something odd has happened // or the stream was closed locally while header processing was occurring. // either way, do not proceed and close the stream. - if (UNLIKELY(stream == nullptr)) + if (UNLIKELY(!stream)) return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; // If the stream has already been destroyed, ignore. - if (!stream->IsDestroyed() && !stream->AddHeader(name, value, flags)) { + if (!stream->is_destroyed() && !stream->AddHeader(name, value, flags)) { // This will only happen if the connected peer sends us more // than the allowed number of header items at any given time stream->SubmitRstStream(NGHTTP2_ENHANCE_YOUR_CALM); @@ -976,10 +976,10 @@ int Http2Session::OnStreamClose(nghttp2_session* handle, Local context = env->context(); Context::Scope context_scope(context); Debug(session, "stream %d closed with code: %d", id, code); - Http2Stream* stream = session->FindStream(id); + BaseObjectPtr stream = session->FindStream(id); // Intentionally ignore the callback if the stream does not exist or has // already been destroyed - if (stream == nullptr || stream->IsDestroyed()) + if (!stream || stream->is_destroyed()) return 0; stream->Close(code); @@ -1037,9 +1037,10 @@ int Http2Session::OnDataChunkReceived(nghttp2_session* handle, // so that it can send a WINDOW_UPDATE frame. This is a critical part of // the flow control process in http2 CHECK_EQ(nghttp2_session_consume_connection(handle, len), 0); - Http2Stream* stream = session->FindStream(id); + BaseObjectPtr stream = session->FindStream(id); + // If the stream has been destroyed, ignore this chunk - if (stream->IsDestroyed()) + if (!stream || stream->is_destroyed()) return 0; stream->statistics_.received_bytes += len; @@ -1071,7 +1072,7 @@ int Http2Session::OnDataChunkReceived(nghttp2_session* handle, // If the stream owner (e.g. the JS Http2Stream) wants more data, just // tell nghttp2 that all data has been consumed. Otherwise, defer until // more data is being requested. - if (stream->IsReading()) + if (stream->is_reading()) nghttp2_session_consume_stream(handle, id, avail); else stream->inbound_consumed_data_while_paused_ += avail; @@ -1085,9 +1086,9 @@ int Http2Session::OnDataChunkReceived(nghttp2_session* handle, // If we are currently waiting for a write operation to finish, we should // tell nghttp2 that we want to wait before we process more input data. - if (session->flags_ & SESSION_STATE_WRITE_IN_PROGRESS) { - CHECK_NE(session->flags_ & SESSION_STATE_READING_STOPPED, 0); - session->flags_ |= SESSION_STATE_NGHTTP2_RECV_PAUSED; + if (session->is_write_in_progress()) { + CHECK(session->is_reading_stopped()); + session->set_receive_paused(); return NGHTTP2_ERR_PAUSE; } @@ -1194,10 +1195,10 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) { int32_t id = GetFrameID(frame); Debug(this, "handle headers frame for stream %d", id); - Http2Stream* stream = FindStream(id); + BaseObjectPtr stream = FindStream(id); // If the stream has already been destroyed, ignore. - if (stream->IsDestroyed()) + if (!stream || stream->is_destroyed()) return; // The headers are stored as a vector of Http2Header instances. @@ -1263,9 +1264,11 @@ void Http2Session::HandlePriorityFrame(const nghttp2_frame* frame) { int Http2Session::HandleDataFrame(const nghttp2_frame* frame) { int32_t id = GetFrameID(frame); Debug(this, "handling data frame for stream %d", id); - Http2Stream* stream = FindStream(id); + BaseObjectPtr stream = FindStream(id); - if (!stream->IsDestroyed() && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + if (stream && + !stream->is_destroyed() && + frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { stream->EmitRead(UV_EOF); } else if (frame->hd.length == 0) { return 1; // Consider 0-length frame without END_STREAM an error. @@ -1292,6 +1295,9 @@ void Http2Session::HandleGoawayFrame(const nghttp2_frame* frame) { size_t length = goaway_frame.opaque_data_len; if (length > 0) { + // If the copy fails for any reason here, we just ignore it. + // The additional goaway data is completely optional and we + // shouldn't fail if we're not able to process it. argv[2] = Buffer::Copy(isolate, reinterpret_cast(goaway_frame.opaque_data), length).ToLocalChecked(); @@ -1317,14 +1323,8 @@ void Http2Session::HandleAltSvcFrame(const nghttp2_frame* frame) { Local argv[3] = { Integer::New(isolate, id), - String::NewFromOneByte(isolate, - altsvc->origin, - NewStringType::kNormal, - altsvc->origin_len).ToLocalChecked(), - String::NewFromOneByte(isolate, - altsvc->field_value, - NewStringType::kNormal, - altsvc->field_value_len).ToLocalChecked(), + OneByteString(isolate, altsvc->origin, altsvc->origin_len), + OneByteString(isolate, altsvc->field_value, altsvc->field_value_len) }; MakeCallback(env()->http2session_on_altsvc_function(), @@ -1347,10 +1347,7 @@ void Http2Session::HandleOriginFrame(const nghttp2_frame* frame) { for (size_t i = 0; i < nov; ++i) { const nghttp2_origin_entry& entry = origin->ov[i]; - origin_v[i] = - String::NewFromOneByte( - isolate, entry.origin, NewStringType::kNormal, entry.origin_len) - .ToLocalChecked(); + origin_v[i] = OneByteString(isolate, entry.origin, entry.origin_len); } Local holder = Array::New(isolate, origin_v.data(), origin_v.size()); MakeCallback(env()->http2session_on_origin_function(), 1, &holder); @@ -1384,9 +1381,10 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { if (!(js_fields_->bitfield & (1 << kSessionHasPingListeners))) return; // Notify the session that a ping occurred - arg = Buffer::Copy(env(), - reinterpret_cast(frame->ping.opaque_data), - 8).ToLocalChecked(); + arg = Buffer::Copy( + env(), + reinterpret_cast(frame->ping.opaque_data), + 8).ToLocalChecked(); MakeCallback(env()->http2session_on_ping_function(), 1, &arg); } @@ -1430,20 +1428,20 @@ void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) { void Http2Session::OnStreamAfterWrite(WriteWrap* w, int status) { Debug(this, "write finished with status %d", status); - CHECK_NE(flags_ & SESSION_STATE_WRITE_IN_PROGRESS, 0); - flags_ &= ~SESSION_STATE_WRITE_IN_PROGRESS; + CHECK(is_write_in_progress()); + set_write_in_progress(false); // Inform all pending writes about their completion. ClearOutgoing(status); - if ((flags_ & SESSION_STATE_READING_STOPPED) && - !(flags_ & SESSION_STATE_WRITE_IN_PROGRESS) && + if (is_reading_stopped() && + !is_write_in_progress() && nghttp2_session_want_read(session_.get())) { - flags_ &= ~SESSION_STATE_READING_STOPPED; + set_reading_stopped(false); stream_->ReadStart(); } - if ((flags_ & SESSION_STATE_CLOSED) != 0) { + if (is_destroyed()) { HandleScope scope(env()->isolate()); MakeCallback(env()->ondone_string(), 0, nullptr); return; @@ -1454,7 +1452,7 @@ void Http2Session::OnStreamAfterWrite(WriteWrap* w, int status) { ConsumeHTTP2Data(); } - if (!(flags_ & SESSION_STATE_WRITE_SCHEDULED)) { + if (!is_write_scheduled()) { // Schedule a new write if nghttp2 wants to send data. MaybeScheduleWrite(); } @@ -1465,17 +1463,17 @@ void Http2Session::OnStreamAfterWrite(WriteWrap* w, int status) { // on the next iteration of the Node.js event loop (using the SetImmediate // queue), but only if a write has not already been scheduled. void Http2Session::MaybeScheduleWrite() { - CHECK_EQ(flags_ & SESSION_STATE_WRITE_SCHEDULED, 0); + CHECK(!is_write_scheduled()); if (UNLIKELY(!session_)) return; if (nghttp2_session_want_write(session_.get())) { HandleScope handle_scope(env()->isolate()); Debug(this, "scheduling write"); - flags_ |= SESSION_STATE_WRITE_SCHEDULED; + set_write_scheduled(); BaseObjectPtr strong_ref{this}; env()->SetImmediate([this, strong_ref](Environment* env) { - if (!session_ || !(flags_ & SESSION_STATE_WRITE_SCHEDULED)) { + if (!session_ || !is_write_scheduled()) { // This can happen e.g. when a stream was reset before this turn // of the event loop, in which case SendPendingData() is called early, // or the session was destroyed in the meantime. @@ -1492,11 +1490,11 @@ void Http2Session::MaybeScheduleWrite() { } void Http2Session::MaybeStopReading() { - if (flags_ & SESSION_STATE_READING_STOPPED) return; + if (is_reading_stopped()) return; int want_read = nghttp2_session_want_read(session_.get()); Debug(this, "wants read? %d", want_read); - if (want_read == 0 || (flags_ & SESSION_STATE_WRITE_IN_PROGRESS)) { - flags_ |= SESSION_STATE_READING_STOPPED; + if (want_read == 0 || is_write_in_progress()) { + set_reading_stopped(); stream_->ReadStop(); } } @@ -1504,9 +1502,9 @@ void Http2Session::MaybeStopReading() { // Unset the sending state, finish up all current writes, and reset // storage for data and metadata that was associated with these writes. void Http2Session::ClearOutgoing(int status) { - CHECK_NE(flags_ & SESSION_STATE_SENDING, 0); + CHECK(is_sending()); - flags_ &= ~SESSION_STATE_SENDING; + set_sending(false); if (outgoing_buffers_.size() > 0) { outgoing_storage_.clear(); @@ -1534,8 +1532,8 @@ void Http2Session::ClearOutgoing(int status) { SendPendingData(); for (int32_t stream_id : current_pending_rst_streams) { - Http2Stream* stream = FindStream(stream_id); - if (LIKELY(stream != nullptr)) + BaseObjectPtr stream = FindStream(stream_id); + if (LIKELY(stream)) stream->FlushRstStream(); } } @@ -1573,15 +1571,15 @@ uint8_t Http2Session::SendPendingData() { // Do not attempt to send data on the socket if the destroying flag has // been set. That means everything is shutting down and the socket // will not be usable. - if (IsDestroyed()) + if (is_destroyed()) return 0; - flags_ &= ~SESSION_STATE_WRITE_SCHEDULED; + set_write_scheduled(false); // SendPendingData should not be called recursively. - if (flags_ & SESSION_STATE_SENDING) + if (is_sending()) return 1; // This is cleared by ClearOutgoing(). - flags_ |= SESSION_STATE_SENDING; + set_sending(); ssize_t src_length; const uint8_t* src; @@ -1635,11 +1633,11 @@ uint8_t Http2Session::SendPendingData() { chunks_sent_since_last_write_++; - CHECK_EQ(flags_ & SESSION_STATE_WRITE_IN_PROGRESS, 0); - flags_ |= SESSION_STATE_WRITE_IN_PROGRESS; + CHECK(!is_write_in_progress()); + set_write_in_progress(); StreamWriteResult res = underlying_stream()->Write(*bufs, count); if (!res.async) { - flags_ &= ~SESSION_STATE_WRITE_IN_PROGRESS; + set_write_in_progress(false); ClearOutgoing(res.err); } @@ -1661,7 +1659,8 @@ int Http2Session::OnSendData( nghttp2_data_source* source, void* user_data) { Http2Session* session = static_cast(user_data); - Http2Stream* stream = GetStream(session, frame->hd.stream_id, source); + BaseObjectPtr stream = session->FindStream(frame->hd.stream_id); + if (!stream) return 0; // Send the frame header + a byte that indicates padding length. session->CopyDataIntoOutgoing(framehd, 9); @@ -1707,7 +1706,7 @@ int Http2Session::OnSendData( // Creates a new Http2Stream and submits a new http2 request. Http2Stream* Http2Session::SubmitRequest( - nghttp2_priority_spec* prispec, + const Http2Priority& priority, const Http2Headers& headers, int32_t* ret, int options) { @@ -1717,7 +1716,7 @@ Http2Stream* Http2Session::SubmitRequest( Http2Stream::Provider::Stream prov(options); *ret = nghttp2_submit_request( session_.get(), - prispec, + &priority, headers.data(), headers.length(), *prov, @@ -1768,6 +1767,9 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf_) { // The data in stream_buf_ is already accounted for, add nread received // bytes to session memory but remove the already processed // stream_buf_offset_ bytes. + // TODO(@jasnell): There are some cases where nread is < stream_buf_offset_ + // here but things still work. Those need to be investigated. + // CHECK_GE(nread, stream_buf_offset_); IncrementCurrentSessionMemory(nread - stream_buf_offset_); buf = std::move(new_buf); @@ -1846,7 +1848,7 @@ Http2Stream::Http2Stream(Http2Session* session, statistics_.start_time = uv_hrtime(); // Limit the number of header pairs - max_header_pairs_ = session->GetMaxHeaderPairs(); + max_header_pairs_ = session->max_header_pairs(); if (max_header_pairs_ == 0) { max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS; } @@ -1861,7 +1863,7 @@ Http2Stream::Http2Stream(Http2Session* session, MAX_MAX_HEADER_LIST_SIZE); if (options & STREAM_OPTION_GET_TRAILERS) - flags_ |= NGHTTP2_STREAM_FLAG_TRAILERS; + set_has_trailers(); PushStreamListener(&stream_listener_); @@ -1871,11 +1873,12 @@ Http2Stream::Http2Stream(Http2Session* session, } Http2Stream::~Http2Stream() { - if (!session_) - return; Debug(this, "tearing down stream"); - session_->DecrementCurrentSessionMemory(current_headers_length_); - session_->RemoveStream(this); +} + +void Http2Stream::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("current_headers", current_headers_); + tracker->TrackField("queue", queue_); } std::string Http2Stream::diagnostic_name() const { @@ -1887,7 +1890,7 @@ std::string Http2Stream::diagnostic_name() const { // Notify the Http2Stream that a new block of HEADERS is being processed. void Http2Stream::StartHeaders(nghttp2_headers_category category) { Debug(this, "starting headers, category: %d", category); - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); session_->DecrementCurrentSessionMemory(current_headers_length_); current_headers_length_ = 0; current_headers_.clear(); @@ -1895,13 +1898,15 @@ void Http2Stream::StartHeaders(nghttp2_headers_category category) { } -nghttp2_stream* Http2Stream::operator*() { - return nghttp2_session_find_stream(**session_, id_); +nghttp2_stream* Http2Stream::operator*() const { return stream(); } + +nghttp2_stream* Http2Stream::stream() const { + return nghttp2_session_find_stream(session_->session(), id_); } void Http2Stream::Close(int32_t code) { - CHECK(!this->IsDestroyed()); - flags_ |= NGHTTP2_STREAM_FLAG_CLOSED; + CHECK(!this->is_destroyed()); + set_closed(); code_ = code; Debug(this, "closed with code %d", code); } @@ -1913,14 +1918,15 @@ ShutdownWrap* Http2Stream::CreateShutdownWrap(v8::Local object) { } int Http2Stream::DoShutdown(ShutdownWrap* req_wrap) { - if (IsDestroyed()) + if (is_destroyed()) return UV_EPIPE; { Http2Scope h2scope(this); - flags_ |= NGHTTP2_STREAM_FLAG_SHUT; - CHECK_NE(nghttp2_session_resume_data(**session_, id_), - NGHTTP2_ERR_NOMEM); + set_not_writable(); + CHECK_NE(nghttp2_session_resume_data( + session_->session(), id_), + NGHTTP2_ERR_NOMEM); Debug(this, "writable side shutdown"); } return 1; @@ -1931,36 +1937,40 @@ int Http2Stream::DoShutdown(ShutdownWrap* req_wrap) { // using the SetImmediate queue. void Http2Stream::Destroy() { // Do nothing if this stream instance is already destroyed - if (IsDestroyed()) + if (is_destroyed()) return; - if (session_->HasPendingRstStream(id_)) + if (session_->has_pending_rststream(id_)) FlushRstStream(); - flags_ |= NGHTTP2_STREAM_FLAG_DESTROYED; + set_destroyed(); Debug(this, "destroying stream"); // Wait until the start of the next loop to delete because there // may still be some pending operations queued for this stream. - BaseObjectPtr strong_ref{this}; - env()->SetImmediate([this, strong_ref](Environment* env) { - // Free any remaining outgoing data chunks here. This should be done - // here because it's possible for destroy to have been called while - // we still have queued outbound writes. - while (!queue_.empty()) { - NgHttp2StreamWrite& head = queue_.front(); - if (head.req_wrap != nullptr) - head.req_wrap->Done(UV_ECANCELED); - queue_.pop(); - } + BaseObjectPtr strong_ref = session_->RemoveStream(id_); + if (strong_ref) { + env()->SetImmediate([this, strong_ref = std::move(strong_ref)]( + Environment* env) { + // Free any remaining outgoing data chunks here. This should be done + // here because it's possible for destroy to have been called while + // we still have queued outbound writes. + while (!queue_.empty()) { + NgHttp2StreamWrite& head = queue_.front(); + if (head.req_wrap != nullptr) + head.req_wrap->Done(UV_ECANCELED); + queue_.pop(); + } - // We can destroy the stream now if there are no writes for it - // already on the socket. Otherwise, we'll wait for the garbage collector - // to take care of cleaning up. - if (session() == nullptr || !session()->HasWritesOnSocketForStream(this)) { - // Delete once strong_ref goes out of scope. - Detach(); - } - }); + // We can destroy the stream now if there are no writes for it + // already on the socket. Otherwise, we'll wait for the garbage collector + // to take care of cleaning up. + if (session() == nullptr || + !session()->HasWritesOnSocketForStream(this)) { + // Delete once strong_ref goes out of scope. + Detach(); + } + }); + } statistics_.end_time = uv_hrtime(); session_->statistics_.stream_average_duration = @@ -1973,18 +1983,18 @@ void Http2Stream::Destroy() { // Initiates a response on the Http2Stream using data provided via the // StreamBase Streams API. int Http2Stream::SubmitResponse(const Http2Headers& headers, int options) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Http2Scope h2scope(this); Debug(this, "submitting response"); if (options & STREAM_OPTION_GET_TRAILERS) - flags_ |= NGHTTP2_STREAM_FLAG_TRAILERS; + set_has_trailers(); - if (!IsWritable()) + if (!is_writable()) options |= STREAM_OPTION_EMPTY_PAYLOAD; Http2Stream::Provider::Stream prov(this, options); int ret = nghttp2_submit_response( - **session_, + session_->session(), id_, headers.data(), headers.length(), @@ -1996,11 +2006,11 @@ int Http2Stream::SubmitResponse(const Http2Headers& headers, int options) { // Submit informational headers for a stream. int Http2Stream::SubmitInfo(const Http2Headers& headers) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Http2Scope h2scope(this); Debug(this, "sending %d informational headers", headers.length()); int ret = nghttp2_submit_headers( - **session_, + session_->session(), NGHTTP2_FLAG_NONE, id_, nullptr, @@ -2013,18 +2023,18 @@ int Http2Stream::SubmitInfo(const Http2Headers& headers) { void Http2Stream::OnTrailers() { Debug(this, "let javascript know we are ready for trailers"); - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Isolate* isolate = env()->isolate(); HandleScope scope(isolate); Local context = env()->context(); Context::Scope context_scope(context); - flags_ &= ~NGHTTP2_STREAM_FLAG_TRAILERS; + set_has_trailers(false); MakeCallback(env()->http2session_on_stream_trailers_function(), 0, nullptr); } // Submit informational headers for a stream. int Http2Stream::SubmitTrailers(const Http2Headers& headers) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Http2Scope h2scope(this); Debug(this, "sending %d trailers", headers.length()); int ret; @@ -2033,10 +2043,14 @@ int Http2Stream::SubmitTrailers(const Http2Headers& headers) { // to indicate that the stream is ready to be closed. if (headers.length() == 0) { Http2Stream::Provider::Stream prov(this, 0); - ret = nghttp2_submit_data(**session_, NGHTTP2_FLAG_END_STREAM, id_, *prov); + ret = nghttp2_submit_data( + session_->session(), + NGHTTP2_FLAG_END_STREAM, + id_, + *prov); } else { ret = nghttp2_submit_trailer( - **session_, + session_->session(), id_, headers.data(), headers.length()); @@ -2046,17 +2060,20 @@ int Http2Stream::SubmitTrailers(const Http2Headers& headers) { } // Submit a PRIORITY frame to the connected peer. -int Http2Stream::SubmitPriority(nghttp2_priority_spec* prispec, +int Http2Stream::SubmitPriority(const Http2Priority& priority, bool silent) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Http2Scope h2scope(this); Debug(this, "sending priority spec"); int ret = silent ? - nghttp2_session_change_stream_priority(**session_, - id_, prispec) : - nghttp2_submit_priority(**session_, - NGHTTP2_FLAG_NONE, - id_, prispec); + nghttp2_session_change_stream_priority( + session_->session(), + id_, + &priority) : + nghttp2_submit_priority( + session_->session(), + NGHTTP2_FLAG_NONE, + id_, &priority); CHECK_NE(ret, NGHTTP2_ERR_NOMEM); return ret; } @@ -2064,7 +2081,7 @@ int Http2Stream::SubmitPriority(nghttp2_priority_spec* prispec, // Closes the Http2Stream by submitting an RST_STREAM frame to the connected // peer. void Http2Stream::SubmitRstStream(const uint32_t code) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); code_ = code; // If possible, force a purge of any currently pending data here to make sure // it is sent before closing the stream. If it returns non-zero then we need @@ -2079,11 +2096,14 @@ void Http2Stream::SubmitRstStream(const uint32_t code) { } void Http2Stream::FlushRstStream() { - if (IsDestroyed()) + if (is_destroyed()) return; Http2Scope h2scope(this); - CHECK_EQ(nghttp2_submit_rst_stream(**session_, NGHTTP2_FLAG_NONE, - id_, code_), 0); + CHECK_EQ(nghttp2_submit_rst_stream( + session_->session(), + NGHTTP2_FLAG_NONE, + id_, + code_), 0); } @@ -2091,11 +2111,11 @@ void Http2Stream::FlushRstStream() { Http2Stream* Http2Stream::SubmitPushPromise(const Http2Headers& headers, int32_t* ret, int options) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); Http2Scope h2scope(this); Debug(this, "sending push promise"); *ret = nghttp2_submit_push_promise( - **session_, + session_->session(), NGHTTP2_FLAG_NONE, id_, headers.data(), @@ -2115,17 +2135,17 @@ Http2Stream* Http2Stream::SubmitPushPromise(const Http2Headers& headers, // out to JS land. int Http2Stream::ReadStart() { Http2Scope h2scope(this); - CHECK(!this->IsDestroyed()); - flags_ |= NGHTTP2_STREAM_FLAG_READ_START; - flags_ &= ~NGHTTP2_STREAM_FLAG_READ_PAUSED; + CHECK(!this->is_destroyed()); + set_reading(); Debug(this, "reading starting"); // Tell nghttp2 about our consumption of the data that was handed // off to JS land. - nghttp2_session_consume_stream(**session_, - id_, - inbound_consumed_data_while_paused_); + nghttp2_session_consume_stream( + session_->session(), + id_, + inbound_consumed_data_while_paused_); inbound_consumed_data_while_paused_ = 0; return 0; @@ -2133,10 +2153,10 @@ int Http2Stream::ReadStart() { // Switch the StreamBase into paused mode. int Http2Stream::ReadStop() { - CHECK(!this->IsDestroyed()); - if (!IsReading()) + CHECK(!this->is_destroyed()); + if (!is_reading()) return 0; - flags_ |= NGHTTP2_STREAM_FLAG_READ_PAUSED; + set_paused(); Debug(this, "reading stopped"); return 0; } @@ -2157,7 +2177,7 @@ int Http2Stream::DoWrite(WriteWrap* req_wrap, uv_stream_t* send_handle) { CHECK_NULL(send_handle); Http2Scope h2scope(this); - if (!IsWritable() || IsDestroyed()) { + if (!is_writable() || is_destroyed()) { req_wrap->Done(UV_EOF); return 0; } @@ -2171,7 +2191,9 @@ int Http2Stream::DoWrite(WriteWrap* req_wrap, }); IncrementAvailableOutboundLength(bufs[i].len); } - CHECK_NE(nghttp2_session_resume_data(**session_, id_), NGHTTP2_ERR_NOMEM); + CHECK_NE(nghttp2_session_resume_data( + session_->session(), + id_), NGHTTP2_ERR_NOMEM); return 0; } @@ -2183,7 +2205,7 @@ int Http2Stream::DoWrite(WriteWrap* req_wrap, bool Http2Stream::AddHeader(nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags) { - CHECK(!this->IsDestroyed()); + CHECK(!this->is_destroyed()); if (Http2RcBufferPointer::IsZeroLength(name)) return true; // Ignore empty headers. @@ -2192,7 +2214,7 @@ bool Http2Stream::AddHeader(nghttp2_rcbuf* name, size_t length = header.length() + 32; // A header can only be added if we have not exceeded the maximum number // of headers and the session has memory available for it. - if (!session_->IsAvailableSessionMemory(length) || + if (!session_->has_available_session_memory(length) || current_headers_.size() == max_header_pairs_ || current_headers_length_ + length > max_header_length_) { return false; @@ -2210,7 +2232,7 @@ bool Http2Stream::AddHeader(nghttp2_rcbuf* name, // A Provider is the thing that provides outbound DATA frame data. Http2Stream::Provider::Provider(Http2Stream* stream, int options) { - CHECK(!stream->IsDestroyed()); + CHECK(!stream->is_destroyed()); provider_.source.ptr = stream; empty_ = options & STREAM_OPTION_EMPTY_PAYLOAD; } @@ -2245,7 +2267,8 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, void* user_data) { Http2Session* session = static_cast(user_data); Debug(session, "reading outbound data for stream %d", id); - Http2Stream* stream = GetStream(session, id, source); + BaseObjectPtr stream = session->FindStream(id); + if (!stream) return 0; if (stream->statistics_.first_byte_sent == 0) stream->statistics_.first_byte_sent = uv_hrtime(); CHECK_EQ(id, stream->id()); @@ -2275,21 +2298,21 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, } } - if (amount == 0 && stream->IsWritable()) { + if (amount == 0 && stream->is_writable()) { CHECK(stream->queue_.empty()); Debug(session, "deferring stream %d", id); stream->EmitWantsWrite(length); - if (stream->available_outbound_length_ > 0 || !stream->IsWritable()) { + if (stream->available_outbound_length_ > 0 || !stream->is_writable()) { // EmitWantsWrite() did something interesting synchronously, restart: return OnRead(handle, id, buf, length, flags, source, user_data); } return NGHTTP2_ERR_DEFERRED; } - if (stream->queue_.empty() && !stream->IsWritable()) { + if (stream->queue_.empty() && !stream->is_writable()) { Debug(session, "no more data for stream %d", id); *flags |= NGHTTP2_DATA_FLAG_EOF; - if (stream->HasTrailers()) { + if (stream->has_trailers()) { *flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM; stream->OnTrailers(); } @@ -2299,12 +2322,12 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle, return amount; } -inline void Http2Stream::IncrementAvailableOutboundLength(size_t amount) { +void Http2Stream::IncrementAvailableOutboundLength(size_t amount) { available_outbound_length_ += amount; session_->IncrementCurrentSessionMemory(amount); } -inline void Http2Stream::DecrementAvailableOutboundLength(size_t amount) { +void Http2Stream::DecrementAvailableOutboundLength(size_t amount) { available_outbound_length_ -= amount; session_->DecrementCurrentSessionMemory(amount); } @@ -2318,10 +2341,9 @@ void HttpErrorString(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); uint32_t val = args[0]->Uint32Value(env->context()).ToChecked(); args.GetReturnValue().Set( - String::NewFromOneByte( + OneByteString( env->isolate(), - reinterpret_cast(nghttp2_strerror(val)), - NewStringType::kInternalized).ToLocalChecked()); + reinterpret_cast(nghttp2_strerror(val)))); } @@ -2330,16 +2352,7 @@ void HttpErrorString(const FunctionCallbackInfo& args) { // output for an HTTP2-Settings header field. void PackSettings(const FunctionCallbackInfo& args) { Http2State* state = Unwrap(args.Data()); - Environment* env = state->env(); - // TODO(addaleax): We should not be creating a full AsyncWrap for this. - Local obj; - if (!env->http2settings_constructor_template() - ->NewInstance(env->context()) - .ToLocal(&obj)) { - return; - } - Http2Session::Http2Settings settings(state, nullptr, obj); - args.GetReturnValue().Set(settings.Pack()); + args.GetReturnValue().Set(Http2Settings::Pack(state)); } // A TypedArray instance is shared between C++ and JS land to contain the @@ -2347,7 +2360,7 @@ void PackSettings(const FunctionCallbackInfo& args) { // default values. void RefreshDefaultSettings(const FunctionCallbackInfo& args) { Http2State* state = Unwrap(args.Data()); - Http2Session::Http2Settings::RefreshDefaults(state); + Http2Settings::RefreshDefaults(state); } // Sets the next stream ID the Http2Session. If successful, returns true. @@ -2356,7 +2369,7 @@ void Http2Session::SetNextStreamID(const FunctionCallbackInfo& args) { Http2Session* session; ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); int32_t id = args[0]->Int32Value(env->context()).ToChecked(); - if (nghttp2_session_set_next_stream_id(**session, id) < 0) { + if (nghttp2_session_set_next_stream_id(session->session(), id) < 0) { Debug(session, "failed to set next stream id to %d", id); return args.GetReturnValue().Set(false); } @@ -2385,7 +2398,7 @@ void Http2Session::RefreshState(const FunctionCallbackInfo& args) { AliasedFloat64Array& buffer = session->http2_state()->session_state_buffer; - nghttp2_session* s = **session; + nghttp2_session* s = session->session(); buffer[IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE] = nghttp2_session_get_effective_local_window_size(s); @@ -2413,8 +2426,9 @@ void Http2Session::New(const FunctionCallbackInfo& args) { Http2State* state = Unwrap(args.Data()); Environment* env = state->env(); CHECK(args.IsConstructCall()); - int32_t val = args[0]->Int32Value(env->context()).ToChecked(); - nghttp2_session_type type = static_cast(val); + SessionType type = + static_cast( + args[0]->Int32Value(env->context()).ToChecked()); Http2Session* session = new Http2Session(state, args.This(), type); session->get_async_id(); // avoid compiler warning Debug(session, "session created"); @@ -2450,14 +2464,13 @@ void Http2Session::Request(const FunctionCallbackInfo& args) { Local headers = args[0].As(); int32_t options = args[1]->Int32Value(env->context()).ToChecked(); - Http2Priority priority(env, args[2], args[3], args[4]); Debug(session, "request submitted"); int32_t ret = 0; Http2Stream* stream = session->Http2Session::SubmitRequest( - &priority, + Http2Priority(env, args[2], args[3], args[4]), Http2Headers(env, headers), &ret, static_cast(options)); @@ -2478,7 +2491,7 @@ void Http2Session::Goaway(uint32_t code, int32_t lastStreamID, const uint8_t* data, size_t len) { - if (IsDestroyed()) + if (is_destroyed()) return; Http2Scope h2scope(this); @@ -2629,10 +2642,9 @@ void Http2Stream::Priority(const FunctionCallbackInfo& args) { Http2Stream* stream; ASSIGN_OR_RETURN_UNWRAP(&stream, args.Holder()); - Http2Priority priority(env, args[0], args[1], args[2]); - bool silent = args[3]->IsTrue(); - - CHECK_EQ(stream->SubmitPriority(&priority, silent), 0); + CHECK_EQ(stream->SubmitPriority( + Http2Priority(env, args[0], args[1], args[2]), + args[3]->IsTrue()), 0); Debug(stream, "priority submitted"); } @@ -2649,8 +2661,8 @@ void Http2Stream::RefreshState(const FunctionCallbackInfo& args) { AliasedFloat64Array& buffer = stream->session()->http2_state()->stream_state_buffer; - nghttp2_stream* str = **stream; - nghttp2_session* s = **(stream->session()); + nghttp2_stream* str = stream->stream(); + nghttp2_session* s = stream->session()->session(); if (str == nullptr) { buffer[IDX_STREAM_STATE] = NGHTTP2_STREAM_STATE_IDLE; @@ -2685,12 +2697,13 @@ void Http2Session::AltSvc(int32_t id, origin, origin_len, value, value_len), 0); } -void Http2Session::Origin(nghttp2_origin_entry* ov, size_t count) { +void Http2Session::Origin(const Origins& origins) { Http2Scope h2scope(this); CHECK_EQ(nghttp2_submit_origin( session_.get(), NGHTTP2_FLAG_NONE, - ov, count), 0); + *origins, + origins.length()), 0); } // Submits an AltSvc frame to be sent to the connected peer. @@ -2705,6 +2718,9 @@ void Http2Session::AltSvc(const FunctionCallbackInfo& args) { Local origin_str = args[1]->ToString(env->context()).ToLocalChecked(); Local value_str = args[2]->ToString(env->context()).ToLocalChecked(); + if (origin_str.IsEmpty() || value_str.IsEmpty()) + return; + size_t origin_len = origin_str->Length(); size_t value_len = value_str->Length(); @@ -2728,20 +2744,13 @@ void Http2Session::Origin(const FunctionCallbackInfo& args) { ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); Local origin_string = args[0].As(); - int32_t count = args[1]->Int32Value(context).ToChecked(); - - - Origins origins(env->isolate(), - env->context(), - origin_string, - static_cast(count)); + size_t count = args[1]->Int32Value(context).ToChecked(); - session->Origin(*origins, origins.length()); + session->Origin(Origins(env, origin_string, count)); } // Submits a PING frame to be sent to the connected peer. void Http2Session::Ping(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); Http2Session* session; ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); @@ -2753,55 +2762,20 @@ void Http2Session::Ping(const FunctionCallbackInfo& args) { CHECK_EQ(payload.length(), 8); } - Local obj; - if (!env->http2ping_constructor_template() - ->NewInstance(env->context()) - .ToLocal(&obj)) { - return; - } - if (obj->Set(env->context(), env->ondone_string(), args[1]).IsNothing()) - return; - - Http2Ping* ping = session->AddPing( - MakeDetachedBaseObject(session, obj)); - // To prevent abuse, we strictly limit the number of unacknowledged PING - // frames that may be sent at any given time. This is configurable in the - // Options when creating a Http2Session. - if (ping == nullptr) return args.GetReturnValue().Set(false); - - // The Ping itself is an Async resource. When the acknowledgement is received, - // the callback will be invoked and a notification sent out to JS land. The - // notification will include the duration of the ping, allowing the round - // trip to be measured. - ping->Send(payload.data()); - args.GetReturnValue().Set(true); + CHECK(args[1]->IsFunction()); + args.GetReturnValue().Set( + session->AddPing(payload.data(), args[1].As())); } // Submits a SETTINGS frame for the Http2Session void Http2Session::Settings(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); Http2Session* session; ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); - - Local obj; - if (!env->http2settings_constructor_template() - ->NewInstance(env->context()) - .ToLocal(&obj)) { - return; - } - if (obj->Set(env->context(), env->ondone_string(), args[0]).IsNothing()) - return; - - Http2Settings* settings = session->AddSettings( - MakeDetachedBaseObject( - session->http2_state(), session, obj, 0)); - if (settings == nullptr) return args.GetReturnValue().Set(false); - - settings->Send(); - args.GetReturnValue().Set(true); + CHECK(args[0]->IsFunction()); + args.GetReturnValue().Set(session->AddSettings(args[0].As())); } -BaseObjectPtr Http2Session::PopPing() { +BaseObjectPtr Http2Session::PopPing() { BaseObjectPtr ping; if (!outstanding_pings_.empty()) { ping = std::move(outstanding_pings_.front()); @@ -2811,19 +2785,36 @@ BaseObjectPtr Http2Session::PopPing() { return ping; } -Http2Session::Http2Ping* Http2Session::AddPing( - BaseObjectPtr ping) { +bool Http2Session::AddPing(const uint8_t* payload, Local callback) { + Local obj; + if (!env()->http2ping_constructor_template() + ->NewInstance(env()->context()) + .ToLocal(&obj)) { + return false; + } + + BaseObjectPtr ping = + MakeDetachedBaseObject(this, obj, callback); + if (!ping) + return false; + if (outstanding_pings_.size() == max_outstanding_pings_) { ping->Done(false); - return nullptr; + return false; } - Http2Ping* ptr = ping.get(); - outstanding_pings_.emplace(std::move(ping)); + IncrementCurrentSessionMemory(sizeof(*ping)); - return ptr; + // The Ping itself is an Async resource. When the acknowledgement is received, + // the callback will be invoked and a notification sent out to JS land. The + // notification will include the duration of the ping, allowing the round + // trip to be measured. + ping->Send(payload); + + outstanding_pings_.emplace(std::move(ping)); + return true; } -BaseObjectPtr Http2Session::PopSettings() { +BaseObjectPtr Http2Session::PopSettings() { BaseObjectPtr settings; if (!outstanding_settings_.empty()) { settings = std::move(outstanding_settings_.front()); @@ -2833,60 +2824,88 @@ BaseObjectPtr Http2Session::PopSettings() { return settings; } -Http2Session::Http2Settings* Http2Session::AddSettings( - BaseObjectPtr settings) { +bool Http2Session::AddSettings(Local callback) { + Local obj; + if (!env()->http2settings_constructor_template() + ->NewInstance(env()->context()) + .ToLocal(&obj)) { + return false; + } + + BaseObjectPtr settings = + MakeDetachedBaseObject(this, obj, callback, 0); + if (!settings) + return false; + if (outstanding_settings_.size() == max_outstanding_settings_) { settings->Done(false); - return nullptr; + return false; } - Http2Settings* ptr = settings.get(); - outstanding_settings_.emplace(std::move(settings)); + IncrementCurrentSessionMemory(sizeof(*settings)); - return ptr; + settings->Send(); + outstanding_settings_.emplace(std::move(settings)); + return true; } -Http2Session::Http2Ping::Http2Ping(Http2Session* session, Local obj) +Http2Ping::Http2Ping( + Http2Session* session, + Local obj, + Local callback) : AsyncWrap(session->env(), obj, AsyncWrap::PROVIDER_HTTP2PING), session_(session), startTime_(uv_hrtime()) { + callback_.Reset(env()->isolate(), callback); +} + +void Http2Ping::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("callback", callback_); +} + +Local Http2Ping::callback() const { + return callback_.Get(env()->isolate()); } -void Http2Session::Http2Ping::Send(const uint8_t* payload) { - CHECK_NOT_NULL(session_); +void Http2Ping::Send(const uint8_t* payload) { + CHECK(session_); uint8_t data[8]; if (payload == nullptr) { memcpy(&data, &startTime_, arraysize(data)); payload = data; } - Http2Scope h2scope(session_); - CHECK_EQ(nghttp2_submit_ping(**session_, NGHTTP2_FLAG_NONE, payload), 0); + Http2Scope h2scope(session_.get()); + CHECK_EQ(nghttp2_submit_ping( + session_->session(), + NGHTTP2_FLAG_NONE, + payload), 0); } -void Http2Session::Http2Ping::Done(bool ack, const uint8_t* payload) { +void Http2Ping::Done(bool ack, const uint8_t* payload) { uint64_t duration_ns = uv_hrtime() - startTime_; double duration_ms = duration_ns / 1e6; - if (session_ != nullptr) session_->statistics_.ping_rtt = duration_ns; + if (session_) session_->statistics_.ping_rtt = duration_ns; - HandleScope handle_scope(env()->isolate()); + Isolate* isolate = env()->isolate(); + HandleScope handle_scope(isolate); Context::Scope context_scope(env()->context()); - Local buf = Undefined(env()->isolate()); + Local buf = Undefined(isolate); if (payload != nullptr) { - buf = Buffer::Copy(env()->isolate(), + buf = Buffer::Copy(isolate, reinterpret_cast(payload), 8).ToLocalChecked(); } Local argv[] = { - Boolean::New(env()->isolate(), ack), - Number::New(env()->isolate(), duration_ms), + ack ? v8::True(isolate) : v8::False(isolate), + Number::New(isolate, duration_ms), buf }; - MakeCallback(env()->ondone_string(), arraysize(argv), argv); + MakeCallback(callback(), arraysize(argv), argv); } -void Http2Session::Http2Ping::DetachFromSession() { - session_ = nullptr; +void Http2Ping::DetachFromSession() { + session_.reset(); } void NgHttp2StreamWrite::MemoryInfo(MemoryTracker* tracker) const { @@ -2970,6 +2989,9 @@ void Initialize(Local target, // Method to fetch the nghttp2 string description of an nghttp2 error code env->SetMethod(target, "nghttp2ErrorString", HttpErrorString); + env->SetMethod(target, "refreshDefaultSettings", RefreshDefaultSettings); + env->SetMethod(target, "packSettings", PackSettings); + env->SetMethod(target, "setCallbackFunctions", SetCallbackFunctions); Local http2SessionClassName = FIXED_ONE_BYTE_STRING(isolate, "Http2Session"); @@ -2978,7 +3000,7 @@ void Initialize(Local target, ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping")); ping->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local pingt = ping->InstanceTemplate(); - pingt->SetInternalFieldCount(Http2Session::Http2Ping::kInternalFieldCount); + pingt->SetInternalFieldCount(Http2Ping::kInternalFieldCount); env->set_http2ping_constructor_template(pingt); Local setting = FunctionTemplate::New(env->isolate()); @@ -3038,113 +3060,52 @@ void Initialize(Local target, session->GetFunction(env->context()).ToLocalChecked()).Check(); Local constants = Object::New(isolate); - Local name_for_error_code = Array::New(isolate); - -#define NODE_NGHTTP2_ERROR_CODES(V) \ - V(NGHTTP2_SESSION_SERVER); \ - V(NGHTTP2_SESSION_CLIENT); \ - V(NGHTTP2_STREAM_STATE_IDLE); \ - V(NGHTTP2_STREAM_STATE_OPEN); \ - V(NGHTTP2_STREAM_STATE_RESERVED_LOCAL); \ - V(NGHTTP2_STREAM_STATE_RESERVED_REMOTE); \ - V(NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL); \ - V(NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE); \ - V(NGHTTP2_STREAM_STATE_CLOSED); \ - V(NGHTTP2_NO_ERROR); \ - V(NGHTTP2_PROTOCOL_ERROR); \ - V(NGHTTP2_INTERNAL_ERROR); \ - V(NGHTTP2_FLOW_CONTROL_ERROR); \ - V(NGHTTP2_SETTINGS_TIMEOUT); \ - V(NGHTTP2_STREAM_CLOSED); \ - V(NGHTTP2_FRAME_SIZE_ERROR); \ - V(NGHTTP2_REFUSED_STREAM); \ - V(NGHTTP2_CANCEL); \ - V(NGHTTP2_COMPRESSION_ERROR); \ - V(NGHTTP2_CONNECT_ERROR); \ - V(NGHTTP2_ENHANCE_YOUR_CALM); \ - V(NGHTTP2_INADEQUATE_SECURITY); \ - V(NGHTTP2_HTTP_1_1_REQUIRED); \ - -#define V(name) \ - NODE_DEFINE_CONSTANT(constants, name); \ - name_for_error_code->Set(env->context(), \ - static_cast(name), \ - FIXED_ONE_BYTE_STRING(isolate, \ - #name)).Check(); - NODE_NGHTTP2_ERROR_CODES(V) + + // This does alocate one more slot than needed but it's not used. +#define V(name) FIXED_ONE_BYTE_STRING(isolate, #name), + Local error_code_names[] = { + HTTP2_ERROR_CODES(V) + }; #undef V - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_HCAT_REQUEST); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_HCAT_RESPONSE); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_HCAT_PUSH_RESPONSE); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_HCAT_HEADERS); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_NV_FLAG_NONE); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_NV_FLAG_NO_INDEX); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_ERR_DEFERRED); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_ERR_INVALID_ARGUMENT); - NODE_DEFINE_HIDDEN_CONSTANT(constants, NGHTTP2_ERR_STREAM_CLOSED); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_ERR_FRAME_SIZE_ERROR); - - NODE_DEFINE_HIDDEN_CONSTANT(constants, STREAM_OPTION_EMPTY_PAYLOAD); - NODE_DEFINE_HIDDEN_CONSTANT(constants, STREAM_OPTION_GET_TRAILERS); - - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_NONE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_END_STREAM); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_END_HEADERS); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_ACK); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_PADDED); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_FLAG_PRIORITY); - - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_HEADER_TABLE_SIZE); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_ENABLE_PUSH); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_MAX_FRAME_SIZE); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE); - NODE_DEFINE_CONSTANT(constants, DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL); - NODE_DEFINE_CONSTANT(constants, MAX_MAX_FRAME_SIZE); - NODE_DEFINE_CONSTANT(constants, MIN_MAX_FRAME_SIZE); - NODE_DEFINE_CONSTANT(constants, MAX_INITIAL_WINDOW_SIZE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_DEFAULT_WEIGHT); + Local name_for_error_code = + Array::New( + isolate, + error_code_names, + arraysize(error_code_names)); + + target->Set(context, + FIXED_ONE_BYTE_STRING(isolate, "nameForErrorCode"), + name_for_error_code).Check(); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_ENABLE_PUSH); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_MAX_FRAME_SIZE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE); - NODE_DEFINE_CONSTANT(constants, NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL); +#define V(constant) NODE_DEFINE_HIDDEN_CONSTANT(constants, constant); + HTTP2_HIDDEN_CONSTANTS(V) +#undef V - NODE_DEFINE_CONSTANT(constants, PADDING_STRATEGY_NONE); - NODE_DEFINE_CONSTANT(constants, PADDING_STRATEGY_ALIGNED); - NODE_DEFINE_CONSTANT(constants, PADDING_STRATEGY_MAX); - NODE_DEFINE_CONSTANT(constants, PADDING_STRATEGY_CALLBACK); +#define V(constant) NODE_DEFINE_CONSTANT(constants, constant); + HTTP2_CONSTANTS(V) +#undef V -#define STRING_CONSTANT(NAME, VALUE) \ + // NGHTTP2_DEFAULT_WEIGHT is a macro and not a regular define + // it won't be set properly on the constants object if included + // in the HTTP2_CONSTANTS macro. + NODE_DEFINE_CONSTANT(constants, NGHTTP2_DEFAULT_WEIGHT); + +#define V(NAME, VALUE) \ NODE_DEFINE_STRING_CONSTANT(constants, "HTTP2_HEADER_" # NAME, VALUE); -HTTP_KNOWN_HEADERS(STRING_CONSTANT) -#undef STRING_CONSTANT + HTTP_KNOWN_HEADERS(V) +#undef V -#define STRING_CONSTANT(NAME, VALUE) \ +#define V(NAME, VALUE) \ NODE_DEFINE_STRING_CONSTANT(constants, "HTTP2_METHOD_" # NAME, VALUE); -HTTP_KNOWN_METHODS(STRING_CONSTANT) -#undef STRING_CONSTANT + HTTP_KNOWN_METHODS(V) +#undef V #define V(name, _) NODE_DEFINE_CONSTANT(constants, HTTP_STATUS_##name); -HTTP_STATUS_CODES(V) + HTTP_STATUS_CODES(V) #undef V - env->SetMethod(target, "refreshDefaultSettings", RefreshDefaultSettings); - env->SetMethod(target, "packSettings", PackSettings); - env->SetMethod(target, "setCallbackFunctions", SetCallbackFunctions); - - target->Set(context, - env->constants_string(), - constants).Check(); - target->Set(context, - FIXED_ONE_BYTE_STRING(isolate, "nameForErrorCode"), - name_for_error_code).Check(); + target->Set(context, env->constants_string(), constants).Check(); } } // namespace http2 } // namespace node diff --git a/src/node_http2.h b/src/node_http2.h index 1e5f99acfacec9..6b11535f84e121 100644 --- a/src/node_http2.h +++ b/src/node_http2.h @@ -21,6 +21,10 @@ namespace node { namespace http2 { +// Constants in all caps are exported as user-facing constants +// in JavaScript. Constants using the kName pattern are internal +// only. + // We strictly limit the number of outstanding unacknowledged PINGS a user // may send in order to prevent abuse. The current default cap is 10. The // user may set a different limit using a per Http2Session configuration @@ -34,16 +38,62 @@ constexpr size_t kDefaultMaxSettings = 10; constexpr uint64_t kDefaultMaxSessionMemory = 10000000; // These are the standard HTTP/2 defaults as specified by the RFC -#define DEFAULT_SETTINGS_HEADER_TABLE_SIZE 4096 -#define DEFAULT_SETTINGS_ENABLE_PUSH 1 -#define DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS 0xffffffffu -#define DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE 65535 -#define DEFAULT_SETTINGS_MAX_FRAME_SIZE 16384 -#define DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE 65535 -#define DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL 0 -#define MAX_MAX_FRAME_SIZE 16777215 -#define MIN_MAX_FRAME_SIZE DEFAULT_SETTINGS_MAX_FRAME_SIZE -#define MAX_INITIAL_WINDOW_SIZE 2147483647 +constexpr uint32_t DEFAULT_SETTINGS_HEADER_TABLE_SIZE = 4096; +constexpr uint32_t DEFAULT_SETTINGS_ENABLE_PUSH = 1; +constexpr uint32_t DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS = 0xffffffffu; +constexpr uint32_t DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE = 65535; +constexpr uint32_t DEFAULT_SETTINGS_MAX_FRAME_SIZE = 16384; +constexpr uint32_t DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE = 65535; +constexpr uint32_t DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0; +constexpr uint32_t MAX_MAX_FRAME_SIZE = 16777215; +constexpr uint32_t MIN_MAX_FRAME_SIZE = DEFAULT_SETTINGS_MAX_FRAME_SIZE; +constexpr uint32_t MAX_INITIAL_WINDOW_SIZE = 2147483647; + +// Stream is not going to have any DATA frames +constexpr int STREAM_OPTION_EMPTY_PAYLOAD = 0x1; + +// Stream might have trailing headers +constexpr int STREAM_OPTION_GET_TRAILERS = 0x2; + +// Http2Stream internal states +constexpr int kStreamStateNone = 0x0; +constexpr int kStreamStateShut = 0x1; +constexpr int kStreamStateReadStart = 0x2; +constexpr int kStreamStateReadPaused = 0x4; +constexpr int kStreamStateClosed = 0x8; +constexpr int kStreamStateDestroyed = 0x10; +constexpr int kStreamStateTrailers = 0x20; + +// Http2Session internal states +constexpr int kSessionStateNone = 0x0; +constexpr int kSessionStateHasScope = 0x1; +constexpr int kSessionStateWriteScheduled = 0x2; +constexpr int kSessionStateClosed = 0x4; +constexpr int kSessionStateClosing = 0x8; +constexpr int kSessionStateSending = 0x10; +constexpr int kSessionStateWriteInProgress = 0x20; +constexpr int kSessionStateReadingStopped = 0x40; +constexpr int kSessionStateReceivePaused = 0x80; + +// The Padding Strategy determines the method by which extra padding is +// selected for HEADERS and DATA frames. These are configurable via the +// options passed in to a Http2Session object. +enum PaddingStrategy { + // No padding strategy. This is the default. + PADDING_STRATEGY_NONE, + // Attempts to ensure that the frame is 8-byte aligned + PADDING_STRATEGY_ALIGNED, + // Padding will ensure all data frames are maxFrameSize + PADDING_STRATEGY_MAX, + // Removed and turned into an alias because it is unreasonably expensive for + // very little benefit. + PADDING_STRATEGY_CALLBACK = PADDING_STRATEGY_ALIGNED +}; + +enum SessionType { + NGHTTP2_SESSION_SERVER, + NGHTTP2_SESSION_CLIENT +}; template struct Nghttp2Deleter { @@ -93,37 +143,6 @@ struct Http2RcBufferPointerTraits { using Http2Headers = NgHeaders; using Http2RcBufferPointer = NgRcBufPointer; - -enum nghttp2_session_type { - NGHTTP2_SESSION_SERVER, - NGHTTP2_SESSION_CLIENT -}; - -enum nghttp2_stream_flags { - NGHTTP2_STREAM_FLAG_NONE = 0x0, - // Writable side has ended - NGHTTP2_STREAM_FLAG_SHUT = 0x1, - // Reading has started - NGHTTP2_STREAM_FLAG_READ_START = 0x2, - // Reading is paused - NGHTTP2_STREAM_FLAG_READ_PAUSED = 0x4, - // Stream is closed - NGHTTP2_STREAM_FLAG_CLOSED = 0x8, - // Stream is destroyed - NGHTTP2_STREAM_FLAG_DESTROYED = 0x10, - // Stream has trailers - NGHTTP2_STREAM_FLAG_TRAILERS = 0x20, - // Stream has received all the data it can - NGHTTP2_STREAM_FLAG_EOS = 0x40 -}; - -enum nghttp2_stream_options { - // Stream is not going to have any DATA frames - STREAM_OPTION_EMPTY_PAYLOAD = 0x1, - // Stream might have trailing headers - STREAM_OPTION_GET_TRAILERS = 0x2, -}; - struct NgHttp2StreamWrite : public MemoryRetainer { WriteWrap* req_wrap = nullptr; uv_buf_t buf; @@ -137,38 +156,14 @@ struct NgHttp2StreamWrite : public MemoryRetainer { SET_SELF_SIZE(NgHttp2StreamWrite) }; -// The Padding Strategy determines the method by which extra padding is -// selected for HEADERS and DATA frames. These are configurable via the -// options passed in to a Http2Session object. -enum padding_strategy_type { - // No padding strategy. This is the default. - PADDING_STRATEGY_NONE, - // Attempts to ensure that the frame is 8-byte aligned - PADDING_STRATEGY_ALIGNED, - // Padding will ensure all data frames are maxFrameSize - PADDING_STRATEGY_MAX, - // Removed and turned into an alias because it is unreasonably expensive for - // very little benefit. - PADDING_STRATEGY_CALLBACK = PADDING_STRATEGY_ALIGNED -}; - -enum session_state_flags { - SESSION_STATE_NONE = 0x0, - SESSION_STATE_HAS_SCOPE = 0x1, - SESSION_STATE_WRITE_SCHEDULED = 0x2, - SESSION_STATE_CLOSED = 0x4, - SESSION_STATE_CLOSING = 0x8, - SESSION_STATE_SENDING = 0x10, - SESSION_STATE_WRITE_IN_PROGRESS = 0x20, - SESSION_STATE_READING_STOPPED = 0x40, - SESSION_STATE_NGHTTP2_RECV_PAUSED = 0x80 -}; - typedef uint32_t(*get_setting)(nghttp2_session* session, nghttp2_settings_id id); +class Http2Ping; class Http2Session; +class Http2Settings; class Http2Stream; +class Origins; // This scope should be present when any call into nghttp2 that may schedule // data to be written to the underlying transport is made, and schedules @@ -180,8 +175,7 @@ class Http2Scope { ~Http2Scope(); private: - Http2Session* session_ = nullptr; - v8::Local session_handle_; + BaseObjectPtr session_; }; // The Http2Options class is used to parse the options object passed in to @@ -191,7 +185,7 @@ class Http2Scope { class Http2Options { public: Http2Options(Http2State* http2_state, - nghttp2_session_type type); + SessionType type); ~Http2Options() = default; @@ -199,43 +193,43 @@ class Http2Options { return options_.get(); } - void SetMaxHeaderPairs(uint32_t max) { + void set_max_header_pairs(uint32_t max) { max_header_pairs_ = max; } - uint32_t GetMaxHeaderPairs() const { + uint32_t max_header_pairs() const { return max_header_pairs_; } - void SetPaddingStrategy(padding_strategy_type val) { + void set_padding_strategy(PaddingStrategy val) { padding_strategy_ = val; } - padding_strategy_type GetPaddingStrategy() const { + PaddingStrategy padding_strategy() const { return padding_strategy_; } - void SetMaxOutstandingPings(size_t max) { + void set_max_outstanding_pings(size_t max) { max_outstanding_pings_ = max; } - size_t GetMaxOutstandingPings() const { + size_t max_outstanding_pings() const { return max_outstanding_pings_; } - void SetMaxOutstandingSettings(size_t max) { + void set_max_outstanding_settings(size_t max) { max_outstanding_settings_ = max; } - size_t GetMaxOutstandingSettings() const { + size_t max_outstanding_settings() const { return max_outstanding_settings_; } - void SetMaxSessionMemory(uint64_t max) { + void set_max_session_memory(uint64_t max) { max_session_memory_ = max; } - uint64_t GetMaxSessionMemory() const { + uint64_t max_session_memory() const { return max_session_memory_; } @@ -243,7 +237,7 @@ class Http2Options { Nghttp2OptionPointer options_; uint64_t max_session_memory_ = kDefaultMaxSessionMemory; uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS; - padding_strategy_type padding_strategy_ = PADDING_STRATEGY_NONE; + PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE; size_t max_outstanding_pings_ = kDefaultMaxPings; size_t max_outstanding_settings_ = kDefaultMaxSettings; }; @@ -282,13 +276,13 @@ class Http2Stream : public AsyncWrap, int options = 0); ~Http2Stream() override; - nghttp2_stream* operator*(); + nghttp2_stream* operator*() const; + + nghttp2_stream* stream() const; Http2Session* session() { return session_.get(); } const Http2Session* session() const { return session_.get(); } - void EmitStatistics(); - // Required for StreamBase int ReadStart() override; @@ -312,7 +306,7 @@ class Http2Stream : public AsyncWrap, void OnTrailers(); // Submit a PRIORITY frame for this stream - int SubmitPriority(nghttp2_priority_spec* prispec, bool silent = false); + int SubmitPriority(const Http2Priority& priority, bool silent = false); // Submits an RST_STREAM frame using the given code void SubmitRstStream(const uint32_t code); @@ -331,42 +325,74 @@ class Http2Stream : public AsyncWrap, // Destroy this stream instance and free all held memory. void Destroy(); - inline bool IsDestroyed() const { - return flags_ & NGHTTP2_STREAM_FLAG_DESTROYED; + bool is_destroyed() const { + return flags_ & kStreamStateDestroyed; + } + + bool is_writable() const { + return !(flags_ & kStreamStateShut); + } + + bool is_paused() const { + return flags_ & kStreamStateReadPaused; + } + + bool is_closed() const { + return flags_ & kStreamStateClosed; + } + + bool has_trailers() const { + return flags_ & kStreamStateTrailers; + } + + void set_has_trailers(bool on = true) { + if (on) + flags_ |= kStreamStateTrailers; + else + flags_ &= ~kStreamStateTrailers; } - inline bool IsWritable() const { - return !(flags_ & NGHTTP2_STREAM_FLAG_SHUT); + void set_closed() { + flags_ |= kStreamStateClosed; } - inline bool IsPaused() const { - return flags_ & NGHTTP2_STREAM_FLAG_READ_PAUSED; + void set_destroyed() { + flags_ |= kStreamStateDestroyed; } - inline bool IsClosed() const { - return flags_ & NGHTTP2_STREAM_FLAG_CLOSED; + void set_not_writable() { + flags_ |= kStreamStateShut; } - inline bool HasTrailers() const { - return flags_ & NGHTTP2_STREAM_FLAG_TRAILERS; + void set_reading(bool on = true) { + if (on) { + flags_ |= kStreamStateReadStart; + set_paused(false); + } else {} + } + + void set_paused(bool on = true) { + if (on) + flags_ |= kStreamStateReadPaused; + else + flags_ &= ~kStreamStateReadPaused; } // Returns true if this stream is in the reading state, which occurs when - // the NGHTTP2_STREAM_FLAG_READ_START flag has been set and the - // NGHTTP2_STREAM_FLAG_READ_PAUSED flag is *not* set. - inline bool IsReading() const { - return flags_ & NGHTTP2_STREAM_FLAG_READ_START && - !(flags_ & NGHTTP2_STREAM_FLAG_READ_PAUSED); + // the kStreamStateReadStart flag has been set and the + // kStreamStateReadPaused flag is *not* set. + bool is_reading() const { + return flags_ & kStreamStateReadStart && !is_paused(); } // Returns the RST_STREAM code used to close this stream - inline int32_t code() const { return code_; } + int32_t code() const { return code_; } // Returns the stream identifier for this stream - inline int32_t id() const { return id_; } + int32_t id() const { return id_; } - inline void IncrementAvailableOutboundLength(size_t amount); - inline void DecrementAvailableOutboundLength(size_t amount); + void IncrementAvailableOutboundLength(size_t amount); + void DecrementAvailableOutboundLength(size_t amount); bool AddHeader(nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags); @@ -382,7 +408,7 @@ class Http2Stream : public AsyncWrap, return current_headers_.size(); } - inline nghttp2_headers_category headers_category() const { + nghttp2_headers_category headers_category() const { return current_headers_category_; } @@ -403,11 +429,7 @@ class Http2Stream : public AsyncWrap, int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count, uv_stream_t* send_handle) override; - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("current_headers", current_headers_); - tracker->TrackField("queue", queue_); - } - + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Http2Stream) SET_SELF_SIZE(Http2Stream) @@ -445,10 +467,12 @@ class Http2Stream : public AsyncWrap, nghttp2_headers_category category, int options); + void EmitStatistics(); + BaseObjectWeakPtr session_; // The Parent HTTP/2 Session int32_t id_ = 0; // The Stream Identifier int32_t code_ = NGHTTP2_NO_ERROR; // The RST_STREAM code (if any) - int flags_ = NGHTTP2_STREAM_FLAG_NONE; // Internal state flags + int flags_ = kStreamStateNone; // Internal state flags uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS; uint32_t max_header_length_ = DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE; @@ -545,29 +569,28 @@ class Http2Session : public AsyncWrap, public: Http2Session(Http2State* http2_state, v8::Local wrap, - nghttp2_session_type type = NGHTTP2_SESSION_SERVER); + SessionType type = NGHTTP2_SESSION_SERVER); ~Http2Session() override; - class Http2Ping; - class Http2Settings; - - void EmitStatistics(); - - inline StreamBase* underlying_stream() { + StreamBase* underlying_stream() { return static_cast(stream_); } void Close(uint32_t code = NGHTTP2_NO_ERROR, bool socket_closed = false); + void Consume(v8::Local stream); + void Goaway(uint32_t code, int32_t lastStreamID, const uint8_t* data, size_t len); + void AltSvc(int32_t id, uint8_t* origin, size_t origin_len, uint8_t* value, size_t value_len); - void Origin(nghttp2_origin_entry* ov, size_t count); + + void Origin(const Origins& origins); uint8_t SendPendingData(); @@ -575,25 +598,48 @@ class Http2Session : public AsyncWrap, // will be a pointer to the Http2Stream instance assigned. // This only works if the session is a client session. Http2Stream* SubmitRequest( - nghttp2_priority_spec* prispec, + const Http2Priority& priority, const Http2Headers& headers, int32_t* ret, int options = 0); - inline nghttp2_session_type type() const { return session_type_; } + SessionType type() const { return session_type_; } - inline nghttp2_session* session() const { return session_.get(); } + nghttp2_session* session() const { return session_.get(); } - inline nghttp2_session* operator*() { return session_.get(); } + nghttp2_session* operator*() { return session_.get(); } - inline uint32_t GetMaxHeaderPairs() const { return max_header_pairs_; } + uint32_t max_header_pairs() const { return max_header_pairs_; } + + const char* TypeName() const; + + bool is_destroyed() { + return (flags_ & kSessionStateClosed) || session_ == nullptr; + } - inline const char* TypeName() const; + void set_destroyed() { + flags_ |= kSessionStateClosed; + } - inline bool IsDestroyed() { - return (flags_ & SESSION_STATE_CLOSED) || session_ == nullptr; +#define IS_FLAG(name, flag) \ + bool is_##name() const { return flags_ & flag; } \ + void set_##name(bool on = true) { \ + if (on) \ + flags_ |= flag; \ + else \ + flags_ &= ~flag; \ } + IS_FLAG(in_scope, kSessionStateHasScope) + IS_FLAG(write_scheduled, kSessionStateWriteScheduled) + IS_FLAG(closing, kSessionStateClosing) + IS_FLAG(sending, kSessionStateSending) + IS_FLAG(write_in_progress, kSessionStateWriteInProgress) + IS_FLAG(reading_stopped, kSessionStateReadingStopped) + IS_FLAG(receive_paused, kSessionStateReceivePaused) + +#undef IS_FLAG + // Schedule a write if nghttp2 indicates it wants to write to the socket. void MaybeScheduleWrite(); @@ -601,15 +647,15 @@ class Http2Session : public AsyncWrap, void MaybeStopReading(); // Returns pointer to the stream, or nullptr if stream does not exist - inline Http2Stream* FindStream(int32_t id); + BaseObjectPtr FindStream(int32_t id); - inline bool CanAddStream(); + bool CanAddStream(); // Adds a stream instance to this session - inline void AddStream(Http2Stream* stream); + void AddStream(Http2Stream* stream); // Removes a stream instance from this session - inline void RemoveStream(Http2Stream* stream); + BaseObjectPtr RemoveStream(int32_t id); // Indicates whether there currently exist outgoing buffers for this stream. bool HasWritesOnSocketForStream(Http2Stream* stream); @@ -617,32 +663,22 @@ class Http2Session : public AsyncWrap, // Write data from stream_buf_ to the session ssize_t ConsumeHTTP2Data(); - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("streams", streams_); - tracker->TrackField("outstanding_pings", outstanding_pings_); - tracker->TrackField("outstanding_settings", outstanding_settings_); - tracker->TrackField("outgoing_buffers", outgoing_buffers_); - tracker->TrackFieldWithSize("stream_buf", stream_buf_.len); - tracker->TrackFieldWithSize("outgoing_storage", outgoing_storage_.size()); - tracker->TrackFieldWithSize("pending_rst_streams", - pending_rst_streams_.size() * sizeof(int32_t)); - tracker->TrackFieldWithSize("nghttp2_memory", current_nghttp2_memory_); - } - + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Http2Session) SET_SELF_SIZE(Http2Session) std::string diagnostic_name() const override; // Schedule an RstStream for after the current write finishes. - inline void AddPendingRstStream(int32_t stream_id) { + void AddPendingRstStream(int32_t stream_id) { pending_rst_streams_.emplace_back(stream_id); } - inline bool HasPendingRstStream(int32_t stream_id) { - return pending_rst_streams_.end() != std::find(pending_rst_streams_.begin(), - pending_rst_streams_.end(), - stream_id); + bool has_pending_rststream(int32_t stream_id) { + return pending_rst_streams_.end() != + std::find(pending_rst_streams_.begin(), + pending_rst_streams_.end(), + stream_id); } // Handle reads/writes from the underlying network transport. @@ -676,14 +712,13 @@ class Http2Session : public AsyncWrap, return env()->event_loop(); } - Http2State* http2_state() { - return http2_state_.get(); - } + Http2State* http2_state() const { return http2_state_.get(); } + BaseObjectPtr PopPing(); - Http2Ping* AddPing(BaseObjectPtr ping); + bool AddPing(const uint8_t* data, v8::Local callback); BaseObjectPtr PopSettings(); - Http2Settings* AddSettings(BaseObjectPtr settings); + bool AddSettings(v8::Local callback); void IncrementCurrentSessionMemory(uint64_t amount) { current_session_memory_ += amount; @@ -700,7 +735,7 @@ class Http2Session : public AsyncWrap, // Returns the current session memory including memory allocated by nghttp2, // the current outbound storage queue, and pending writes. - uint64_t GetCurrentSessionMemory() { + uint64_t current_session_memory() const { uint64_t total = current_session_memory_ + sizeof(Http2Session); total += current_nghttp2_memory_; total += outgoing_storage_.size(); @@ -708,8 +743,8 @@ class Http2Session : public AsyncWrap, } // Return true if current_session_memory + amount is less than the max - bool IsAvailableSessionMemory(uint64_t amount) { - return GetCurrentSessionMemory() + amount <= max_session_memory_; + bool has_available_session_memory(uint64_t amount) const { + return current_session_memory() + amount <= max_session_memory_; } struct Statistics { @@ -728,6 +763,8 @@ class Http2Session : public AsyncWrap, Statistics statistics_ = {}; private: + void EmitStatistics(); + // Frame Padding Strategies ssize_t OnDWordAlignedPadding(size_t frameLength, size_t maxPayloadLen); @@ -812,7 +849,7 @@ class Http2Session : public AsyncWrap, void* user_data); struct Callbacks { - inline explicit Callbacks(bool kHasGetPaddingCallback); + explicit Callbacks(bool kHasGetPaddingCallback); Nghttp2SessionCallbacksPointer callbacks; }; @@ -827,7 +864,7 @@ class Http2Session : public AsyncWrap, AliasedStruct js_fields_; // The session type: client or server - nghttp2_session_type session_type_; + SessionType session_type_; // The maximum number of header pairs permitted for streams on this session uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS; @@ -839,12 +876,12 @@ class Http2Session : public AsyncWrap, uint64_t current_nghttp2_memory_ = 0; // The collection of active Http2Streams associated with this session - std::unordered_map streams_; + std::unordered_map> streams_; - int flags_ = SESSION_STATE_NONE; + int flags_ = kSessionStateNone; // The StreamBase instance being used for i/o - padding_strategy_type padding_strategy_ = PADDING_STRATEGY_NONE; + PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE; // use this to allow timeout tracking during long-lasting writes uint32_t chunks_sent_since_last_write_ = 0; @@ -890,7 +927,7 @@ class Http2SessionPerformanceEntry : public performance::PerformanceEntry { Http2SessionPerformanceEntry( Http2State* http2_state, const Http2Session::Statistics& stats, - nghttp2_session_type type) : + SessionType type) : performance::PerformanceEntry( http2_state->env(), "Http2Session", "http2", stats.start_time, @@ -914,7 +951,7 @@ class Http2SessionPerformanceEntry : public performance::PerformanceEntry { int32_t stream_count() const { return stream_count_; } size_t max_concurrent_streams() const { return max_concurrent_streams_; } double stream_average_duration() const { return stream_average_duration_; } - nghttp2_session_type type() const { return session_type_; } + SessionType type() const { return session_type_; } Http2State* http2_state() const { return http2_state_.get(); } void Notify(v8::Local obj) { @@ -930,7 +967,7 @@ class Http2SessionPerformanceEntry : public performance::PerformanceEntry { int32_t stream_count_; size_t max_concurrent_streams_; double stream_average_duration_; - nghttp2_session_type session_type_; + SessionType session_type_; BaseObjectPtr http2_state_; }; @@ -975,14 +1012,14 @@ class Http2StreamPerformanceEntry BaseObjectPtr http2_state_; }; -class Http2Session::Http2Ping : public AsyncWrap { +class Http2Ping : public AsyncWrap { public: - explicit Http2Ping(Http2Session* session, v8::Local obj); - - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("session", session_); - } + explicit Http2Ping( + Http2Session* session, + v8::Local obj, + v8::Local callback); + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Http2Ping) SET_SELF_SIZE(Http2Ping) @@ -990,34 +1027,38 @@ class Http2Session::Http2Ping : public AsyncWrap { void Done(bool ack, const uint8_t* payload = nullptr); void DetachFromSession(); + v8::Local callback() const; + private: - Http2Session* session_; + BaseObjectWeakPtr session_; + v8::Global callback_; uint64_t startTime_; }; // The Http2Settings class is used to parse the settings passed in for // an Http2Session, converting those into an array of nghttp2_settings_entry // structs. -class Http2Session::Http2Settings : public AsyncWrap { +class Http2Settings : public AsyncWrap { public: - Http2Settings(Http2State* http2_state, - Http2Session* session, + Http2Settings(Http2Session* session, v8::Local obj, + v8::Local callback, uint64_t start_time = uv_hrtime()); - void MemoryInfo(MemoryTracker* tracker) const override { - tracker->TrackField("session", session_); - } - + void MemoryInfo(MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Http2Settings) SET_SELF_SIZE(Http2Settings) void Send(); void Done(bool ack); + v8::Local callback() const; + // Returns a Buffer instance with the serialized SETTINGS payload v8::Local Pack(); + static v8::Local Pack(Http2State* state); + // Resets the default values in the settings buffer static void RefreshDefaults(Http2State* http2_state); @@ -1026,8 +1067,17 @@ class Http2Session::Http2Settings : public AsyncWrap { get_setting fn); private: - void Init(Http2State* http2_state); - Http2Session* session_; + static size_t Init( + Http2State* http2_state, + nghttp2_settings_entry* entries); + + static v8::Local Pack( + Environment* env, + size_t count, + const nghttp2_settings_entry* entries); + + BaseObjectWeakPtr session_; + v8::Global callback_; uint64_t startTime_; size_t count_ = 0; nghttp2_settings_entry entries_[IDX_SETTINGS_COUNT]; @@ -1035,14 +1085,13 @@ class Http2Session::Http2Settings : public AsyncWrap { class Origins { public: - Origins(v8::Isolate* isolate, - v8::Local context, + Origins(Environment* env, v8::Local origin_string, size_t origin_count); ~Origins() = default; - nghttp2_origin_entry* operator*() { - return reinterpret_cast(*buf_); + const nghttp2_origin_entry* operator*() const { + return reinterpret_cast(buf_.data()); } size_t length() const { @@ -1051,9 +1100,88 @@ class Origins { private: size_t count_; - MaybeStackBuffer buf_; + AllocatedBuffer buf_; }; +#define HTTP2_HIDDEN_CONSTANTS(V) \ + V(NGHTTP2_HCAT_REQUEST) \ + V(NGHTTP2_HCAT_RESPONSE) \ + V(NGHTTP2_HCAT_PUSH_RESPONSE) \ + V(NGHTTP2_HCAT_HEADERS) \ + V(NGHTTP2_NV_FLAG_NONE) \ + V(NGHTTP2_NV_FLAG_NO_INDEX) \ + V(NGHTTP2_ERR_DEFERRED) \ + V(NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE) \ + V(NGHTTP2_ERR_INVALID_ARGUMENT) \ + V(NGHTTP2_ERR_STREAM_CLOSED) \ + V(STREAM_OPTION_EMPTY_PAYLOAD) \ + V(STREAM_OPTION_GET_TRAILERS) + +#define HTTP2_ERROR_CODES(V) \ + V(NGHTTP2_NO_ERROR) \ + V(NGHTTP2_PROTOCOL_ERROR) \ + V(NGHTTP2_INTERNAL_ERROR) \ + V(NGHTTP2_FLOW_CONTROL_ERROR) \ + V(NGHTTP2_SETTINGS_TIMEOUT) \ + V(NGHTTP2_STREAM_CLOSED) \ + V(NGHTTP2_FRAME_SIZE_ERROR) \ + V(NGHTTP2_REFUSED_STREAM) \ + V(NGHTTP2_CANCEL) \ + V(NGHTTP2_COMPRESSION_ERROR) \ + V(NGHTTP2_CONNECT_ERROR) \ + V(NGHTTP2_ENHANCE_YOUR_CALM) \ + V(NGHTTP2_INADEQUATE_SECURITY) \ + V(NGHTTP2_HTTP_1_1_REQUIRED) \ + +#define HTTP2_CONSTANTS(V) \ + V(NGHTTP2_ERR_FRAME_SIZE_ERROR) \ + V(NGHTTP2_SESSION_SERVER) \ + V(NGHTTP2_SESSION_CLIENT) \ + V(NGHTTP2_STREAM_STATE_IDLE) \ + V(NGHTTP2_STREAM_STATE_OPEN) \ + V(NGHTTP2_STREAM_STATE_RESERVED_LOCAL) \ + V(NGHTTP2_STREAM_STATE_RESERVED_REMOTE) \ + V(NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL) \ + V(NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE) \ + V(NGHTTP2_STREAM_STATE_CLOSED) \ + V(NGHTTP2_FLAG_NONE) \ + V(NGHTTP2_FLAG_END_STREAM) \ + V(NGHTTP2_FLAG_END_HEADERS) \ + V(NGHTTP2_FLAG_ACK) \ + V(NGHTTP2_FLAG_PADDED) \ + V(NGHTTP2_FLAG_PRIORITY) \ + V(DEFAULT_SETTINGS_HEADER_TABLE_SIZE) \ + V(DEFAULT_SETTINGS_ENABLE_PUSH) \ + V(DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS) \ + V(DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE) \ + V(DEFAULT_SETTINGS_MAX_FRAME_SIZE) \ + V(DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE) \ + V(DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL) \ + V(MAX_MAX_FRAME_SIZE) \ + V(MIN_MAX_FRAME_SIZE) \ + V(MAX_INITIAL_WINDOW_SIZE) \ + V(NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) \ + V(NGHTTP2_SETTINGS_ENABLE_PUSH) \ + V(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS) \ + V(NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE) \ + V(NGHTTP2_SETTINGS_MAX_FRAME_SIZE) \ + V(NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE) \ + V(NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL) \ + V(PADDING_STRATEGY_NONE) \ + V(PADDING_STRATEGY_ALIGNED) \ + V(PADDING_STRATEGY_MAX) \ + V(PADDING_STRATEGY_CALLBACK) \ + HTTP2_ERROR_CODES(V) + +#define HTTP2_SETTINGS(V) \ + V(HEADER_TABLE_SIZE) \ + V(ENABLE_PUSH) \ + V(MAX_CONCURRENT_STREAMS) \ + V(INITIAL_WINDOW_SIZE) \ + V(MAX_FRAME_SIZE) \ + V(MAX_HEADER_LIST_SIZE) \ + V(ENABLE_CONNECT_PROTOCOL) \ + } // namespace http2 } // namespace node diff --git a/src/node_options.cc b/src/node_options.cc index 4148cfc04eb2ac..3b9142c19e98a8 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -285,7 +285,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { kAllowedInEnvironment); AddAlias("--loader", "--experimental-loader"); AddOption("--experimental-modules", - "experimental modules features", + "", &EnvironmentOptions::experimental_modules, kAllowedInEnvironment); AddOption("--experimental-wasm-modules", diff --git a/src/node_os.cc b/src/node_os.cc index b64b75fa6b90be..bd61b4c87c0e1a 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -132,16 +132,12 @@ static void GetCPUInfo(const FunctionCallbackInfo& args) { static void GetFreeMemory(const FunctionCallbackInfo& args) { double amount = uv_get_free_memory(); - if (amount < 0) - return; args.GetReturnValue().Set(amount); } static void GetTotalMemory(const FunctionCallbackInfo& args) { double amount = uv_get_total_memory(); - if (amount < 0) - return; args.GetReturnValue().Set(amount); } @@ -197,7 +193,7 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo& args) { // they name the interface from any input that uses UTF-8, which should be // the most frequent case by far these days.) name = String::NewFromUtf8(isolate, raw_name, - v8::NewStringType::kNormal).ToLocalChecked(); + NewStringType::kNormal).ToLocalChecked(); snprintf(mac.data(), mac.size(), @@ -257,7 +253,7 @@ static void GetHomeDirectory(const FunctionCallbackInfo& args) { Local home = String::NewFromUtf8(env->isolate(), buf, - v8::NewStringType::kNormal, + NewStringType::kNormal, len).ToLocalChecked(); args.GetReturnValue().Set(home); } diff --git a/src/node_version.h b/src/node_version.h index a8317b22395433..372ca6e779f738 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 14 -#define NODE_MINOR_VERSION 0 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 1 +#define NODE_PATCH_VERSION 0 #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/tcp_wrap.cc b/src/tcp_wrap.cc index 1aca3a5e6aeeee..619c9ef6196373 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -185,7 +185,7 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo& args) { Environment* env = wrap->env(); int enable; if (!args[0]->Int32Value(env->context()).To(&enable)) return; - unsigned int delay = args[1].As()->Value(); + unsigned int delay = static_cast(args[1].As()->Value()); int err = uv_tcp_keepalive(&wrap->handle_, enable, delay); args.GetReturnValue().Set(err); } @@ -278,7 +278,8 @@ void TCPWrap::Listen(const FunctionCallbackInfo& args) { void TCPWrap::Connect(const FunctionCallbackInfo& args) { CHECK(args[2]->IsUint32()); - int port = args[2].As()->Value(); + // explicit cast to fit to libuv's type expectation + int port = static_cast(args[2].As()->Value()); Connect(args, [port](const char* ip_address, sockaddr_in* addr) { return uv_ip4_addr(ip_address, port, addr); diff --git a/test/es-module/test-esm-exports.mjs b/test/es-module/test-esm-exports.mjs index f71e2172951843..74bf66be32c39a 100644 --- a/test/es-module/test-esm-exports.mjs +++ b/test/es-module/test-esm-exports.mjs @@ -64,6 +64,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; // Conditional exports with no match are "not exported" errors ['pkgexports/invalid1', './invalid1'], ['pkgexports/invalid4', './invalid4'], + // Null mapping + ['pkgexports/null', './null'], + ['pkgexports/null/subpath', './null/subpath'], + // Empty fallback + ['pkgexports/nofallback1', './nofallback1'], ]); const invalidExports = new Map([ @@ -74,12 +79,11 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; ['pkgexports/belowdir/pkgexports/asdf.js', './belowdir/'], // This target file steps below the package ['pkgexports/belowfile', './belowfile'], - // Invalid target handling - ['pkgexports/null', './null'], + // Invalid targets ['pkgexports/invalid2', './invalid2'], ['pkgexports/invalid3', './invalid3'], + ['pkgexports/invalid5', 'invalid5'], // Missing / invalid fallbacks - ['pkgexports/nofallback1', './nofallback1'], ['pkgexports/nofallback2', './nofallback2'], // Reaching into nested node_modules ['pkgexports/nodemodules', './nodemodules'], @@ -106,6 +110,9 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; strictEqual(err.code, 'ERR_INVALID_PACKAGE_TARGET'); assertStartsWith(err.message, 'Invalid "exports"'); assertIncludes(err.message, subpath); + if (!subpath.startsWith('./')) { + assertIncludes(err.message, 'targets must start with'); + } })); } diff --git a/test/fixtures/cycles/warning-esm-half-transpiled-a.js b/test/fixtures/cycles/warning-esm-half-transpiled-a.js new file mode 100644 index 00000000000000..f4c17f9e4adaaf --- /dev/null +++ b/test/fixtures/cycles/warning-esm-half-transpiled-a.js @@ -0,0 +1 @@ +require('./warning-esm-half-transpiled-b.js'); diff --git a/test/fixtures/cycles/warning-esm-half-transpiled-b.js b/test/fixtures/cycles/warning-esm-half-transpiled-b.js new file mode 100644 index 00000000000000..ab31fdbffc1a07 --- /dev/null +++ b/test/fixtures/cycles/warning-esm-half-transpiled-b.js @@ -0,0 +1,2 @@ +const a = require('./warning-esm-half-transpiled-a.js'); +a.__esModule; diff --git a/test/fixtures/node_modules/pkgexports/package.json b/test/fixtures/node_modules/pkgexports/package.json index f3ec20c49b2b91..b99e5c7b79f6a8 100644 --- a/test/fixtures/node_modules/pkgexports/package.json +++ b/test/fixtures/node_modules/pkgexports/package.json @@ -9,10 +9,12 @@ "./belowfile": "../belowfile", "./missingtrailer/": ".", "./null": null, + "./null/": null, "./invalid1": {}, "./invalid2": 1234, "./invalid3": "", "./invalid4": {}, + "./invalid5": "invalid5.js", "./fallbackdir/": [[], null, {}, "builtin:x/", "./fallbackfile", "./"], "./fallbackfile": [[], null, {}, "builtin:x", "./asdf.js"], "./nofallback1": [], diff --git a/test/internet/test-http2-issue-32922.js b/test/internet/test-http2-issue-32922.js new file mode 100644 index 00000000000000..e11de0286eb7a4 --- /dev/null +++ b/test/internet/test-http2-issue-32922.js @@ -0,0 +1,80 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const http2 = require('http2'); +const net = require('net'); + +const { + HTTP2_HEADER_PATH, +} = http2.constants; + +// Create a normal session, as a control case +function normalSession(cb) { + http2.connect('https://google.com', (clientSession) => { + let error = null; + const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' }); + req.on('error', (err) => { + error = err; + }); + req.on('response', (_headers) => { + req.on('data', (_chunk) => { }); + req.on('end', () => { + clientSession.close(); + return cb(error); + }); + }); + }); +} +normalSession(common.mustCall(function(err) { + assert.ifError(err); +})); + +// Create a session using a socket that has not yet finished connecting +function socketNotFinished(done) { + const socket2 = net.connect(443, 'google.com'); + http2.connect('https://google.com', { socket2 }, (clientSession) => { + let error = null; + const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' }); + req.on('error', (err) => { + error = err; + }); + req.on('response', (_headers) => { + req.on('data', (_chunk) => { }); + req.on('end', () => { + clientSession.close(); + socket2.destroy(); + return done(error); + }); + }); + }); +} +socketNotFinished(common.mustCall(function(err) { + assert.ifError(err); +})); + +// Create a session using a socket that has finished connecting +function socketFinished(done) { + const socket = net.connect(443, 'google.com', () => { + http2.connect('https://google.com', { socket }, (clientSession) => { + let error = null; + const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' }); + req.on('error', (err) => { + error = err; + }); + req.on('response', (_headers) => { + req.on('data', (_chunk) => { }); + req.on('end', () => { + clientSession.close(); + return done(error); + }); + }); + }); + }); +} +socketFinished(common.mustCall(function(err) { + assert.ifError(err); +})); diff --git a/test/node-api/test_callback_scope/binding.cc b/test/node-api/test_callback_scope/binding.cc index 1a06d04fce53e3..153428a65bd6e4 100644 --- a/test/node-api/test_callback_scope/binding.cc +++ b/test/node-api/test_callback_scope/binding.cc @@ -4,21 +4,12 @@ namespace { -// the test needs to fake out the async structure, so we need to use -// the raw structure here and then cast as done behind the scenes -// in napi calls. -struct async_context { - double async_id; - double trigger_async_id; -}; - - napi_value RunInCallbackScope(napi_env env, napi_callback_info info) { size_t argc; - napi_value args[4]; + napi_value args[3]; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr)); - NAPI_ASSERT(env, argc == 4 , "Wrong number of arguments"); + NAPI_ASSERT(env, argc == 3 , "Wrong number of arguments"); NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); @@ -28,35 +19,29 @@ napi_value RunInCallbackScope(napi_env env, napi_callback_info info) { "Wrong type of arguments. Expects an object as first argument."); NAPI_CALL(env, napi_typeof(env, args[1], &valuetype)); - NAPI_ASSERT(env, valuetype == napi_number, - "Wrong type of arguments. Expects a number as second argument."); + NAPI_ASSERT(env, valuetype == napi_string, + "Wrong type of arguments. Expects a string as second argument."); NAPI_CALL(env, napi_typeof(env, args[2], &valuetype)); - NAPI_ASSERT(env, valuetype == napi_number, - "Wrong type of arguments. Expects a number as third argument."); - - NAPI_CALL(env, napi_typeof(env, args[3], &valuetype)); NAPI_ASSERT(env, valuetype == napi_function, "Wrong type of arguments. Expects a function as third argument."); - struct async_context context; - NAPI_CALL(env, napi_get_value_double(env, args[1], &context.async_id)); - NAPI_CALL(env, - napi_get_value_double(env, args[2], &context.trigger_async_id)); + napi_async_context context; + NAPI_CALL(env, napi_async_init(env, args[0], args[1], &context)); napi_callback_scope scope = nullptr; NAPI_CALL( env, napi_open_callback_scope(env, args[0], - reinterpret_cast(&context), + context, &scope)); // if the function has an exception pending after the call that is ok // so we don't use NAPI_CALL as we must close the callback scope regardless napi_value result = nullptr; napi_status function_call_result = - napi_call_function(env, args[0], args[3], 0, nullptr, &result); + napi_call_function(env, args[0], args[2], 0, nullptr, &result); if (function_call_result != napi_ok) { GET_AND_THROW_LAST_ERROR((env)); } diff --git a/test/node-api/test_callback_scope/test-async-hooks.js b/test/node-api/test_callback_scope/test-async-hooks.js index 1a11bf60398f9b..22074428883d6b 100644 --- a/test/node-api/test_callback_scope/test-async-hooks.js +++ b/test/node-api/test_callback_scope/test-async-hooks.js @@ -12,18 +12,28 @@ process.emitWarning = () => {}; const { runInCallbackScope } = require(`./build/${common.buildType}/binding`); +const expectedResource = {}; +const expectedResourceType = 'test-resource'; let insideHook = false; +let expectedId; async_hooks.createHook({ + init: common.mustCall((id, type, triggerAsyncId, resource) => { + if (type !== expectedResourceType) { + return; + } + assert.strictEqual(resource, expectedResource); + expectedId = id; + }), before: common.mustCall((id) => { - assert.strictEqual(id, 1000); + assert.strictEqual(id, expectedId); insideHook = true; }), after: common.mustCall((id) => { - assert.strictEqual(id, 1000); + assert.strictEqual(id, expectedId); insideHook = false; }) }).enable(); -runInCallbackScope({}, 1000, 1000, () => { +runInCallbackScope(expectedResource, expectedResourceType, () => { assert(insideHook); }); diff --git a/test/node-api/test_callback_scope/test.js b/test/node-api/test_callback_scope/test.js index 2f2efe5f47b98a..abf9e41b8f5028 100644 --- a/test/node-api/test_callback_scope/test.js +++ b/test/node-api/test_callback_scope/test.js @@ -4,14 +4,14 @@ const common = require('../../common'); const assert = require('assert'); const { runInCallbackScope } = require(`./build/${common.buildType}/binding`); -assert.strictEqual(runInCallbackScope({}, 0, 0, () => 42), 42); +assert.strictEqual(runInCallbackScope({}, 'test-resource', () => 42), 42); { process.once('uncaughtException', common.mustCall((err) => { assert.strictEqual(err.message, 'foo'); })); - runInCallbackScope({}, 0, 0, () => { + runInCallbackScope({}, 'test-resource', () => { throw new Error('foo'); }); } diff --git a/test/node-api/test_threadsafe_function/binding.c b/test/node-api/test_threadsafe_function/binding.c index c9c526153804c6..9f2fa5f9bd21bc 100644 --- a/test/node-api/test_threadsafe_function/binding.c +++ b/test/node-api/test_threadsafe_function/binding.c @@ -267,6 +267,60 @@ static napi_value StartThreadNoJsFunc(napi_env env, napi_callback_info info) { /** block_on_full */true, /** alt_ref_js_cb */true); } +static void DeadlockTestDummyMarshaller(napi_env env, + napi_value empty0, + void* empty1, + void* empty2) {} + +static napi_value TestDeadlock(napi_env env, napi_callback_info info) { + napi_threadsafe_function tsfn; + napi_status status; + napi_value async_name; + napi_value return_value; + + // Create an object to store the returned information. + NAPI_CALL(env, napi_create_object(env, &return_value)); + + // Create a string to be used with the thread-safe function. + NAPI_CALL(env, napi_create_string_utf8(env, + "N-API Thread-safe Function Deadlock Test", + NAPI_AUTO_LENGTH, + &async_name)); + + // Create the thread-safe function with a single queue slot and a single thread. + NAPI_CALL(env, napi_create_threadsafe_function(env, + NULL, + NULL, + async_name, + 1, + 1, + NULL, + NULL, + NULL, + DeadlockTestDummyMarshaller, + &tsfn)); + + // Call the threadsafe function. This should succeed and fill the queue. + NAPI_CALL(env, napi_call_threadsafe_function(tsfn, NULL, napi_tsfn_blocking)); + + // Call the threadsafe function. This should not block, but return + // `napi_would_deadlock`. We save the resulting status in an object to be + // returned. + status = napi_call_threadsafe_function(tsfn, NULL, napi_tsfn_blocking); + add_returned_status(env, + "deadlockTest", + return_value, + "Main thread would deadlock", + napi_would_deadlock, + status); + + // Clean up the thread-safe function before returning. + NAPI_CALL(env, napi_release_threadsafe_function(tsfn, napi_tsfn_release)); + + // Return the result. + return return_value; +} + // Module init static napi_value Init(napi_env env, napi_value exports) { size_t index; @@ -305,6 +359,7 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_PROPERTY("StopThread", StopThread), DECLARE_NAPI_PROPERTY("Unref", Unref), DECLARE_NAPI_PROPERTY("Release", Release), + DECLARE_NAPI_PROPERTY("TestDeadlock", TestDeadlock), }; NAPI_CALL(env, napi_define_properties(env, exports, diff --git a/test/node-api/test_threadsafe_function/binding.gyp b/test/node-api/test_threadsafe_function/binding.gyp index b60352e05af103..34587eed3dfb1f 100644 --- a/test/node-api/test_threadsafe_function/binding.gyp +++ b/test/node-api/test_threadsafe_function/binding.gyp @@ -2,7 +2,10 @@ 'targets': [ { 'target_name': 'binding', - 'sources': ['binding.c'] + 'sources': [ + 'binding.c', + '../../js-native-api/common.c' + ] } ] } diff --git a/test/node-api/test_threadsafe_function/test.js b/test/node-api/test_threadsafe_function/test.js index 3603d79ee6b5d3..f5afe225f07624 100644 --- a/test/node-api/test_threadsafe_function/test.js +++ b/test/node-api/test_threadsafe_function/test.js @@ -210,8 +210,13 @@ new Promise(function testWithoutJSMarshaller(resolve) { })) .then((result) => assert.strictEqual(result.indexOf(0), -1)) -// Start a child process to test rapid teardown +// Start a child process to test rapid teardown. .then(() => testUnref(binding.MAX_QUEUE_SIZE)) -// Start a child process with an infinite queue to test rapid teardown -.then(() => testUnref(0)); +// Start a child process with an infinite queue to test rapid teardown. +.then(() => testUnref(0)) + +// Test deadlock prevention. +.then(() => assert.deepStrictEqual(binding.TestDeadlock(), { + deadlockTest: 'Main thread would deadlock' +})); diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 9314874d3f9082..8703fea2b0b3a7 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -9,6 +9,8 @@ prefix parallel test-http2-reset-flood: PASS,FLAKY [$system==win32] +# https://github.com/nodejs/node/issues/32863 +test-child-process-fork-args: PASS,FLAKY # https://github.com/nodejs/node/issues/20750 test-http2-client-upload: PASS,FLAKY # https://github.com/nodejs/node/issues/20750 diff --git a/test/parallel/test-async-hooks-constructor.js b/test/parallel/test-async-hooks-constructor.js index f6f5c45607fc48..62ec854108e9dc 100644 --- a/test/parallel/test-async-hooks-constructor.js +++ b/test/parallel/test-async-hooks-constructor.js @@ -5,20 +5,17 @@ require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); -const non_function = 10; +const nonFunctionArray = [null, -1, 1, {}, []]; -typeErrorForFunction('init'); -typeErrorForFunction('before'); -typeErrorForFunction('after'); -typeErrorForFunction('destroy'); -typeErrorForFunction('promiseResolve'); - -function typeErrorForFunction(functionName) { - assert.throws(() => { - async_hooks.createHook({ [functionName]: non_function }); - }, { - code: 'ERR_ASYNC_CALLBACK', - name: 'TypeError', - message: `hook.${functionName} must be a function` +['init', 'before', 'after', 'destroy', 'promiseResolve'].forEach( + (functionName) => { + nonFunctionArray.forEach((nonFunction) => { + assert.throws(() => { + async_hooks.createHook({ [functionName]: nonFunction }); + }, { + code: 'ERR_ASYNC_CALLBACK', + name: 'TypeError', + message: `hook.${functionName} must be a function`, + }); + }); }); -} diff --git a/test/parallel/test-async-wrap-constructor.js b/test/parallel/test-async-wrap-constructor.js index 8e96e9ce3021ef..e89bc49df02333 100644 --- a/test/parallel/test-async-wrap-constructor.js +++ b/test/parallel/test-async-wrap-constructor.js @@ -6,14 +6,15 @@ require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); -for (const badArg of [0, 1, false, true, null, 'hello']) { +[0, 1, false, true, null, 'hello'].forEach((badArg) => { const hookNames = ['init', 'before', 'after', 'destroy', 'promiseResolve']; - for (const field of hookNames) { + hookNames.forEach((field) => { assert.throws(() => { async_hooks.createHook({ [field]: badArg }); }, { code: 'ERR_ASYNC_CALLBACK', name: 'TypeError', + message: `hook.${field} must be a function` }); - } -} + }); +}); diff --git a/test/parallel/test-event-capture-rejections.js b/test/parallel/test-event-capture-rejections.js index dbe5deeefade99..233b6b35d55072 100644 --- a/test/parallel/test-event-capture-rejections.js +++ b/test/parallel/test-event-capture-rejections.js @@ -278,14 +278,22 @@ function resetCaptureOnThrowInError() { function argValidation() { function testType(obj) { + const received = obj.constructor.name !== 'Number' ? + `an instance of ${obj.constructor.name}` : + `type number (${obj})`; + assert.throws(() => new EventEmitter({ captureRejections: obj }), { code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError' + name: 'TypeError', + message: 'The "options.captureRejections" property must be of type ' + + `boolean. Received ${received}` }); assert.throws(() => EventEmitter.captureRejections = obj, { code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError' + name: 'TypeError', + message: 'The "EventEmitter.captureRejections" property must be of ' + + `type boolean. Received ${received}` }); } diff --git a/test/parallel/test-event-emitter-add-listeners.js b/test/parallel/test-event-emitter-add-listeners.js index 4b0305c176bd14..f42d1f24878483 100644 --- a/test/parallel/test-event-emitter-add-listeners.js +++ b/test/parallel/test-event-emitter-add-listeners.js @@ -84,14 +84,3 @@ const EventEmitter = require('events'); // listeners were added. assert.deepStrictEqual(ee.listeners('hello'), [listen2, listen1]); } - -// Verify that the listener must be a function -assert.throws(() => { - const ee = new EventEmitter(); - ee.on('foo', null); -}, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "listener" argument must be of type function. ' + - 'Received null' -}); diff --git a/test/parallel/test-event-emitter-invalid-listener.js b/test/parallel/test-event-emitter-invalid-listener.js new file mode 100644 index 00000000000000..3070d4ed7517de --- /dev/null +++ b/test/parallel/test-event-emitter-invalid-listener.js @@ -0,0 +1,20 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const eventsMethods = ['on', 'once', 'removeListener', 'prependOnceListener']; + +// Verify that the listener must be a function for events methods +for (const method of eventsMethods) { + assert.throws(() => { + const ee = new EventEmitter(); + ee[method]('foo', null); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "listener" argument must be of type function. ' + + 'Received null' + }, `event.${method}('foo', null) should throw the proper error`); +} diff --git a/test/parallel/test-event-emitter-once.js b/test/parallel/test-event-emitter-once.js index 1ad2de1da556bf..983f6141b9dc4c 100644 --- a/test/parallel/test-event-emitter-once.js +++ b/test/parallel/test-event-emitter-once.js @@ -49,17 +49,6 @@ e.once('e', common.mustCall()); e.emit('e'); -// Verify that the listener must be a function -assert.throws(() => { - const ee = new EventEmitter(); - ee.once('foo', null); -}, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "listener" argument must be of type function. ' + - 'Received null' -}); - { // once() has different code paths based on the number of arguments being // emitted. Verify that all of the cases are covered. diff --git a/test/parallel/test-event-emitter-prepend.js b/test/parallel/test-event-emitter-prepend.js index c65b6b8f780f5c..ffe8544911365c 100644 --- a/test/parallel/test-event-emitter-prepend.js +++ b/test/parallel/test-event-emitter-prepend.js @@ -18,17 +18,6 @@ myEE.prependOnceListener('foo', myEE.emit('foo'); -// Verify that the listener must be a function -assert.throws(() => { - const ee = new EventEmitter(); - ee.prependOnceListener('foo', null); -}, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "listener" argument must be of type function. ' + - 'Received null' -}); - // Test fallback if prependListener is undefined. const stream = require('stream'); diff --git a/test/parallel/test-event-emitter-remove-listeners.js b/test/parallel/test-event-emitter-remove-listeners.js index 91e1f071046ac1..f37d26eb258c23 100644 --- a/test/parallel/test-event-emitter-remove-listeners.js +++ b/test/parallel/test-event-emitter-remove-listeners.js @@ -144,17 +144,6 @@ function listener2() {} assert.deepStrictEqual(ee, ee.removeListener('foo', () => {})); } -// Verify that the removed listener must be a function -assert.throws(() => { - const ee = new EventEmitter(); - ee.removeListener('foo', null); -}, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "listener" argument must be of type function. ' + - 'Received null' -}); - { const ee = new EventEmitter(); const listener = () => {}; diff --git a/test/parallel/test-fs-read-type.js b/test/parallel/test-fs-read-type.js index dbe036794ceb56..0f9bdbab588661 100644 --- a/test/parallel/test-fs-read-type.js +++ b/test/parallel/test-fs-read-type.js @@ -44,7 +44,7 @@ assert.throws(() => { }, { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', - message: 'The value of "offset" is out of range. It must be >= 0 && <= 4. ' + + message: 'The value of "offset" is out of range. It must be >= 0. ' + 'Received -1' }); @@ -73,7 +73,7 @@ assert.throws(() => { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "length" is out of range. ' + - 'It must be >= 0 && <= 4. Received -1' + 'It must be >= 0. Received -1' }); @@ -110,7 +110,7 @@ assert.throws(() => { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - 'It must be >= 0 && <= 4. Received -1' + 'It must be >= 0. Received -1' }); assert.throws(() => { @@ -136,5 +136,18 @@ assert.throws(() => { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "length" is out of range. ' + - 'It must be >= 0 && <= 4. Received -1' + 'It must be >= 0. Received -1' +}); + +assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length + 1, + 0); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + 'It must be <= 4. Received 5' }); diff --git a/test/parallel/test-http2-getpackedsettings.js b/test/parallel/test-http2-getpackedsettings.js index 4aa5747a053bd1..a54ab4499e1f89 100644 --- a/test/parallel/test-http2-getpackedsettings.js +++ b/test/parallel/test-http2-getpackedsettings.js @@ -7,11 +7,11 @@ const assert = require('assert'); const http2 = require('http2'); const check = Buffer.from([0x00, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x05, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x05, 0x00, 0x00, 0x40, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); const val = http2.getPackedSettings(http2.getDefaultSettings()); assert.deepStrictEqual(val, check); @@ -83,12 +83,13 @@ http2.getPackedSettings({ enablePush: false }); { const check = Buffer.from([ 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, - 0x00, 0x05, 0x00, 0x00, 0x4e, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x05, 0x00, 0x00, 0x4e, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 + ]); const packed = http2.getPackedSettings({ headerTableSize: 100, diff --git a/test/parallel/test-https-hwm.js b/test/parallel/test-https-hwm.js new file mode 100644 index 00000000000000..71ee33b7086861 --- /dev/null +++ b/test/parallel/test-https-hwm.js @@ -0,0 +1,66 @@ +'use strict'; + +// Test https highWaterMark + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const https = require('https'); +const fixtures = require('../common/fixtures'); + +let counter = 0; + +function loadCallback(highWaterMark) { + return common.mustCall(function(res) { + assert.strictEqual(highWaterMark, res.readableHighWaterMark); + counter--; + console.log('back from https request. ', + `highWaterMark = ${res.readableHighWaterMark}`); + if (counter === 0) { + httpsServer.close(); + console.log('ok'); + } + res.resume(); + }); +} + +// create server +const httpsServer = https.createServer({ + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') +}, common.mustCall(function(req, res) { + res.writeHead(200, {}); + res.end('ok'); +}, 3)).listen(0, common.mustCall(function(err) { + console.log(`test https server listening on port ${this.address().port}`); + assert.ifError(err); + + https.request({ + method: 'GET', + path: `/${counter++}`, + host: 'localhost', + port: this.address().port, + rejectUnauthorized: false, + highWaterMark: 128000, + }, loadCallback(128000)).on('error', common.mustNotCall()).end(); + + https.request({ + method: 'GET', + path: `/${counter++}`, + host: 'localhost', + port: this.address().port, + rejectUnauthorized: false, + highWaterMark: 0, + }, loadCallback(0)).on('error', common.mustNotCall()).end(); + + https.request({ + method: 'GET', + path: `/${counter++}`, + host: 'localhost', + port: this.address().port, + rejectUnauthorized: false, + highWaterMark: undefined, + }, loadCallback(16 * 1024)).on('error', common.mustNotCall()).end(); +})); diff --git a/test/parallel/test-icu-stringwidth.js b/test/parallel/test-icu-stringwidth.js index 66d75c4cbe2cb2..4e8389961d0d6d 100644 --- a/test/parallel/test-icu-stringwidth.js +++ b/test/parallel/test-icu-stringwidth.js @@ -87,3 +87,12 @@ for (let i = 0; i < 256; i++) { assert.strictEqual(getStringWidth(char), 1); } } + +{ + const a = '한글'.normalize('NFD'); // 한글 + const b = '한글'.normalize('NFC'); // 한글 + assert.strictEqual(a.length, 6); + assert.strictEqual(b.length, 2); + assert.strictEqual(getStringWidth(a), 4); + assert.strictEqual(getStringWidth(b), 4); +} diff --git a/test/parallel/test-module-circular-dependency-warning.js b/test/parallel/test-module-circular-dependency-warning.js index 10893978829ff5..1fe82c2b0288d5 100644 --- a/test/parallel/test-module-circular-dependency-warning.js +++ b/test/parallel/test-module-circular-dependency-warning.js @@ -31,3 +31,10 @@ assert.strictEqual(Object.getPrototypeOf(classExport).name, 'Parent'); const esmTranspiledExport = require(fixtures.path('cycles', 'warning-esm-transpiled-a.js')); assert.strictEqual(esmTranspiledExport.__esModule, true); + +// If module.exports.__esModule is being accessed but is not present, e.g. +// because only the one of the files is a transpiled ES module, no warning +// should be emitted. +const halfTranspiledExport = + require(fixtures.path('cycles', 'warning-esm-half-transpiled-a.js')); +assert.strictEqual(halfTranspiledExport.__esModule, undefined); diff --git a/test/parallel/test-net-after-close.js b/test/parallel/test-net-after-close.js index 641e61bd04c5d0..7d49780d001d6e 100644 --- a/test/parallel/test-net-after-close.js +++ b/test/parallel/test-net-after-close.js @@ -24,14 +24,14 @@ const common = require('../common'); const assert = require('assert'); const net = require('net'); -const server = net.createServer(common.mustCall(function(s) { +const server = net.createServer(common.mustCall((s) => { console.error('SERVER: got connection'); s.end(); })); -server.listen(0, common.mustCall(function() { - const c = net.createConnection(this.address().port); - c.on('close', common.mustCall(function() { +server.listen(0, common.mustCall(() => { + const c = net.createConnection(server.address().port); + c.on('close', common.mustCall(() => { console.error('connection closed'); assert.strictEqual(c._handle, null); // Calling functions / accessing properties of a closed socket should not diff --git a/test/parallel/test-process-env.js b/test/parallel/test-process-env.js index 0e06306634c3e2..4ece826e8b938f 100644 --- a/test/parallel/test-process-env.js +++ b/test/parallel/test-process-env.js @@ -106,3 +106,11 @@ if (common.isWindows) { const keys = Object.keys(process.env); assert.ok(keys.length > 0); } + +// Setting environment variables on Windows with empty names should not cause +// an assertion failure. +// https://github.com/nodejs/node/issues/32920 +{ + process.env[''] = ''; + assert.strictEqual(process.env[''], undefined); +} diff --git a/test/parallel/test-readable-from-iterator-closing.js b/test/parallel/test-readable-from-iterator-closing.js new file mode 100644 index 00000000000000..0254ccfc163093 --- /dev/null +++ b/test/parallel/test-readable-from-iterator-closing.js @@ -0,0 +1,198 @@ +'use strict'; + +const { mustCall, mustNotCall } = require('../common'); +const { Readable } = require('stream'); +const { strictEqual } = require('assert'); + +async function asyncSupport() { + const finallyMustCall = mustCall(); + const bodyMustCall = mustCall(); + + async function* infiniteGenerate() { + try { + while (true) yield 'a'; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncSupport() { + const finallyMustCall = mustCall(); + const bodyMustCall = mustCall(); + + function* infiniteGenerate() { + try { + while (true) yield 'a'; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncPromiseSupport() { + const returnMustBeAwaited = mustCall(); + const bodyMustCall = mustCall(); + + function* infiniteGenerate() { + try { + while (true) yield Promise.resolve('a'); + } finally { + // eslint-disable-next-line no-unsafe-finally + return { then(cb) { + returnMustBeAwaited(); + cb(); + } }; + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncRejectedSupport() { + const returnMustBeAwaited = mustCall(); + const bodyMustNotCall = mustNotCall(); + const catchMustCall = mustCall(); + const secondNextMustNotCall = mustNotCall(); + + function* generate() { + try { + yield Promise.reject('a'); + secondNextMustNotCall(); + } finally { + // eslint-disable-next-line no-unsafe-finally + return { then(cb) { + returnMustBeAwaited(); + cb(); + } }; + } + } + + const stream = Readable.from(generate()); + + try { + for await (const chunk of stream) { + bodyMustNotCall(chunk); + } + } catch { + catchMustCall(); + } +} + +async function noReturnAfterThrow() { + const returnMustNotCall = mustNotCall(); + const bodyMustNotCall = mustNotCall(); + const catchMustCall = mustCall(); + const nextMustCall = mustCall(); + + const stream = Readable.from({ + [Symbol.asyncIterator]() { return this; }, + async next() { + nextMustCall(); + throw new Error('a'); + }, + async return() { + returnMustNotCall(); + return { done: true }; + }, + }); + + try { + for await (const chunk of stream) { + bodyMustNotCall(chunk); + } + } catch { + catchMustCall(); + } +} + +async function closeStreamWhileNextIsPending() { + const finallyMustCall = mustCall(); + const dataMustCall = mustCall(); + + let resolveDestroy; + const destroyed = + new Promise((resolve) => { resolveDestroy = mustCall(resolve); }); + let resolveYielded; + const yielded = + new Promise((resolve) => { resolveYielded = mustCall(resolve); }); + + async function* infiniteGenerate() { + try { + while (true) { + yield 'a'; + resolveYielded(); + await destroyed; + } + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + stream.on('data', (data) => { + dataMustCall(); + strictEqual(data, 'a'); + }); + + yielded.then(() => { + stream.destroy(); + resolveDestroy(); + }); +} + +async function closeAfterNullYielded() { + const finallyMustCall = mustCall(); + const dataMustCall = mustCall(3); + + function* infiniteGenerate() { + try { + yield 'a'; + yield 'a'; + yield 'a'; + while (true) yield null; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + stream.on('data', (chunk) => { + dataMustCall(); + strictEqual(chunk, 'a'); + }); +} + +Promise.all([ + asyncSupport(), + syncSupport(), + syncPromiseSupport(), + syncRejectedSupport(), + noReturnAfterThrow(), + closeStreamWhileNextIsPending(), + closeAfterNullYielded(), +]).then(mustCall()); diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index 0dca3391961a93..fdbe3cd21145ee 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -36,7 +36,11 @@ class TestStream extends stream.Transform { } } -const s1 = new stream.PassThrough(); +const s1 = new stream.Transform({ + transform(chunk, encoding, cb) { + process.nextTick(cb, null, chunk); + } +}); const s2 = new stream.PassThrough(); const s3 = new TestStream(); s1.pipe(s3); diff --git a/test/parallel/test-stream-catch-rejections.js b/test/parallel/test-stream-catch-rejections.js index 848c2ada130e64..81427c35757ca8 100644 --- a/test/parallel/test-stream-catch-rejections.js +++ b/test/parallel/test-stream-catch-rejections.js @@ -30,7 +30,7 @@ const assert = require('assert'); captureRejections: true, highWaterMark: 1, write(chunk, enc, cb) { - cb(); + process.nextTick(cb); } }); diff --git a/test/parallel/test-stream-duplex-destroy.js b/test/parallel/test-stream-duplex-destroy.js index e7c91ec797beb3..c7d294e144bb5e 100644 --- a/test/parallel/test-stream-duplex-destroy.js +++ b/test/parallel/test-stream-duplex-destroy.js @@ -124,7 +124,7 @@ const assert = require('assert'); duplex.removeListener('end', fail); duplex.removeListener('finish', fail); - duplex.on('end', common.mustCall()); + duplex.on('end', common.mustNotCall()); duplex.on('finish', common.mustCall()); assert.strictEqual(duplex.destroyed, true); } diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index ab35d402e31cfd..d4336e84db35d6 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common'); -const { Writable, Readable, Transform, finished } = require('stream'); +const { Writable, Readable, Transform, finished, Duplex } = require('stream'); const assert = require('assert'); const EE = require('events'); const fs = require('fs'); @@ -352,3 +352,47 @@ testClosed((opts) => new Writable({ write() {}, ...opts })); r.push(null); r.destroy(); } + +{ + const d = new Duplex({ + final(cb) { }, // Never close writable side for test purpose + read() { + this.push(null); + } + }); + + d.on('end', common.mustCall()); + + finished(d, { readable: true, writable: false }, common.mustCall()); + + d.end(); + d.resume(); +} + +{ + const d = new Duplex({ + final(cb) { }, // Never close writable side for test purpose + read() { + this.push(null); + } + }); + + d.on('end', common.mustCall()); + + d.end(); + finished(d, { readable: true, writable: false }, common.mustCall()); + + d.resume(); +} + +{ + // Test for compat for e.g. fd-slicer which implements + // non standard destroy behavior which might not emit + // 'close'. + const r = new Readable(); + finished(r, common.mustCall()); + r.resume(); + r.push('asd'); + r.destroyed = true; + r.push(null); +} diff --git a/test/parallel/test-stream-pipe-await-drain-push-while-write.js b/test/parallel/test-stream-pipe-await-drain-push-while-write.js index 6dbf3c669bc177..a717291cda2b03 100644 --- a/test/parallel/test-stream-pipe-await-drain-push-while-write.js +++ b/test/parallel/test-stream-pipe-await-drain-push-while-write.js @@ -19,7 +19,7 @@ const writable = new stream.Writable({ }); } - cb(); + process.nextTick(cb); }, 3) }); diff --git a/test/parallel/test-stream-pipe-await-drain.js b/test/parallel/test-stream-pipe-await-drain.js index 3ae248e08b854f..90d418a09783e3 100644 --- a/test/parallel/test-stream-pipe-await-drain.js +++ b/test/parallel/test-stream-pipe-await-drain.js @@ -19,7 +19,7 @@ reader._read = () => {}; writer1._write = common.mustCall(function(chunk, encoding, cb) { this.emit('chunk-received'); - cb(); + process.nextTick(cb); }, 1); writer1.once('chunk-received', () => { @@ -42,7 +42,7 @@ writer2._write = common.mustCall((chunk, encoding, cb) => { reader._readableState.awaitDrainWriters.size, 1, 'awaitDrain should be 1 after first push, actual is ' + - reader._readableState.awaitDrainWriters + reader._readableState.awaitDrainWriters.size ); // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call @@ -54,7 +54,7 @@ writer3._write = common.mustCall((chunk, encoding, cb) => { reader._readableState.awaitDrainWriters.size, 2, 'awaitDrain should be 2 after second push, actual is ' + - reader._readableState.awaitDrainWriters + reader._readableState.awaitDrainWriters.size ); // Not calling cb here to "simulate" slow stream. // This should be called exactly once, since the first .write() call diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index b273fddfa3b613..203a32b5cd74a1 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -13,6 +13,7 @@ const { const assert = require('assert'); const http = require('http'); const { promisify } = require('util'); +const net = require('net'); { let finished = false; @@ -916,7 +917,7 @@ const { promisify } = require('util'); const src = new PassThrough({ autoDestroy: false }); const dst = new PassThrough({ autoDestroy: false }); pipeline(src, dst, common.mustCall(() => { - assert.strictEqual(src.destroyed, true); + assert.strictEqual(src.destroyed, false); assert.strictEqual(dst.destroyed, false); })); src.end(); @@ -981,7 +982,7 @@ const { promisify } = require('util'); dst.readable = false; pipeline(src, dst, common.mustCall((err) => { assert(!err); - assert.strictEqual(dst.destroyed, true); + assert.strictEqual(dst.destroyed, false); })); src.end(); } @@ -1118,3 +1119,95 @@ const { promisify } = require('util'); assert.strictEqual(closed, true); })); } + +{ + const server = net.createServer(common.mustCall((socket) => { + // echo server + pipeline(socket, socket, common.mustCall()); + // 13 force destroys the socket before it has a chance to emit finish + socket.on('finish', common.mustCall(() => { + server.close(); + })); + })).listen(0, common.mustCall(() => { + const socket = net.connect(server.address().port); + socket.end(); + })); +} + +{ + const d = new Duplex({ + autoDestroy: false, + write: common.mustCall((data, enc, cb) => { + d.push(data); + cb(); + }), + read: common.mustCall(() => { + d.push(null); + }), + final: common.mustCall((cb) => { + setTimeout(() => { + assert.strictEqual(d.destroyed, false); + cb(); + }, 1000); + }), + destroy: common.mustNotCall() + }); + + const sink = new Writable({ + write: common.mustCall((data, enc, cb) => { + cb(); + }) + }); + + pipeline(d, sink, common.mustCall()); + + d.write('test'); + d.end(); +} + +{ + const server = net.createServer(common.mustCall((socket) => { + // echo server + pipeline(socket, socket, common.mustCall()); + socket.on('finish', common.mustCall(() => { + server.close(); + })); + })).listen(0, common.mustCall(() => { + const socket = net.connect(server.address().port); + socket.end(); + })); +} + +{ + const d = new Duplex({ + autoDestroy: false, + write: common.mustCall((data, enc, cb) => { + d.push(data); + cb(); + }), + read: common.mustCall(() => { + d.push(null); + }), + final: common.mustCall((cb) => { + setTimeout(() => { + assert.strictEqual(d.destroyed, false); + cb(); + }, 1000); + }), + // `destroy()` won't be invoked by pipeline since + // the writable side has not completed when + // the pipeline has completed. + destroy: common.mustNotCall() + }); + + const sink = new Writable({ + write: common.mustCall((data, enc, cb) => { + cb(); + }) + }); + + pipeline(d, sink, common.mustCall()); + + d.write('test'); + d.end(); +} diff --git a/test/parallel/test-stream-readable-destroy.js b/test/parallel/test-stream-readable-destroy.js index 6caf88a1f151e8..3d1ac8c92f9bd3 100644 --- a/test/parallel/test-stream-readable-destroy.js +++ b/test/parallel/test-stream-readable-destroy.js @@ -113,7 +113,7 @@ const assert = require('assert'); read.destroy(); read.removeListener('end', fail); - read.on('end', common.mustCall()); + read.on('end', common.mustNotCall()); assert.strictEqual(read.destroyed, true); } diff --git a/test/parallel/test-stream-readable-end-destroyed.js b/test/parallel/test-stream-readable-end-destroyed.js new file mode 100644 index 00000000000000..4b60bf4614770a --- /dev/null +++ b/test/parallel/test-stream-readable-end-destroyed.js @@ -0,0 +1,17 @@ +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); + +{ + // Don't emit 'end' after 'close'. + + const r = new Readable(); + + r.on('end', common.mustNotCall()); + r.resume(); + r.destroy(); + r.on('close', common.mustCall(() => { + r.push(null); + })); +} diff --git a/test/parallel/test-stream-writable-needdrain-state.js b/test/parallel/test-stream-writable-needdrain-state.js index ea5617d997d5ed..0e72d832bc3ff0 100644 --- a/test/parallel/test-stream-writable-needdrain-state.js +++ b/test/parallel/test-stream-writable-needdrain-state.js @@ -10,8 +10,10 @@ const transform = new stream.Transform({ }); function _transform(chunk, encoding, cb) { - assert.strictEqual(transform._writableState.needDrain, true); - cb(); + process.nextTick(() => { + assert.strictEqual(transform._writableState.needDrain, true); + cb(); + }); } assert.strictEqual(transform._writableState.needDrain, false); diff --git a/test/parallel/test-stream2-finish-pipe.js b/test/parallel/test-stream2-finish-pipe.js index 1cee74063233b2..5e2969aad4f259 100644 --- a/test/parallel/test-stream2-finish-pipe.js +++ b/test/parallel/test-stream2-finish-pipe.js @@ -30,7 +30,7 @@ r._read = function(size) { const w = new stream.Writable(); w._write = function(data, encoding, cb) { - cb(null); + process.nextTick(cb, null); }; r.pipe(w); diff --git a/test/parallel/test-tls-connect-hwm-option.js b/test/parallel/test-tls-connect-hwm-option.js new file mode 100644 index 00000000000000..e016ccc6cba0dc --- /dev/null +++ b/test/parallel/test-tls-connect-hwm-option.js @@ -0,0 +1,53 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +const pem = (n) => fixtures.readKey(`${n}.pem`); + +let clients = 0; + +const server = tls.createServer({ + key: pem('agent1-key'), + cert: pem('agent1-cert') +}, common.mustCall(() => { + if (--clients === 0) + server.close(); +}, 3)); + +server.listen(0, common.mustCall(() => { + clients++; + const highBob = tls.connect({ + port: server.address().port, + rejectUnauthorized: false, + highWaterMark: 128000, + }, common.mustCall(() => { + assert.strictEqual(highBob.readableHighWaterMark, 128000); + highBob.end(); + })); + + clients++; + const defaultHighBob = tls.connect({ + port: server.address().port, + rejectUnauthorized: false, + highWaterMark: undefined, + }, common.mustCall(() => { + assert.strictEqual(defaultHighBob.readableHighWaterMark, 16 * 1024); + defaultHighBob.end(); + })); + + clients++; + const zeroHighBob = tls.connect({ + port: server.address().port, + rejectUnauthorized: false, + highWaterMark: 0, + }, common.mustCall(() => { + assert.strictEqual(zeroHighBob.readableHighWaterMark, 0); + zeroHighBob.end(); + })); +})); diff --git a/test/parallel/test-vm-module-basic.js b/test/parallel/test-vm-module-basic.js index 86e13f8b12bfa8..155524f7e7a176 100644 --- a/test/parallel/test-vm-module-basic.js +++ b/test/parallel/test-vm-module-basic.js @@ -8,7 +8,8 @@ const { Module, SourceTextModule, SyntheticModule, - createContext + createContext, + compileFunction, } = require('vm'); const util = require('util'); @@ -147,3 +148,19 @@ const util = require('util'); name: 'TypeError' }); } + +// Test compileFunction importModuleDynamically +{ + const module = new SyntheticModule([], () => {}); + module.link(() => {}); + const f = compileFunction('return import("x")', [], { + importModuleDynamically(specifier, referrer) { + assert.strictEqual(specifier, 'x'); + assert.strictEqual(referrer, f); + return module; + }, + }); + f().then((ns) => { + assert.strictEqual(ns, module.namespace); + }); +} diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status index f73b428de5f390..fce8bd959f0326 100644 --- a/test/sequential/sequential.status +++ b/test/sequential/sequential.status @@ -17,8 +17,6 @@ test-worker-prof: PASS, FLAKY [$system==linux] [$system==macos] -# https://github.com/nodejs/node/issues/21781 -test-timers-blocking-callback: PASS, FLAKY [$system==solaris] # Also applies to SmartOS diff --git a/test/sequential/test-timers-blocking-callback.js b/test/sequential/test-timers-blocking-callback.js deleted file mode 100644 index a5e0f596a34b93..00000000000000 --- a/test/sequential/test-timers-blocking-callback.js +++ /dev/null @@ -1,114 +0,0 @@ -// Flags: --expose-internals -'use strict'; - -/* - * This is a regression test for - * https://github.com/nodejs/node-v0.x-archive/issues/15447 and - * https://github.com/nodejs/node-v0.x-archive/issues/9333. - * - * When a timer is added in another timer's callback, its underlying timer - * handle was started with a timeout that was actually incorrect. - * - * The reason was that the value that represents the current time was not - * updated between the time the original callback was called and the time - * the added timer was processed by timers.listOnTimeout. That led the - * logic in timers.listOnTimeout to do an incorrect computation that made - * the added timer fire with a timeout of scheduledTimeout + - * timeSpentInCallback. - * - * This test makes sure that a timer added by another timer's callback - * fires with the expected timeout. - * - * It makes sure that it works when the timers list for a given timeout is - * empty (see testAddingTimerToEmptyTimersList) and when the timers list - * is not empty (see testAddingTimerToNonEmptyTimersList). - */ - -const common = require('../common'); -const assert = require('assert'); -const { sleep } = require('internal/util'); - -const TIMEOUT = 100; - -let nbBlockingCallbackCalls; -let latestDelay; -let timeCallbackScheduled; - -// These tests are timing dependent so they may fail even when the bug is -// not present (if the host is sufficiently busy that the timers are delayed -// significantly). However, they fail 100% of the time when the bug *is* -// present, so to increase reliability, allow for a small number of retries. -let retries = 2; - -function initTest() { - nbBlockingCallbackCalls = 0; - latestDelay = 0; - timeCallbackScheduled = 0; -} - -function blockingCallback(retry, callback) { - ++nbBlockingCallbackCalls; - - if (nbBlockingCallbackCalls > 1) { - latestDelay = Date.now() - timeCallbackScheduled; - // Even if timers can fire later than when they've been scheduled - // to fire, they shouldn't generally be more than 100% late in this case. - // But they are guaranteed to be at least 100ms late given the bug in - // https://github.com/nodejs/node-v0.x-archive/issues/15447 and - // https://github.com/nodejs/node-v0.x-archive/issues/9333. - if (latestDelay >= TIMEOUT * 2) { - if (retries > 0) { - retries--; - return retry(callback); - } - assert.fail(`timeout delayed by more than 100% (${latestDelay}ms)`); - } - if (callback) - return callback(); - } else { - // Block by busy-looping to trigger the issue - sleep(TIMEOUT); - - timeCallbackScheduled = Date.now(); - setTimeout(blockingCallback.bind(null, retry, callback), TIMEOUT); - } -} - -function testAddingTimerToEmptyTimersList(callback) { - initTest(); - // Call setTimeout just once to make sure the timers list is - // empty when blockingCallback is called. - setTimeout( - blockingCallback.bind(null, testAddingTimerToEmptyTimersList, callback), - TIMEOUT - ); -} - -function testAddingTimerToNonEmptyTimersList() { - // If both timers fail and attempt a retry, only actually do anything for one - // of them. - let retryOK = true; - const retry = () => { - if (retryOK) - testAddingTimerToNonEmptyTimersList(); - retryOK = false; - }; - - initTest(); - // Call setTimeout twice with the same timeout to make - // sure the timers list is not empty when blockingCallback is called. - setTimeout( - blockingCallback.bind(null, retry), - TIMEOUT - ); - setTimeout( - blockingCallback.bind(null, retry), - TIMEOUT - ); -} - -// Run the test for the empty timers list case, and then for the non-empty -// timers list one. -testAddingTimerToEmptyTimersList( - common.mustCall(testAddingTimerToNonEmptyTimersList) -); diff --git a/tools/code_cache/mkcodecache.cc b/tools/code_cache/mkcodecache.cc index 34af7bc61ba374..23df0f69317b8b 100644 --- a/tools/code_cache/mkcodecache.cc +++ b/tools/code_cache/mkcodecache.cc @@ -49,8 +49,8 @@ int main(int argc, char* argv[]) { // Create a new Isolate and make it the current one. Isolate::CreateParams create_params; - create_params.array_buffer_allocator = - ArrayBuffer::Allocator::NewDefaultAllocator(); + create_params.array_buffer_allocator_shared.reset( + ArrayBuffer::Allocator::NewDefaultAllocator()); Isolate* isolate = Isolate::New(create_params); { Isolate::Scope isolate_scope(isolate); @@ -65,6 +65,7 @@ int main(int argc, char* argv[]) { out << cache; out.close(); } + isolate->Dispose(); v8::V8::ShutdownPlatform(); return 0; diff --git a/tools/doc/html.js b/tools/doc/html.js index acd62c3e8d0ddb..b58563045def8d 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -313,23 +313,11 @@ function versionSort(a, b) { function buildToc({ filename, apilinks }) { return (tree, file) => { - const startIncludeRefRE = /^\s*\s*$/; - const endIncludeRefRE = /^\s*\s*$/; - const realFilenames = [filename]; const idCounters = Object.create(null); let toc = ''; let depth = 0; visit(tree, null, (node) => { - // Keep track of the current filename for comment wrappers of inclusions. - if (node.type === 'html') { - const [, includedFileName] = node.value.match(startIncludeRefRE) || []; - if (includedFileName !== undefined) - realFilenames.unshift(includedFileName); - else if (endIncludeRefRE.test(node.value)) - realFilenames.shift(); - } - if (node.type !== 'heading') return; if (node.depth - depth > 1) { @@ -339,7 +327,7 @@ function buildToc({ filename, apilinks }) { } depth = node.depth; - const realFilename = path.basename(realFilenames[0], '.md'); + const realFilename = path.basename(filename, '.md'); const headingText = file.contents.slice( node.children[0].position.start.offset, node.position.end.offset).trim(); diff --git a/tools/doc/type-parser.js b/tools/doc/type-parser.js index 02b59d37ffd278..b244564d8f8ebf 100644 --- a/tools/doc/type-parser.js +++ b/tools/doc/type-parser.js @@ -148,6 +148,7 @@ const customTypesMap = { 'URLSearchParams': 'url.html#url_class_urlsearchparams', 'vm.Module': 'vm.html#vm_class_vm_module', + 'vm.Script': 'vm.html#vm_class_vm_script', 'vm.SourceTextModule': 'vm.html#vm_class_vm_sourcetextmodule', 'MessagePort': 'worker_threads.html#worker_threads_class_messageport', diff --git a/tools/icu/README.md b/tools/icu/README.md index 01b0178c454a8b..e59f28b71801b7 100644 --- a/tools/icu/README.md +++ b/tools/icu/README.md @@ -21,7 +21,7 @@ Note: > The files in this directory were written for the Node.js v0.12 effort. > The original intent was to merge the tools such as `icutrim.py` and `iculslocs.cc` > back into ICU. ICU has gained its own “data slicer” tool. -> There is an issue open, https://github.com/nodejs/node/issues/25136 +> There is an issue open, > for replacing `icutrim.py` with the [ICU data slicer][]. ## See Also diff --git a/tools/node_modules/eslint/README.md b/tools/node_modules/eslint/README.md index da75b5c149d799..0a802b0c25d0ca 100644 --- a/tools/node_modules/eslint/README.md +++ b/tools/node_modules/eslint/README.md @@ -214,6 +214,11 @@ The people who review and implement new features.
薛定谔的猫 +
+ +
+Milos Djermanovic +
@@ -233,11 +238,6 @@ Pig Fang
YeonJuan - - -
-Milos Djermanovic -
@@ -250,9 +250,9 @@ The following companies, organizations, and individuals support ESLint's ongoing

Gold Sponsors

-

Shopify Salesforce MagicLab Airbnb

Silver Sponsors

+

Shopify Salesforce Airbnb

Silver Sponsors

AMP Project

Bronze Sponsors

-

Kasinot.fi Pelisivut Nettikasinot.org BonusFinder Deutschland Top Web Design Agencies Bugsnag Stability Monitoring Mixpanel VPS Server Free Icons by Icons8 UI UX Design Agencies clay Discord ThemeIsle TekHattan Marfeel Fire Stick Tricks

+

CasinoTop.com Casino Topp Writers Per Hour Anagram Solver vpn netflix Kasinot.fi Pelisivut Nettikasinot.org BonusFinder Deutschland Top Web Design Agencies Bugsnag Stability Monitoring Mixpanel VPS Server Free Icons by Icons8 UI UX Design Agencies clay Discord ThemeIsle TekHattan Marfeel Fire Stick Tricks

## Technology Sponsors diff --git a/tools/node_modules/eslint/bin/eslint.js b/tools/node_modules/eslint/bin/eslint.js index a9f51f1d7d4c57..75b413148695e5 100755 --- a/tools/node_modules/eslint/bin/eslint.js +++ b/tools/node_modules/eslint/bin/eslint.js @@ -12,97 +12,135 @@ // to use V8's code cache to speed up instantiation time require("v8-compile-cache"); -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const useStdIn = process.argv.includes("--stdin"), - init = process.argv.includes("--init"), - debug = process.argv.includes("--debug"); - // must do this initialization *before* other requires in order to work -if (debug) { +if (process.argv.includes("--debug")) { require("debug").enable("eslint:*,-eslint:code-path"); } //------------------------------------------------------------------------------ -// Requirements +// Helpers //------------------------------------------------------------------------------ -// now we can safely include the other modules that use debug -const path = require("path"), - fs = require("fs"), - cli = require("../lib/cli"); - -//------------------------------------------------------------------------------ -// Execution -//------------------------------------------------------------------------------ +/** + * Read data from stdin til the end. + * + * Note: See + * - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin + * - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io + * - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html + * - https://github.com/nodejs/node/issues/7439 (historical) + * + * On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems + * to read 4096 bytes before blocking and never drains to read further data. + * + * The investigation on the Emacs thread indicates: + * + * > Emacs on MS-Windows uses pipes to communicate with subprocesses; a + * > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than + * > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for + * > the subprocess to read its end of the pipe, at which time Emacs will + * > write the rest of the stuff. + * @returns {Promise} The read text. + */ +function readStdin() { + return new Promise((resolve, reject) => { + let content = ""; + let chunk = ""; + + process.stdin + .setEncoding("utf8") + .on("readable", () => { + while ((chunk = process.stdin.read()) !== null) { + content += chunk; + } + }) + .on("end", () => resolve(content)) + .on("error", reject); + }); +} -process.once("uncaughtException", err => { +/** + * Get the error message of a given value. + * @param {any} error The value to get. + * @returns {string} The error message. + */ +function getErrorMessage(error) { - // lazy load + // Lazy loading because those are used only if error happened. + const fs = require("fs"); + const path = require("path"); + const util = require("util"); const lodash = require("lodash"); - if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) { - const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8")); - const pkg = require("../package.json"); + // Foolproof -- thirdparty module might throw non-object. + if (typeof error !== "object" || error === null) { + return String(error); + } + + // Use templates if `error.messageTemplate` is present. + if (typeof error.messageTemplate === "string") { + try { + const templateFilePath = path.resolve( + __dirname, + `../messages/${error.messageTemplate}.txt` + ); + + // Use sync API because Node.js should exit at this tick. + const templateText = fs.readFileSync(templateFilePath, "utf-8"); + const template = lodash.template(templateText); + + return template(error.messageData || {}); + } catch { + + // Ignore template error then fallback to use `error.stack`. + } + } - console.error("\nOops! Something went wrong! :("); - console.error(`\nESLint: ${pkg.version}.\n\n${template(err.messageData || {})}`); - } else { - console.error(err.stack); + // Use the stacktrace if it's an error object. + if (typeof error.stack === "string") { + return error.stack; } + // Otherwise, dump the object. + return util.format("%o", error); +} + +/** + * Catch and report unexpected error. + * @param {any} error The thrown error object. + * @returns {void} + */ +function onFatalError(error) { process.exitCode = 2; -}); - -if (useStdIn) { - - /* - * Note: See - * - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin - * - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io - * - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html - * - https://github.com/nodejs/node/issues/7439 (historical) - * - * On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems - * to read 4096 bytes before blocking and never drains to read further data. - * - * The investigation on the Emacs thread indicates: - * - * > Emacs on MS-Windows uses pipes to communicate with subprocesses; a - * > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than - * > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for - * > the subprocess to read its end of the pipe, at which time Emacs will - * > write the rest of the stuff. - * - * Using the nodejs code example for reading from stdin. - */ - let contents = "", - chunk = ""; - - process.stdin.setEncoding("utf8"); - process.stdin.on("readable", () => { - - // Use a loop to make sure we read all available data. - while ((chunk = process.stdin.read()) !== null) { - contents += chunk; - } - }); - process.stdin.on("end", () => { - process.exitCode = cli.execute(process.argv, contents, "utf8"); - }); -} else if (init) { - const configInit = require("../lib/init/config-initializer"); - - configInit.initializeConfig().then(() => { - process.exitCode = 0; - }).catch(err => { - process.exitCode = 1; - console.error(err.message); - console.error(err.stack); - }); -} else { - process.exitCode = cli.execute(process.argv); + const { version } = require("../package.json"); + const message = getErrorMessage(error); + + console.error(` +Oops! Something went wrong! :( + +ESLint: ${version} + +${message}`); } + +//------------------------------------------------------------------------------ +// Execution +//------------------------------------------------------------------------------ + +(async function main() { + process.on("uncaughtException", onFatalError); + process.on("unhandledRejection", onFatalError); + + // Call the config initializer if `--init` is present. + if (process.argv.includes("--init")) { + await require("../lib/init/config-initializer").initializeConfig(); + return; + } + + // Otherwise, call the CLI. + process.exitCode = await require("../lib/cli").execute( + process.argv, + process.argv.includes("--stdin") ? await readStdin() : null + ); +}()).catch(onFatalError); diff --git a/tools/node_modules/eslint/lib/api.js b/tools/node_modules/eslint/lib/api.js index 40a5cc9fa5ccd4..e4b6643b44780a 100644 --- a/tools/node_modules/eslint/lib/api.js +++ b/tools/node_modules/eslint/lib/api.js @@ -6,6 +6,7 @@ "use strict"; const { CLIEngine } = require("./cli-engine"); +const { ESLint } = require("./eslint"); const { Linter } = require("./linter"); const { RuleTester } = require("./rule-tester"); const { SourceCode } = require("./source-code"); @@ -13,6 +14,7 @@ const { SourceCode } = require("./source-code"); module.exports = { Linter, CLIEngine, + ESLint, RuleTester, SourceCode }; diff --git a/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js b/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js index b53f67bd9dce6c..f54605c4db991e 100644 --- a/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js +++ b/tools/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js @@ -279,6 +279,18 @@ class CascadingConfigArrayFactory { ); } + /** + * Set the config data to override all configs. + * Require to call `clearCache()` method after this method is called. + * @param {ConfigData} configData The config data to override all configs. + * @returns {void} + */ + setOverrideConfig(configData) { + const slots = internalSlotsMap.get(this); + + slots.cliConfigData = configData; + } + /** * Clear config cache. * @returns {void} diff --git a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js index 72d1fa4d5dcd5d..b6aa995beef933 100644 --- a/tools/node_modules/eslint/lib/cli-engine/cli-engine.js +++ b/tools/node_modules/eslint/lib/cli-engine/cli-engine.js @@ -39,6 +39,7 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]); // For VSCode IntelliSense /** @typedef {import("../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ /** @typedef {import("../shared/types").LintMessage} LintMessage */ /** @typedef {import("../shared/types").ParserOptions} ParserOptions */ /** @typedef {import("../shared/types").Plugin} Plugin */ @@ -50,29 +51,29 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]); /** * The options to configure a CLI engine with. * @typedef {Object} CLIEngineOptions - * @property {boolean} allowInlineConfig Enable or disable inline configuration comments. - * @property {ConfigData} baseConfig Base config object, extended by all configs used with this CLIEngine instance - * @property {boolean} cache Enable result caching. - * @property {string} cacheLocation The cache file to use instead of .eslintcache. - * @property {string} configFile The configuration file to use. - * @property {string} cwd The value to use for the current working directory. - * @property {string[]} envs An array of environments to load. - * @property {string[]|null} extensions An array of file extensions to check. - * @property {boolean|Function} fix Execute in autofix mode. If a function, should return a boolean. - * @property {string[]} fixTypes Array of rule types to apply fixes for. - * @property {string[]} globals An array of global variables to declare. - * @property {boolean} ignore False disables use of .eslintignore. - * @property {string} ignorePath The ignore file to use instead of .eslintignore. - * @property {string|string[]} ignorePattern One or more glob patterns to ignore. - * @property {boolean} useEslintrc False disables looking for .eslintrc - * @property {string} parser The name of the parser to use. - * @property {ParserOptions} parserOptions An object of parserOption settings to use. - * @property {string[]} plugins An array of plugins to load. - * @property {Record} rules An object of rules to use. - * @property {string[]} rulePaths An array of directories to load custom rules from. - * @property {boolean} reportUnusedDisableDirectives `true` adds reports for unused eslint-disable directives - * @property {boolean} globInputPaths Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {string} resolvePluginsRelativeTo The folder where plugins should be resolved from, defaulting to the CWD + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {string} [configFile] The configuration file to use. + * @property {string} [cwd] The value to use for the current working directory. + * @property {string[]} [envs] An array of environments to load. + * @property {string[]|null} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {string[]} [globals] An array of global variables to declare. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc + * @property {string} [parser] The name of the parser to use. + * @property {ParserOptions} [parserOptions] An object of parserOption settings to use. + * @property {string[]} [plugins] An array of plugins to load. + * @property {Record} [rules] An object of rules to use. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD */ /** @@ -88,13 +89,6 @@ const validFixTypes = new Set(["problem", "suggestion", "layout"]); * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. */ -/** - * Information of deprecated rules. - * @typedef {Object} DeprecatedRuleInfo - * @property {string} ruleId The rule ID. - * @property {string[]} replacedBy The rule IDs that replace this deprecated rule. - */ - /** * Linting results. * @typedef {Object} LintReport @@ -821,16 +815,22 @@ class CLIEngine { lintResultCache.reconcile(); } - // Collect used deprecated rules. - const usedDeprecatedRules = Array.from( - iterateRuleDeprecationWarnings(lastConfigArrays) - ); - debug(`Linting complete in: ${Date.now() - startTime}ms`); + let usedDeprecatedRules; + return { results, ...calculateStatsPerRun(results), - usedDeprecatedRules + + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from( + iterateRuleDeprecationWarnings(lastConfigArrays) + ); + } + return usedDeprecatedRules; + } }; } @@ -858,9 +858,9 @@ class CLIEngine { const startTime = Date.now(); const resolvedFilename = filename && path.resolve(cwd, filename); + // Clear the last used config arrays. lastConfigArrays.length = 0; - if (resolvedFilename && this.isPathIgnored(resolvedFilename)) { if (warnIgnored) { results.push(createIgnoreResult(resolvedFilename, cwd)); @@ -892,16 +892,22 @@ class CLIEngine { })); } - // Collect used deprecated rules. - const usedDeprecatedRules = Array.from( - iterateRuleDeprecationWarnings(lastConfigArrays) - ); - debug(`Linting complete in: ${Date.now() - startTime}ms`); + let usedDeprecatedRules; + return { results, ...calculateStatsPerRun(results), - usedDeprecatedRules + + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from( + iterateRuleDeprecationWarnings(lastConfigArrays) + ); + } + return usedDeprecatedRules; + } }; } @@ -955,11 +961,10 @@ class CLIEngine { } /** - * Returns the formatter representing the given format or null if no formatter - * with the given name can be found. + * Returns the formatter representing the given format or null if the `format` is not a string. * @param {string} [format] The name of the format to load or the path to a * custom formatter. - * @returns {Function} The formatter function or null if not found. + * @returns {(Function|null)} The formatter function or null if the `format` is not a string. */ getFormatter(format) { diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js b/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js index b1429af6ad95cf..fa3fdb3bedd89b 100644 --- a/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js +++ b/tools/node_modules/eslint/lib/cli-engine/config-array-factory.js @@ -817,7 +817,7 @@ class ConfigArrayFactory { if (configData) { return this._normalizeConfigData(configData, { ...ctx, - filePath: plugin.filePath, + filePath: plugin.filePath || ctx.filePath, name: `${ctx.name} » plugin:${plugin.id}/${configName}` }); } @@ -978,7 +978,7 @@ class ConfigArrayFactory { if (plugin) { return new ConfigDependency({ definition: normalizePlugin(plugin), - filePath: ctx.filePath, + filePath: "", // It's unknown where the plugin came from. id, importerName: ctx.name, importerPath: ctx.filePath diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js b/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js index b3434198b19201..42a7362737fc7c 100644 --- a/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js +++ b/tools/node_modules/eslint/lib/cli-engine/config-array/config-array.js @@ -107,7 +107,7 @@ function getMatchedIndices(elements, filePath) { for (let i = elements.length - 1; i >= 0; --i) { const element = elements[i]; - if (!element.criteria || element.criteria.test(filePath)) { + if (!element.criteria || (filePath && element.criteria.test(filePath))) { indices.push(i); } } diff --git a/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js b/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js index 92690b9f8ae342..6eaec4258e1ae4 100644 --- a/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js +++ b/tools/node_modules/eslint/lib/cli-engine/config-array/ignore-pattern.js @@ -71,7 +71,13 @@ function getCommonAncestorPath(sourcePaths) { } } - return result || path.sep; + let resolvedResult = result || path.sep; + + // if Windows common ancestor is root of drive must have trailing slash to be absolute. + if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") { + resolvedResult += path.sep; + } + return resolvedResult; } /** diff --git a/tools/node_modules/eslint/lib/cli.js b/tools/node_modules/eslint/lib/cli.js index 815ce68c22fe2e..ce11878008f108 100644 --- a/tools/node_modules/eslint/lib/cli.js +++ b/tools/node_modules/eslint/lib/cli.js @@ -17,105 +17,176 @@ const fs = require("fs"), path = require("path"), - { CLIEngine } = require("./cli-engine"), - options = require("./options"), + { promisify } = require("util"), + { ESLint } = require("./eslint"), + CLIOptions = require("./options"), log = require("./shared/logging"), RuntimeInfo = require("./shared/runtime-info"); const debug = require("debug")("eslint:cli"); +//------------------------------------------------------------------------------ +// Types +//------------------------------------------------------------------------------ + +/** @typedef {import("./eslint/eslint").ESLintOptions} ESLintOptions */ +/** @typedef {import("./eslint/eslint").LintMessage} LintMessage */ +/** @typedef {import("./eslint/eslint").LintResult} LintResult */ + //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ +const mkdir = promisify(fs.mkdir); +const stat = promisify(fs.stat); +const writeFile = promisify(fs.writeFile); + /** * Predicate function for whether or not to apply fixes in quiet mode. * If a message is a warning, do not apply a fix. - * @param {LintResult} lintResult The lint result. + * @param {LintMessage} message The lint result. * @returns {boolean} True if the lint message is an error (and thus should be * autofixed), false otherwise. */ -function quietFixPredicate(lintResult) { - return lintResult.severity === 2; +function quietFixPredicate(message) { + return message.severity === 2; } /** * Translates the CLI options into the options expected by the CLIEngine. * @param {Object} cliOptions The CLI options to translate. - * @returns {CLIEngineOptions} The options object for the CLIEngine. + * @returns {ESLintOptions} The options object for the CLIEngine. * @private */ -function translateOptions(cliOptions) { +function translateOptions({ + cache, + cacheFile, + cacheLocation, + config, + env, + errorOnUnmatchedPattern, + eslintrc, + ext, + fix, + fixDryRun, + fixType, + global, + ignore, + ignorePath, + ignorePattern, + inlineConfig, + parser, + parserOptions, + plugin, + quiet, + reportUnusedDisableDirectives, + resolvePluginsRelativeTo, + rule, + rulesdir +}) { return { - envs: cliOptions.env, - extensions: cliOptions.ext, - rules: cliOptions.rule, - plugins: cliOptions.plugin, - globals: cliOptions.global, - ignore: cliOptions.ignore, - ignorePath: cliOptions.ignorePath, - ignorePattern: cliOptions.ignorePattern, - configFile: cliOptions.config, - rulePaths: cliOptions.rulesdir, - useEslintrc: cliOptions.eslintrc, - parser: cliOptions.parser, - parserOptions: cliOptions.parserOptions, - cache: cliOptions.cache, - cacheFile: cliOptions.cacheFile, - cacheLocation: cliOptions.cacheLocation, - fix: (cliOptions.fix || cliOptions.fixDryRun) && (cliOptions.quiet ? quietFixPredicate : true), - fixTypes: cliOptions.fixType, - allowInlineConfig: cliOptions.inlineConfig, - reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives, - resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo, - errorOnUnmatchedPattern: cliOptions.errorOnUnmatchedPattern + allowInlineConfig: inlineConfig, + cache, + cacheLocation: cacheLocation || cacheFile, + errorOnUnmatchedPattern, + extensions: ext, + fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true), + fixTypes: fixType, + ignore, + ignorePath, + overrideConfig: { + env: env && env.reduce((obj, name) => { + obj[name] = true; + return obj; + }, {}), + globals: global && global.reduce((obj, name) => { + if (name.endsWith(":true")) { + obj[name.slice(0, -5)] = "writable"; + } else { + obj[name] = "readonly"; + } + return obj; + }, {}), + ignorePatterns: ignorePattern, + parser, + parserOptions, + plugins: plugin, + rules: rule + }, + overrideConfigFile: config, + reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0, + resolvePluginsRelativeTo, + rulePaths: rulesdir, + useEslintrc: eslintrc }; } +/** + * Count error messages. + * @param {LintResult[]} results The lint results. + * @returns {{errorCount:number;warningCount:number}} The number of error messages. + */ +function countErrors(results) { + let errorCount = 0; + let warningCount = 0; + + for (const result of results) { + errorCount += result.errorCount; + warningCount += result.warningCount; + } + + return { errorCount, warningCount }; +} + +/** + * Check if a given file path is a directory or not. + * @param {string} filePath The path to a file to check. + * @returns {Promise} `true` if the given path is a directory. + */ +async function isDirectory(filePath) { + try { + return (await stat(filePath)).isDirectory(); + } catch (error) { + if (error.code === "ENOENT" || error.code === "ENOTDIR") { + return false; + } + throw error; + } +} + /** * Outputs the results of the linting. - * @param {CLIEngine} engine The CLIEngine to use. + * @param {ESLint} engine The ESLint instance to use. * @param {LintResult[]} results The results to print. * @param {string} format The name of the formatter to use or the path to the formatter. * @param {string} outputFile The path for the output file. - * @returns {boolean} True if the printing succeeds, false if not. + * @returns {Promise} True if the printing succeeds, false if not. * @private */ -function printResults(engine, results, format, outputFile) { +async function printResults(engine, results, format, outputFile) { let formatter; - let rulesMeta; try { - formatter = engine.getFormatter(format); + formatter = await engine.loadFormatter(format); } catch (e) { log.error(e.message); return false; } - const output = formatter(results, { - get rulesMeta() { - if (!rulesMeta) { - rulesMeta = {}; - for (const [ruleId, rule] of engine.getRules()) { - rulesMeta[ruleId] = rule.meta; - } - } - return rulesMeta; - } - }); + const output = formatter.format(results); if (output) { if (outputFile) { const filePath = path.resolve(process.cwd(), outputFile); - if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) { + if (await isDirectory(filePath)) { log.error("Cannot write to output file path, it is a directory: %s", outputFile); return false; } try { - fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, output); + await mkdir(path.dirname(filePath), { recursive: true }); + await writeFile(filePath, output); } catch (ex) { log.error("There was a problem writing the output file:\n%s", ex); return false; @@ -126,7 +197,6 @@ function printResults(engine, results, format, outputFile) { } return true; - } //------------------------------------------------------------------------------ @@ -143,28 +213,33 @@ const cli = { * Executes the CLI based on an array of arguments that is passed in. * @param {string|Array|Object} args The arguments to process. * @param {string} [text] The text to lint (used for TTY). - * @returns {int} The exit code for the operation. + * @returns {Promise} The exit code for the operation. */ - execute(args, text) { + async execute(args, text) { if (Array.isArray(args)) { debug("CLI args: %o", args.slice(2)); } - - let currentOptions; + let options; try { - currentOptions = options.parse(args); + options = CLIOptions.parse(args); } catch (error) { log.error(error.message); return 2; } - const files = currentOptions._; + const files = options._; const useStdin = typeof text === "string"; - if (currentOptions.version) { + if (options.help) { + log.info(CLIOptions.generateHelp()); + return 0; + } + if (options.version) { log.info(RuntimeInfo.version()); - } else if (currentOptions.envInfo) { + return 0; + } + if (options.envInfo) { try { log.info(RuntimeInfo.environment()); return 0; @@ -172,7 +247,9 @@ const cli = { log.error(err.message); return 2; } - } else if (currentOptions.printConfig) { + } + + if (options.printConfig) { if (files.length) { log.error("The --print-config option must be used with exactly one file name."); return 2; @@ -182,58 +259,67 @@ const cli = { return 2; } - const engine = new CLIEngine(translateOptions(currentOptions)); - const fileConfig = engine.getConfigForFile(currentOptions.printConfig); + const engine = new ESLint(translateOptions(options)); + const fileConfig = + await engine.calculateConfigForFile(options.printConfig); log.info(JSON.stringify(fileConfig, null, " ")); return 0; - } else if (currentOptions.help || (!files.length && !useStdin)) { - log.info(options.generateHelp()); - } else { - debug(`Running on ${useStdin ? "text" : "files"}`); - - if (currentOptions.fix && currentOptions.fixDryRun) { - log.error("The --fix option and the --fix-dry-run option cannot be used together."); - return 2; - } + } - if (useStdin && currentOptions.fix) { - log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead."); - return 2; - } + debug(`Running on ${useStdin ? "text" : "files"}`); - if (currentOptions.fixType && !currentOptions.fix && !currentOptions.fixDryRun) { - log.error("The --fix-type option requires either --fix or --fix-dry-run."); - return 2; - } + if (options.fix && options.fixDryRun) { + log.error("The --fix option and the --fix-dry-run option cannot be used together."); + return 2; + } + if (useStdin && options.fix) { + log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead."); + return 2; + } + if (options.fixType && !options.fix && !options.fixDryRun) { + log.error("The --fix-type option requires either --fix or --fix-dry-run."); + return 2; + } - const engine = new CLIEngine(translateOptions(currentOptions)); - const report = useStdin ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files); + const engine = new ESLint(translateOptions(options)); + let results; - if (currentOptions.fix) { - debug("Fix mode enabled - applying fixes"); - CLIEngine.outputFixes(report); - } + if (useStdin) { + results = await engine.lintText(text, { + filePath: options.stdinFilename, + warnIgnored: true + }); + } else { + results = await engine.lintFiles(files); + } - if (currentOptions.quiet) { - debug("Quiet mode enabled - filtering out warnings"); - report.results = CLIEngine.getErrorResults(report.results); - } + if (options.fix) { + debug("Fix mode enabled - applying fixes"); + await ESLint.outputFixes(results); + } - if (printResults(engine, report.results, currentOptions.format, currentOptions.outputFile)) { - const tooManyWarnings = currentOptions.maxWarnings >= 0 && report.warningCount > currentOptions.maxWarnings; + if (options.quiet) { + debug("Quiet mode enabled - filtering out warnings"); + results = ESLint.getErrorResults(results); + } - if (!report.errorCount && tooManyWarnings) { - log.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings); - } + if (await printResults(engine, results, options.format, options.outputFile)) { + const { errorCount, warningCount } = countErrors(results); + const tooManyWarnings = + options.maxWarnings >= 0 && warningCount > options.maxWarnings; - return (report.errorCount || tooManyWarnings) ? 1 : 0; + if (!errorCount && tooManyWarnings) { + log.error( + "ESLint found too many warnings (maximum: %s).", + options.maxWarnings + ); } - return 2; + return (errorCount || tooManyWarnings) ? 1 : 0; } - return 0; + return 2; } }; diff --git a/tools/node_modules/eslint/lib/eslint/eslint.js b/tools/node_modules/eslint/lib/eslint/eslint.js new file mode 100644 index 00000000000000..d195aab09f1918 --- /dev/null +++ b/tools/node_modules/eslint/lib/eslint/eslint.js @@ -0,0 +1,656 @@ +/** + * @fileoverview Main API Class + * @author Kai Cataldo + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const path = require("path"); +const fs = require("fs"); +const { promisify } = require("util"); +const { CLIEngine, getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); +const BuiltinRules = require("../rules"); +const { getRuleSeverity } = require("../shared/config-ops"); +const { version } = require("../../package.json"); + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */ +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ +/** @typedef {import("../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").Plugin} Plugin */ +/** @typedef {import("../shared/types").Rule} Rule */ +/** @typedef {import("./load-formatter").Formatter} Formatter */ + +/** + * The options with which to configure the ESLint instance. + * @typedef {Object} ESLintOptions + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {string} [cwd] The value to use for the current working directory. + * @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`. + * @property {string[]} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance + * @property {string} [overrideConfigFile] The configuration file to use. + * @property {Record} [plugins] An array of plugin implementations. + * @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files. + */ + +/** + * A rules metadata object. + * @typedef {Object} RulesMeta + * @property {string} id The plugin ID. + * @property {Object} definition The plugin definition. + */ + +/** + * A linting result. + * @typedef {Object} LintResult + * @property {string} filePath The path to the file that was linted. + * @property {LintMessage[]} messages All of the messages for the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {string} [source] The source code of the file that was linted. + * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. + * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. + */ + +/** + * Private members for the `ESLint` instance. + * @typedef {Object} ESLintPrivateMembers + * @property {CLIEngine} cliEngine The wrapped CLIEngine instance. + * @property {ESLintOptions} options The options used to instantiate the ESLint instance. + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const writeFile = promisify(fs.writeFile); + +/** + * The map with which to store private class members. + * @type {WeakMap} + */ +const privateMembersMap = new WeakMap(); + +/** + * Check if a given value is a non-empty string or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is a non-empty string. + */ +function isNonEmptyString(x) { + return typeof x === "string" && x.trim() !== ""; +} + +/** + * Check if a given value is an array of non-empty stringss or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of non-empty stringss. + */ +function isArrayOfNonEmptyString(x) { + return Array.isArray(x) && x.every(isNonEmptyString); +} + +/** + * Check if a given value is a valid fix type or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is valid fix type. + */ +function isFixType(x) { + return x === "problem" || x === "suggestion" || x === "layout"; +} + +/** + * Check if a given value is an array of fix types or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of fix types. + */ +function isFixTypeArray(x) { + return Array.isArray(x) && x.every(isFixType); +} + +/** + * The error for invalid options. + */ +class ESLintInvalidOptionsError extends Error { + constructor(messages) { + super(`Invalid Options:\n- ${messages.join("\n- ")}`); + this.code = "ESLINT_INVALID_OPTIONS"; + Error.captureStackTrace(this, ESLintInvalidOptionsError); + } +} + +/** + * Validates and normalizes options for the wrapped CLIEngine instance. + * @param {ESLintOptions} options The options to process. + * @returns {ESLintOptions} The normalized options. + */ +function processOptions({ + allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored. + baseConfig = null, + cache = false, + cacheLocation = ".eslintcache", + cwd = process.cwd(), + errorOnUnmatchedPattern = true, + extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature. + fix = false, + fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property. + globInputPaths = true, + ignore = true, + ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT. + overrideConfig = null, + overrideConfigFile = null, + plugins = {}, + reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. + resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature. + rulePaths = [], + useEslintrc = true, + ...unknownOptions +}) { + const errors = []; + const unknownOptionKeys = Object.keys(unknownOptions); + + if (unknownOptionKeys.length >= 1) { + errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`); + if (unknownOptionKeys.includes("cacheFile")) { + errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead."); + } + if (unknownOptionKeys.includes("configFile")) { + errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead."); + } + if (unknownOptionKeys.includes("envs")) { + errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead."); + } + if (unknownOptionKeys.includes("globals")) { + errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead."); + } + if (unknownOptionKeys.includes("ignorePattern")) { + errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."); + } + if (unknownOptionKeys.includes("parser")) { + errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead."); + } + if (unknownOptionKeys.includes("parserOptions")) { + errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead."); + } + if (unknownOptionKeys.includes("rules")) { + errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead."); + } + } + if (typeof allowInlineConfig !== "boolean") { + errors.push("'allowInlineConfig' must be a boolean."); + } + if (typeof baseConfig !== "object") { + errors.push("'baseConfig' must be an object or null."); + } + if (typeof cache !== "boolean") { + errors.push("'cache' must be a boolean."); + } + if (!isNonEmptyString(cacheLocation)) { + errors.push("'cacheLocation' must be a non-empty string."); + } + if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) { + errors.push("'cwd' must be an absolute path."); + } + if (typeof errorOnUnmatchedPattern !== "boolean") { + errors.push("'errorOnUnmatchedPattern' must be a boolean."); + } + if (!isArrayOfNonEmptyString(extensions) && extensions !== null) { + errors.push("'extensions' must be an array of non-empty strings or null."); + } + if (typeof fix !== "boolean" && typeof fix !== "function") { + errors.push("'fix' must be a boolean or a function."); + } + if (fixTypes !== null && !isFixTypeArray(fixTypes)) { + errors.push("'fixTypes' must be an array of any of \"problem\", \"suggestion\", and \"layout\"."); + } + if (typeof globInputPaths !== "boolean") { + errors.push("'globInputPaths' must be a boolean."); + } + if (typeof ignore !== "boolean") { + errors.push("'ignore' must be a boolean."); + } + if (!isNonEmptyString(ignorePath) && ignorePath !== null) { + errors.push("'ignorePath' must be a non-empty string or null."); + } + if (typeof overrideConfig !== "object") { + errors.push("'overrideConfig' must be an object or null."); + } + if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) { + errors.push("'overrideConfigFile' must be a non-empty string or null."); + } + if (typeof plugins !== "object") { + errors.push("'plugins' must be an object or null."); + } else if (plugins !== null && Object.keys(plugins).includes("")) { + errors.push("'plugins' must not include an empty string."); + } + if (Array.isArray(plugins)) { + errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead."); + } + if ( + reportUnusedDisableDirectives !== "error" && + reportUnusedDisableDirectives !== "warn" && + reportUnusedDisableDirectives !== "off" && + reportUnusedDisableDirectives !== null + ) { + errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null."); + } + if ( + !isNonEmptyString(resolvePluginsRelativeTo) && + resolvePluginsRelativeTo !== null + ) { + errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null."); + } + if (!isArrayOfNonEmptyString(rulePaths)) { + errors.push("'rulePaths' must be an array of non-empty strings."); + } + if (typeof useEslintrc !== "boolean") { + errors.push("'useElintrc' must be a boolean."); + } + + if (errors.length > 0) { + throw new ESLintInvalidOptionsError(errors); + } + + return { + allowInlineConfig, + baseConfig, + cache, + cacheLocation, + configFile: overrideConfigFile, + cwd, + errorOnUnmatchedPattern, + extensions, + fix, + fixTypes, + globInputPaths, + ignore, + ignorePath, + reportUnusedDisableDirectives, + resolvePluginsRelativeTo, + rulePaths, + useEslintrc + }; +} + +/** + * Check if a value has one or more properties and that value is not undefined. + * @param {any} obj The value to check. + * @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined. + */ +function hasDefinedProperty(obj) { + if (typeof obj === "object" && obj !== null) { + for (const key in obj) { + if (typeof obj[key] !== "undefined") { + return true; + } + } + } + return false; +} + +/** + * Create rulesMeta object. + * @param {Map} rules a map of rules from which to generate the object. + * @returns {Object} metadata for all enabled rules. + */ +function createRulesMeta(rules) { + return Array.from(rules).reduce((retVal, [id, rule]) => { + retVal[id] = rule.meta; + return retVal; + }, {}); +} + +/** @type {WeakMap} */ +const usedDeprecatedRulesCache = new WeakMap(); + +/** + * Create used deprecated rule list. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {string} maybeFilePath The absolute path to a lint target file or `""`. + * @returns {DeprecatedRuleInfo[]} The used deprecated rule list. + */ +function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) { + const { + configArrayFactory, + options: { cwd } + } = getCLIEngineInternalSlots(cliEngine); + const filePath = path.isAbsolute(maybeFilePath) + ? maybeFilePath + : path.join(cwd, "__placeholder__.js"); + const configArray = configArrayFactory.getConfigArrayForFile(filePath); + const config = configArray.extractConfig(filePath); + + // Most files use the same config, so cache it. + if (!usedDeprecatedRulesCache.has(config)) { + const pluginRules = configArray.pluginRules; + const retv = []; + + for (const [ruleId, ruleConf] of Object.entries(config.rules)) { + if (getRuleSeverity(ruleConf) === 0) { + continue; + } + const rule = pluginRules.get(ruleId) || BuiltinRules.get(ruleId); + const meta = rule && rule.meta; + + if (meta && meta.deprecated) { + retv.push({ ruleId, replacedBy: meta.replacedBy || [] }); + } + } + + usedDeprecatedRulesCache.set(config, Object.freeze(retv)); + } + + return usedDeprecatedRulesCache.get(config); +} + +/** + * Processes the linting results generated by a CLIEngine linting report to + * match the ESLint class's API. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {CLIEngineLintReport} report The CLIEngine linting report to process. + * @returns {LintResult[]} The processed linting results. + */ +function processCLIEngineLintReport(cliEngine, { results }) { + const descriptor = { + configurable: true, + enumerable: true, + get() { + return getOrFindUsedDeprecatedRules(cliEngine, this.filePath); + } + }; + + for (const result of results) { + Object.defineProperty(result, "usedDeprecatedRules", descriptor); + } + + return results; +} + +/** + * An Array.prototype.sort() compatible compare function to order results by their file path. + * @param {LintResult} a The first lint result. + * @param {LintResult} b The second lint result. + * @returns {number} An integer representing the order in which the two results should occur. + */ +function compareResultsByFilePath(a, b) { + if (a.filePath < b.filePath) { + return -1; + } + + if (a.filePath > b.filePath) { + return 1; + } + + return 0; +} + +class ESLint { + + /** + * Creates a new instance of the main ESLint API. + * @param {ESLintOptions} options The options for this instance. + */ + constructor(options = {}) { + const processedOptions = processOptions(options); + const cliEngine = new CLIEngine(processedOptions); + const { + additionalPluginPool, + configArrayFactory, + lastConfigArrays + } = getCLIEngineInternalSlots(cliEngine); + let updated = false; + + /* + * Address `plugins` to add plugin implementations. + * Operate the `additionalPluginPool` internal slot directly to avoid + * using `addPlugin(id, plugin)` method that resets cache everytime. + */ + if (options.plugins) { + for (const [id, plugin] of Object.entries(options.plugins)) { + additionalPluginPool.set(id, plugin); + updated = true; + } + } + + /* + * Address `overrideConfig` to set override config. + * Operate the `configArrayFactory` internal slot directly because this + * functionality doesn't exist as the public API of CLIEngine. + */ + if (hasDefinedProperty(options.overrideConfig)) { + configArrayFactory.setOverrideConfig(options.overrideConfig); + updated = true; + } + + // Update caches. + if (updated) { + configArrayFactory.clearCache(); + lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); + } + + // Initialize private properties. + privateMembersMap.set(this, { + cliEngine, + options: processedOptions + }); + } + + /** + * The version text. + * @type {string} + */ + static get version() { + return version; + } + + /** + * Outputs fixes from the given results to files. + * @param {LintResult[]} results The lint results. + * @returns {Promise} Returns a promise that is used to track side effects. + */ + static async outputFixes(results) { + if (!Array.isArray(results)) { + throw new Error("'results' must be an array"); + } + + await Promise.all( + results + .filter(result => { + if (typeof result !== "object" || result === null) { + throw new Error("'results' must include only objects"); + } + return ( + typeof result.output === "string" && + path.isAbsolute(result.filePath) + ); + }) + .map(r => writeFile(r.filePath, r.output)) + ); + } + + /** + * Returns results that only contains errors. + * @param {LintResult[]} results The results to filter. + * @returns {LintResult[]} The filtered results. + */ + static getErrorResults(results) { + return CLIEngine.getErrorResults(results); + } + + /** + * Executes the current configuration on an array of file and directory names. + * @param {string[]} patterns An array of file and directory names. + * @returns {Promise} The results of linting the file patterns given. + */ + async lintFiles(patterns) { + if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) { + throw new Error("'patterns' must be a non-empty string or an array of non-empty strings"); + } + const { cliEngine } = privateMembersMap.get(this); + + return processCLIEngineLintReport( + cliEngine, + cliEngine.executeOnFiles(patterns) + ); + } + + /** + * Executes the current configuration on text. + * @param {string} code A string of JavaScript code to lint. + * @param {Object} [options] The options. + * @param {string} [options.filePath] The path to the file of the source code. + * @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path. + * @returns {Promise} The results of linting the string of code given. + */ + async lintText(code, options = {}) { + if (typeof code !== "string") { + throw new Error("'code' must be a string"); + } + if (typeof options !== "object") { + throw new Error("'options' must be an object, null, or undefined"); + } + const { + filePath, + warnIgnored = false, + ...unknownOptions + } = options || {}; + + for (const key of Object.keys(unknownOptions)) { + throw new Error(`'options' must not include the unknown option '${key}'`); + } + if (filePath !== void 0 && !isNonEmptyString(filePath)) { + throw new Error("'options.filePath' must be a non-empty string or undefined"); + } + if (typeof warnIgnored !== "boolean") { + throw new Error("'options.warnIgnored' must be a boolean or undefined"); + } + + const { cliEngine } = privateMembersMap.get(this); + + return processCLIEngineLintReport( + cliEngine, + cliEngine.executeOnText(code, filePath, warnIgnored) + ); + } + + /** + * Returns the formatter representing the given formatter name. + * @param {string} [name] The name of the formattter to load. + * The following values are allowed: + * - `undefined` ... Load `stylish` builtin formatter. + * - A builtin formatter name ... Load the builtin formatter. + * - A thirdparty formatter name: + * - `foo` → `eslint-formatter-foo` + * - `@foo` → `@foo/eslint-formatter` + * - `@foo/bar` → `@foo/eslint-formatter-bar` + * - A file path ... Load the file. + * @returns {Promise} A promise resolving to the formatter object. + * This promise will be rejected if the given formatter was not found or not + * a function. + */ + async loadFormatter(name = "stylish") { + if (typeof name !== "string") { + throw new Error("'name' must be a string"); + } + + const { cliEngine } = privateMembersMap.get(this); + const formatter = cliEngine.getFormatter(name); + + if (typeof formatter !== "function") { + throw new Error(`Formatter must be a function, but got a ${typeof formatter}.`); + } + + return { + + /** + * The main formatter method. + * @param {LintResults[]} results The lint results to format. + * @returns {string} The formatted lint results. + */ + format(results) { + let rulesMeta = null; + + results.sort(compareResultsByFilePath); + + return formatter(results, { + get rulesMeta() { + if (!rulesMeta) { + rulesMeta = createRulesMeta(cliEngine.getRules()); + } + + return rulesMeta; + } + }); + } + }; + } + + /** + * Returns a configuration object for the given file based on the CLI options. + * This is the same logic used by the ESLint CLI executable to determine + * configuration for each file it processes. + * @param {string} filePath The path of the file to retrieve a config object for. + * @returns {Promise} A configuration object for the file. + */ + async calculateConfigForFile(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); + } + const { cliEngine } = privateMembersMap.get(this); + + return cliEngine.getConfigForFile(filePath); + } + + /** + * Checks if a given path is ignored by ESLint. + * @param {string} filePath The path of the file to check. + * @returns {Promise} Whether or not the given path is ignored. + */ + async isPathIgnored(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); + } + const { cliEngine } = privateMembersMap.get(this); + + return cliEngine.isPathIgnored(filePath); + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + ESLint, + + /** + * Get the private class members of a given ESLint instance for tests. + * @param {ESLint} instance The ESLint instance to get. + * @returns {ESLintPrivateMembers} The instance's private class members. + */ + getESLintPrivateMembers(instance) { + return privateMembersMap.get(instance); + } +}; diff --git a/tools/node_modules/eslint/lib/eslint/index.js b/tools/node_modules/eslint/lib/eslint/index.js new file mode 100644 index 00000000000000..c9185ee0eba0a5 --- /dev/null +++ b/tools/node_modules/eslint/lib/eslint/index.js @@ -0,0 +1,7 @@ +"use strict"; + +const { ESLint } = require("./eslint"); + +module.exports = { + ESLint +}; diff --git a/tools/node_modules/eslint/lib/init/autoconfig.js b/tools/node_modules/eslint/lib/init/autoconfig.js index 64be3d2a84f49b..2b0aa12ac13df6 100644 --- a/tools/node_modules/eslint/lib/init/autoconfig.js +++ b/tools/node_modules/eslint/lib/init/autoconfig.js @@ -301,7 +301,7 @@ class Registry { ruleSetIdx += 1; if (cb) { - cb(totalFilesLinting); // eslint-disable-line callback-return + cb(totalFilesLinting); // eslint-disable-line node/callback-return } }); @@ -316,10 +316,10 @@ class Registry { /** * Extract rule configuration into eslint:recommended where possible. * - * This will return a new config with `"extends": "eslint:recommended"` and + * This will return a new config with `["extends": [ ..., "eslint:recommended"]` and * only the rules which have configurations different from the recommended config. * @param {Object} config config object - * @returns {Object} config object using `"extends": "eslint:recommended"` + * @returns {Object} config object using `"extends": ["eslint:recommended"]` */ function extendFromRecommended(config) { const newConfig = Object.assign({}, config); @@ -333,7 +333,7 @@ function extendFromRecommended(config) { delete newConfig.rules[ruleId]; } }); - newConfig.extends = RECOMMENDED_CONFIG_NAME; + newConfig.extends.unshift(RECOMMENDED_CONFIG_NAME); return newConfig; } diff --git a/tools/node_modules/eslint/lib/init/config-initializer.js b/tools/node_modules/eslint/lib/init/config-initializer.js index 28dfad194a7e6f..70f0a250ad1dd6 100644 --- a/tools/node_modules/eslint/lib/init/config-initializer.js +++ b/tools/node_modules/eslint/lib/init/config-initializer.js @@ -15,6 +15,7 @@ const util = require("util"), inquirer = require("inquirer"), ProgressBar = require("progress"), semver = require("semver"), + espree = require("espree"), recConfig = require("../../conf/eslint-recommended"), ConfigOps = require("../shared/config-ops"), log = require("../shared/logging"), @@ -31,8 +32,6 @@ const debug = require("debug")("eslint:config-initializer"); // Private //------------------------------------------------------------------------------ -const DEFAULT_ECMA_VERSION = 2018; - /* istanbul ignore next: hard to test fs function */ /** * Create .eslintrc file in the current working directory @@ -265,8 +264,7 @@ function processAnswers(answers) { extends: [] }; - // set the latest ECMAScript version - config.parserOptions.ecmaVersion = DEFAULT_ECMA_VERSION; + config.parserOptions.ecmaVersion = espree.latestEcmaVersion; config.env.es6 = true; config.globals = { Atomics: "readonly", diff --git a/tools/node_modules/eslint/lib/init/source-code-utils.js b/tools/node_modules/eslint/lib/init/source-code-utils.js index dfc170a65cf71b..dca6541d1ed328 100644 --- a/tools/node_modules/eslint/lib/init/source-code-utils.js +++ b/tools/node_modules/eslint/lib/init/source-code-utils.js @@ -23,7 +23,7 @@ const { CLIEngine } = require("../cli-engine"); * TODO1: Expose the API that enumerates target files. * TODO2: Extract the creation logic of `SourceCode` from `Linter` class. */ -const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line no-restricted-modules +const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require const debug = require("debug")("eslint:source-code-utils"); @@ -97,7 +97,7 @@ function getSourceCodeOfFiles(patterns, options, callback) { sourceCodes[filename] = sourceCode; } if (callback) { - callback(filenames.length); // eslint-disable-line callback-return + callback(filenames.length); // eslint-disable-line node/callback-return } }); diff --git a/tools/node_modules/eslint/lib/options.js b/tools/node_modules/eslint/lib/options.js index 98dc04b6eb3968..1681f1dbd1d733 100644 --- a/tools/node_modules/eslint/lib/options.js +++ b/tools/node_modules/eslint/lib/options.js @@ -46,7 +46,6 @@ module.exports = optionator({ { option: "ext", type: "[String]", - default: ".js", description: "Specify JavaScript file extensions" }, { diff --git a/tools/node_modules/eslint/lib/rule-tester/rule-tester.js b/tools/node_modules/eslint/lib/rule-tester/rule-tester.js index 1c1737152c1b19..77df1def893ccc 100644 --- a/tools/node_modules/eslint/lib/rule-tester/rule-tester.js +++ b/tools/node_modules/eslint/lib/rule-tester/rule-tester.js @@ -563,7 +563,12 @@ class RuleTester { output = SourceCodeFixer.applyFixes(code, messages).output; const errorMessageInFix = linter.verify(output, config, filename).find(m => m.fatal); - assert(!errorMessageInFix, `A fatal parsing error occurred in autofix: ${errorMessageInFix && errorMessageInFix.message}`); + assert(!errorMessageInFix, [ + "A fatal parsing error occurred in autofix.", + `Error: ${errorMessageInFix && errorMessageInFix.message}`, + "Autofix output:", + output + ].join("\n")); } else { output = code; } diff --git a/tools/node_modules/eslint/lib/rules/array-callback-return.js b/tools/node_modules/eslint/lib/rules/array-callback-return.js index eb38965024f05d..62ba7b72d87257 100644 --- a/tools/node_modules/eslint/lib/rules/array-callback-return.js +++ b/tools/node_modules/eslint/lib/rules/array-callback-return.js @@ -29,22 +29,6 @@ function isReachable(segment) { return segment.reachable; } -/** - * Gets a readable location. - * - * - FunctionExpression -> the function name or `function` keyword. - * - ArrowFunctionExpression -> `=>` token. - * @param {ASTNode} node A function node to get. - * @param {SourceCode} sourceCode A source code to get tokens. - * @returns {ASTNode|Token} The node or the token of a location. - */ -function getLocation(node, sourceCode) { - if (node.type === "ArrowFunctionExpression") { - return sourceCode.getTokenBefore(node.body); - } - return node.id || node; -} - /** * Checks a given node is a MemberExpression node which has the specified name's * property. @@ -179,6 +163,7 @@ module.exports = { create(context) { const options = context.options[0] || { allowImplicit: false, checkForEach: false }; + const sourceCode = context.getSourceCode(); let funcInfo = { arrayMethodName: null, @@ -217,12 +202,12 @@ module.exports = { } if (messageId) { - let name = astUtils.getFunctionNameWithKind(funcInfo.node); + let name = astUtils.getFunctionNameWithKind(node); name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name; context.report({ node, - loc: getLocation(node, context.getSourceCode()).loc.start, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), messageId, data: { name } }); diff --git a/tools/node_modules/eslint/lib/rules/callback-return.js b/tools/node_modules/eslint/lib/rules/callback-return.js index c5263cde46b752..5df792d436341e 100644 --- a/tools/node_modules/eslint/lib/rules/callback-return.js +++ b/tools/node_modules/eslint/lib/rules/callback-return.js @@ -10,6 +10,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/callback-return"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/comma-style.js b/tools/node_modules/eslint/lib/rules/comma-style.js index bc22f05dd3892c..f1a23d63b786a0 100644 --- a/tools/node_modules/eslint/lib/rules/comma-style.js +++ b/tools/node_modules/eslint/lib/rules/comma-style.js @@ -146,10 +146,7 @@ module.exports = { // lone comma context.report({ node: reportItem, - loc: { - line: commaToken.loc.end.line, - column: commaToken.loc.start.column - }, + loc: commaToken.loc, messageId: "unexpectedLineBeforeAndAfterComma", fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) }); @@ -158,6 +155,7 @@ module.exports = { context.report({ node: reportItem, + loc: commaToken.loc, messageId: "expectedCommaFirst", fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) }); @@ -166,10 +164,7 @@ module.exports = { context.report({ node: reportItem, - loc: { - line: commaToken.loc.end.line, - column: commaToken.loc.end.column - }, + loc: commaToken.loc, messageId: "expectedCommaLast", fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) }); diff --git a/tools/node_modules/eslint/lib/rules/func-call-spacing.js b/tools/node_modules/eslint/lib/rules/func-call-spacing.js index e2edd4282da578..dccdd0a40c6d76 100644 --- a/tools/node_modules/eslint/lib/rules/func-call-spacing.js +++ b/tools/node_modules/eslint/lib/rules/func-call-spacing.js @@ -63,7 +63,8 @@ module.exports = { }, messages: { - unexpected: "Unexpected newline between function name and paren.", + unexpectedWhitespace: "Unexpected whitespace between function name and paren.", + unexpectedNewline: "Unexpected newline between function name and paren.", missing: "Missing space between function name and paren." } }, @@ -116,7 +117,7 @@ module.exports = { context.report({ node, loc: leftToken.loc.start, - messageId: "unexpected", + messageId: "unexpectedWhitespace", fix(fixer) { /* @@ -143,7 +144,7 @@ module.exports = { context.report({ node, loc: leftToken.loc.start, - messageId: "unexpected", + messageId: "unexpectedNewline", fix(fixer) { return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " "); } diff --git a/tools/node_modules/eslint/lib/rules/getter-return.js b/tools/node_modules/eslint/lib/rules/getter-return.js index e1468a5b19f88d..c54ebfb4ffb8cd 100644 --- a/tools/node_modules/eslint/lib/rules/getter-return.js +++ b/tools/node_modules/eslint/lib/rules/getter-return.js @@ -25,17 +25,6 @@ function isReachable(segment) { return segment.reachable; } -/** - * Gets a readable location. - * - * - FunctionExpression -> the function name or `function` keyword. - * @param {ASTNode} node A function node to get. - * @returns {ASTNode|Token} The node or the token of a location. - */ -function getId(node) { - return node.id || node; -} - //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -75,6 +64,7 @@ module.exports = { create(context) { const options = context.options[0] || { allowImplicit: false }; + const sourceCode = context.getSourceCode(); let funcInfo = { upper: null, @@ -99,7 +89,7 @@ module.exports = { ) { context.report({ node, - loc: getId(node).loc.start, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), messageId: funcInfo.hasReturn ? "expectedAlways" : "expected", data: { name: astUtils.getFunctionNameWithKind(funcInfo.node) diff --git a/tools/node_modules/eslint/lib/rules/global-require.js b/tools/node_modules/eslint/lib/rules/global-require.js index 4af3a6a4669a79..9bd073b88546d6 100644 --- a/tools/node_modules/eslint/lib/rules/global-require.js +++ b/tools/node_modules/eslint/lib/rules/global-require.js @@ -48,6 +48,10 @@ function isShadowed(scope, node) { module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/global-require"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/handle-callback-err.js b/tools/node_modules/eslint/lib/rules/handle-callback-err.js index 640946699e7bea..8ad63bbd53a77b 100644 --- a/tools/node_modules/eslint/lib/rules/handle-callback-err.js +++ b/tools/node_modules/eslint/lib/rules/handle-callback-err.js @@ -11,6 +11,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/handle-callback-err"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/key-spacing.js b/tools/node_modules/eslint/lib/rules/key-spacing.js index c405043794c7d1..57abb00b06e8a4 100644 --- a/tools/node_modules/eslint/lib/rules/key-spacing.js +++ b/tools/node_modules/eslint/lib/rules/key-spacing.js @@ -45,7 +45,7 @@ function isSingleLine(node) { /** * Checks whether the properties on a single line. * @param {ASTNode[]} properties List of Property AST nodes. - * @returns {boolean} True if all properies is on a single line. + * @returns {boolean} True if all properties is on a single line. */ function isSingleLineProperties(properties) { const [firstProp] = properties, diff --git a/tools/node_modules/eslint/lib/rules/new-cap.js b/tools/node_modules/eslint/lib/rules/new-cap.js index 7cce968c5aed0e..0faf45efb92daf 100644 --- a/tools/node_modules/eslint/lib/rules/new-cap.js +++ b/tools/node_modules/eslint/lib/rules/new-cap.js @@ -235,7 +235,7 @@ module.exports = { callee = callee.property; } - context.report({ node, loc: callee.loc.start, messageId }); + context.report({ node, loc: callee.loc, messageId }); } //-------------------------------------------------------------------------- diff --git a/tools/node_modules/eslint/lib/rules/newline-per-chained-call.js b/tools/node_modules/eslint/lib/rules/newline-per-chained-call.js index 8ad88386c0f61d..4254fec185ef88 100644 --- a/tools/node_modules/eslint/lib/rules/newline-per-chained-call.js +++ b/tools/node_modules/eslint/lib/rules/newline-per-chained-call.js @@ -90,16 +90,19 @@ module.exports = { } if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) { + const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); + context.report({ node: callee.property, - loc: callee.property.loc.start, + loc: { + start: firstTokenAfterObject.loc.start, + end: callee.loc.end + }, messageId: "expected", data: { callee: getPropertyText(callee) }, fix(fixer) { - const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); - return fixer.insertTextBefore(firstTokenAfterObject, "\n"); } }); diff --git a/tools/node_modules/eslint/lib/rules/no-buffer-constructor.js b/tools/node_modules/eslint/lib/rules/no-buffer-constructor.js index bf4c8891ad1adf..5dce047b92312e 100644 --- a/tools/node_modules/eslint/lib/rules/no-buffer-constructor.js +++ b/tools/node_modules/eslint/lib/rules/no-buffer-constructor.js @@ -10,6 +10,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-deprecated-api"], + type: "problem", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-empty-function.js b/tools/node_modules/eslint/lib/rules/no-empty-function.js index c74321158b3464..c512f8cd5f4500 100644 --- a/tools/node_modules/eslint/lib/rules/no-empty-function.js +++ b/tools/node_modules/eslint/lib/rules/no-empty-function.js @@ -151,7 +151,7 @@ module.exports = { ) { context.report({ node, - loc: node.body.loc.start, + loc: node.body.loc, messageId: "unexpected", data: { name } }); diff --git a/tools/node_modules/eslint/lib/rules/no-extra-parens.js b/tools/node_modules/eslint/lib/rules/no-extra-parens.js index a3dd5bab699da3..7cbb7522ebedfa 100644 --- a/tools/node_modules/eslint/lib/rules/no-extra-parens.js +++ b/tools/node_modules/eslint/lib/rules/no-extra-parens.js @@ -560,7 +560,11 @@ module.exports = { tokensToIgnore.add(secondToken); } - if (hasExcessParens(node)) { + const hasExtraParens = node.parent.type === "ExportDefaultDeclaration" + ? hasExcessParensWithPrecedence(node, PRECEDENCE_OF_ASSIGNMENT_EXPR) + : hasExcessParens(node); + + if (hasExtraParens) { report(node); } } diff --git a/tools/node_modules/eslint/lib/rules/no-inner-declarations.js b/tools/node_modules/eslint/lib/rules/no-inner-declarations.js index e1c29e0a3b4f3f..0768bc61149cec 100644 --- a/tools/node_modules/eslint/lib/rules/no-inner-declarations.js +++ b/tools/node_modules/eslint/lib/rules/no-inner-declarations.js @@ -5,10 +5,19 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("./utils/ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ +const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]); +const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); + module.exports = { meta: { type: "problem", @@ -33,54 +42,37 @@ module.exports = { create(context) { - /** - * Find the nearest Program or Function ancestor node. - * @returns {Object} Ancestor's type and distance from node. - */ - function nearestBody() { - const ancestors = context.getAncestors(); - let ancestor = ancestors.pop(), - generation = 1; - - while (ancestor && ["Program", "FunctionDeclaration", - "FunctionExpression", "ArrowFunctionExpression" - ].indexOf(ancestor.type) < 0) { - generation += 1; - ancestor = ancestors.pop(); - } - - return { - - // Type of containing ancestor - type: ancestor.type, - - // Separation between ancestor and node - distance: generation - }; - } - /** * Ensure that a given node is at a program or function body's root. * @param {ASTNode} node Declaration node to check. * @returns {void} */ function check(node) { - const body = nearestBody(), - valid = ((body.type === "Program" && body.distance === 1) || - body.distance === 2); - - if (!valid) { - context.report({ - node, - messageId: "moveDeclToRoot", - data: { - type: (node.type === "FunctionDeclaration" ? "function" : "variable"), - body: (body.type === "Program" ? "program" : "function body") - } - }); + const parent = node.parent; + + if ( + parent.type === "BlockStatement" && validBlockStatementParent.has(parent.parent.type) + ) { + return; + } + + if (validParent.has(parent.type)) { + return; } + + const upperFunction = astUtils.getUpperFunction(parent); + + context.report({ + node, + messageId: "moveDeclToRoot", + data: { + type: (node.type === "FunctionDeclaration" ? "function" : "variable"), + body: (upperFunction === null ? "program" : "function body") + } + }); } + return { FunctionDeclaration: check, diff --git a/tools/node_modules/eslint/lib/rules/no-lone-blocks.js b/tools/node_modules/eslint/lib/rules/no-lone-blocks.js index d7069887b8e460..290784b82ea2fb 100644 --- a/tools/node_modules/eslint/lib/rules/no-lone-blocks.js +++ b/tools/node_modules/eslint/lib/rules/no-lone-blocks.js @@ -49,7 +49,7 @@ module.exports = { } /** - * Checks for any ocurrence of a BlockStatement in a place where lists of statements can appear + * Checks for any occurrence of a BlockStatement in a place where lists of statements can appear * @param {ASTNode} node The node to check * @returns {boolean} True if the node is a lone block. */ diff --git a/tools/node_modules/eslint/lib/rules/no-mixed-requires.js b/tools/node_modules/eslint/lib/rules/no-mixed-requires.js index 8e988e32c24f84..bfe9b7aa97858a 100644 --- a/tools/node_modules/eslint/lib/rules/no-mixed-requires.js +++ b/tools/node_modules/eslint/lib/rules/no-mixed-requires.js @@ -11,6 +11,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-mixed-requires"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-new-object.js b/tools/node_modules/eslint/lib/rules/no-new-object.js index f3e99c9bd13502..e9f915db5eaa91 100644 --- a/tools/node_modules/eslint/lib/rules/no-new-object.js +++ b/tools/node_modules/eslint/lib/rules/no-new-object.js @@ -5,6 +5,12 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("./utils/ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -28,10 +34,17 @@ module.exports = { }, create(context) { - return { - NewExpression(node) { + const variable = astUtils.getVariableByName( + context.getScope(), + node.callee.name + ); + + if (variable && variable.identifiers.length > 0) { + return; + } + if (node.callee.name === "Object") { context.report({ node, @@ -40,6 +53,5 @@ module.exports = { } } }; - } }; diff --git a/tools/node_modules/eslint/lib/rules/no-new-require.js b/tools/node_modules/eslint/lib/rules/no-new-require.js index df12a424e3527e..7f81e83fd782c3 100644 --- a/tools/node_modules/eslint/lib/rules/no-new-require.js +++ b/tools/node_modules/eslint/lib/rules/no-new-require.js @@ -11,6 +11,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-new-require"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-path-concat.js b/tools/node_modules/eslint/lib/rules/no-path-concat.js index 9fa8b852fe8358..77a03a7f952b04 100644 --- a/tools/node_modules/eslint/lib/rules/no-path-concat.js +++ b/tools/node_modules/eslint/lib/rules/no-path-concat.js @@ -10,6 +10,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-path-concat"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-process-env.js b/tools/node_modules/eslint/lib/rules/no-process-env.js index 0f8d7f8a339d0e..24bb9f9971d5c9 100644 --- a/tools/node_modules/eslint/lib/rules/no-process-env.js +++ b/tools/node_modules/eslint/lib/rules/no-process-env.js @@ -10,6 +10,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-process-env"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-process-exit.js b/tools/node_modules/eslint/lib/rules/no-process-exit.js index 29871660cc6ee1..9c70ea8808b4c4 100644 --- a/tools/node_modules/eslint/lib/rules/no-process-exit.js +++ b/tools/node_modules/eslint/lib/rules/no-process-exit.js @@ -10,6 +10,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-process-exit"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-modules.js b/tools/node_modules/eslint/lib/rules/no-restricted-modules.js index abd8d5cbe29381..61834ceeb444d3 100644 --- a/tools/node_modules/eslint/lib/rules/no-restricted-modules.js +++ b/tools/node_modules/eslint/lib/rules/no-restricted-modules.js @@ -40,6 +40,10 @@ const arrayOfStringsOrObjects = { module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-restricted-require"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-sync.js b/tools/node_modules/eslint/lib/rules/no-sync.js index d8111059631734..9790d1f94bb20c 100644 --- a/tools/node_modules/eslint/lib/rules/no-sync.js +++ b/tools/node_modules/eslint/lib/rules/no-sync.js @@ -13,6 +13,10 @@ module.exports = { meta: { + deprecated: true, + + replacedBy: ["node/no-sync"], + type: "suggestion", docs: { diff --git a/tools/node_modules/eslint/lib/rules/no-unexpected-multiline.js b/tools/node_modules/eslint/lib/rules/no-unexpected-multiline.js index eb72008a2947e7..b5ec20de4b20a3 100644 --- a/tools/node_modules/eslint/lib/rules/no-unexpected-multiline.js +++ b/tools/node_modules/eslint/lib/rules/no-unexpected-multiline.js @@ -53,7 +53,11 @@ module.exports = { const nodeExpressionEnd = sourceCode.getTokenBefore(openParen); if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { - context.report({ node, loc: openParen.loc.start, messageId, data: { char: openParen.value } }); + context.report({ + node, + loc: openParen.loc, + messageId + }); } } @@ -71,18 +75,24 @@ module.exports = { }, TaggedTemplateExpression(node) { - if (node.tag.loc.end.line === node.quasi.loc.start.line) { - return; - } - - // handle generics type parameters on template tags - const tokenBefore = sourceCode.getTokenBefore(node.quasi); - - if (tokenBefore.loc.end.line === node.quasi.loc.start.line) { - return; + const { quasi } = node; + + // handles common tags, parenthesized tags, and typescript's generic type arguments + const tokenBefore = sourceCode.getTokenBefore(quasi); + + if (tokenBefore.loc.end.line !== quasi.loc.start.line) { + context.report({ + node, + loc: { + start: quasi.loc.start, + end: { + line: quasi.loc.start.line, + column: quasi.loc.start.column + 1 + } + }, + messageId: "taggedTemplate" + }); } - - context.report({ node, loc: node.loc.start, messageId: "taggedTemplate" }); }, CallExpression(node) { diff --git a/tools/node_modules/eslint/lib/rules/no-useless-concat.js b/tools/node_modules/eslint/lib/rules/no-useless-concat.js index aa46742abdd5ca..cfc60c8fb51a24 100644 --- a/tools/node_modules/eslint/lib/rules/no-useless-concat.js +++ b/tools/node_modules/eslint/lib/rules/no-useless-concat.js @@ -105,7 +105,7 @@ module.exports = { context.report({ node, - loc: operatorToken.loc.start, + loc: operatorToken.loc, messageId: "unexpectedConcat" }); } diff --git a/tools/node_modules/eslint/lib/rules/space-before-function-paren.js b/tools/node_modules/eslint/lib/rules/space-before-function-paren.js index af609c2e7c72fa..1021a110cfd3f0 100644 --- a/tools/node_modules/eslint/lib/rules/space-before-function-paren.js +++ b/tools/node_modules/eslint/lib/rules/space-before-function-paren.js @@ -127,7 +127,10 @@ module.exports = { if (hasSpacing && functionConfig === "never") { context.report({ node, - loc: leftToken.loc.end, + loc: { + start: leftToken.loc.end, + end: rightToken.loc.start + }, messageId: "unexpectedSpace", fix(fixer) { const comments = sourceCode.getCommentsBefore(rightToken); @@ -145,7 +148,7 @@ module.exports = { } else if (!hasSpacing && functionConfig === "always") { context.report({ node, - loc: leftToken.loc.end, + loc: rightToken.loc, messageId: "missingSpace", fix: fixer => fixer.insertTextAfter(leftToken, " ") }); diff --git a/tools/node_modules/eslint/lib/rules/yoda.js b/tools/node_modules/eslint/lib/rules/yoda.js index c4ff3f81938595..f1159e5255df79 100644 --- a/tools/node_modules/eslint/lib/rules/yoda.js +++ b/tools/node_modules/eslint/lib/rules/yoda.js @@ -20,7 +20,7 @@ const astUtils = require("./utils/ast-utils"); * @returns {boolean} Whether or not it is a comparison operator. */ function isComparisonOperator(operator) { - return (/^(==|===|!=|!==|<|>|<=|>=)$/u).test(operator); + return /^(==|===|!=|!==|<|>|<=|>=)$/u.test(operator); } /** @@ -29,7 +29,7 @@ function isComparisonOperator(operator) { * @returns {boolean} Whether or not it is an equality operator. */ function isEqualityOperator(operator) { - return (/^(==|===)$/u).test(operator); + return /^(==|===)$/u.test(operator); } /** @@ -50,10 +50,12 @@ function isRangeTestOperator(operator) { * real literal and should be treated as such. */ function isNegativeNumericLiteral(node) { - return (node.type === "UnaryExpression" && + return ( + node.type === "UnaryExpression" && node.operator === "-" && node.prefix && - astUtils.isNumericLiteral(node.argument)); + astUtils.isNumericLiteral(node.argument) + ); } /** @@ -71,25 +73,21 @@ function isStaticTemplateLiteral(node) { * @returns {boolean} True if the node should be treated as a single Literal node. */ function looksLikeLiteral(node) { - return isNegativeNumericLiteral(node) || - isStaticTemplateLiteral(node); + return isNegativeNumericLiteral(node) || isStaticTemplateLiteral(node); } /** * Attempts to derive a Literal node from nodes that are treated like literals. * @param {ASTNode} node Node to normalize. - * @param {number} [defaultValue] The default value to be returned if the node - * is not a Literal. * @returns {ASTNode} One of the following options. * 1. The original node if the node is already a Literal * 2. A normalized Literal node with the negative number as the value if the * node represents a negative number literal. * 3. A normalized Literal node with the string as the value if the node is * a Template Literal without expression. - * 4. The Literal node which has the `defaultValue` argument if it exists. - * 5. Otherwise `null`. + * 4. Otherwise `null`. */ -function getNormalizedLiteral(node, defaultValue) { +function getNormalizedLiteral(node) { if (node.type === "Literal") { return node; } @@ -110,14 +108,6 @@ function getNormalizedLiteral(node, defaultValue) { }; } - if (defaultValue) { - return { - type: "Literal", - value: defaultValue, - raw: String(defaultValue) - }; - } - return null; } @@ -183,7 +173,7 @@ module.exports = { type: "suggestion", docs: { - description: "require or disallow \"Yoda\" conditions", + description: 'require or disallow "Yoda" conditions', category: "Best Practices", recommended: false, url: "https://eslint.org/docs/rules/yoda" @@ -211,16 +201,19 @@ module.exports = { fixable: "code", messages: { - expected: "Expected literal to be on the {{expectedSide}} side of {{operator}}." + expected: + "Expected literal to be on the {{expectedSide}} side of {{operator}}." } }, create(context) { // Default to "never" (!always) if no option - const always = (context.options[0] === "always"); - const exceptRange = (context.options[1] && context.options[1].exceptRange); - const onlyEquality = (context.options[1] && context.options[1].onlyEquality); + const always = context.options[0] === "always"; + const exceptRange = + context.options[1] && context.options[1].exceptRange; + const onlyEquality = + context.options[1] && context.options[1].onlyEquality; const sourceCode = context.getSourceCode(); @@ -243,13 +236,23 @@ module.exports = { * @returns {boolean} Whether node is a "between" range test. */ function isBetweenTest() { - let leftLiteral, rightLiteral; + if (node.operator === "&&" && same(left.right, right.left)) { + const leftLiteral = getNormalizedLiteral(left.left); + const rightLiteral = getNormalizedLiteral(right.right); + + if (leftLiteral === null && rightLiteral === null) { + return false; + } - return (node.operator === "&&" && - (leftLiteral = getNormalizedLiteral(left.left)) && - (rightLiteral = getNormalizedLiteral(right.right, Number.POSITIVE_INFINITY)) && - leftLiteral.value <= rightLiteral.value && - same(left.right, right.left)); + if (rightLiteral === null || leftLiteral === null) { + return true; + } + + if (leftLiteral.value <= rightLiteral.value) { + return true; + } + } + return false; } /** @@ -257,13 +260,24 @@ module.exports = { * @returns {boolean} Whether node is an "outside" range test. */ function isOutsideTest() { - let leftLiteral, rightLiteral; + if (node.operator === "||" && same(left.left, right.right)) { + const leftLiteral = getNormalizedLiteral(left.right); + const rightLiteral = getNormalizedLiteral(right.left); + + if (leftLiteral === null && rightLiteral === null) { + return false; + } + + if (rightLiteral === null || leftLiteral === null) { + return true; + } + + if (leftLiteral.value <= rightLiteral.value) { + return true; + } + } - return (node.operator === "||" && - (leftLiteral = getNormalizedLiteral(left.right, Number.NEGATIVE_INFINITY)) && - (rightLiteral = getNormalizedLiteral(right.left)) && - leftLiteral.value <= rightLiteral.value && - same(left.left, right.right)); + return false; } /** @@ -276,13 +290,15 @@ module.exports = { return astUtils.isParenthesised(sourceCode, node); } - return (node.type === "LogicalExpression" && + return ( + node.type === "LogicalExpression" && left.type === "BinaryExpression" && right.type === "BinaryExpression" && isRangeTestOperator(left.operator) && isRangeTestOperator(right.operator) && (isBetweenTest() || isOutsideTest()) && - isParenWrapped()); + isParenWrapped() + ); } const OPERATOR_FLIP_MAP = { @@ -303,21 +319,52 @@ module.exports = { */ function getFlippedString(node) { const tokenBefore = sourceCode.getTokenBefore(node); - const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); - const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]); - const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]); - const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]); + const operatorToken = sourceCode.getFirstTokenBetween( + node.left, + node.right, + token => token.value === node.operator + ); + const textBeforeOperator = sourceCode + .getText() + .slice( + sourceCode.getTokenBefore(operatorToken).range[1], + operatorToken.range[0] + ); + const textAfterOperator = sourceCode + .getText() + .slice( + operatorToken.range[1], + sourceCode.getTokenAfter(operatorToken).range[0] + ); + const leftText = sourceCode + .getText() + .slice( + node.range[0], + sourceCode.getTokenBefore(operatorToken).range[1] + ); const firstRightToken = sourceCode.getTokenAfter(operatorToken); - const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]); + const rightText = sourceCode + .getText() + .slice(firstRightToken.range[0], node.range[1]); let prefix = ""; - if (tokenBefore && tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken)) { + if ( + tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken) + ) { prefix = " "; } - return prefix + rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText; + return ( + prefix + + rightText + + textBeforeOperator + + OPERATOR_FLIP_MAP[operatorToken.value] + + textAfterOperator + + leftText + ); } //-------------------------------------------------------------------------- @@ -331,8 +378,12 @@ module.exports = { // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error. if ( - (expectedNonLiteral.type === "Literal" || looksLikeLiteral(expectedNonLiteral)) && - !(expectedLiteral.type === "Literal" || looksLikeLiteral(expectedLiteral)) && + (expectedNonLiteral.type === "Literal" || + looksLikeLiteral(expectedNonLiteral)) && + !( + expectedLiteral.type === "Literal" || + looksLikeLiteral(expectedLiteral) + ) && !(!isEqualityOperator(node.operator) && onlyEquality) && isComparisonOperator(node.operator) && !(exceptRange && isRangeTest(context.getAncestors().pop())) @@ -344,12 +395,11 @@ module.exports = { operator: node.operator, expectedSide: always ? "left" : "right" }, - fix: fixer => fixer.replaceText(node, getFlippedString(node)) + fix: fixer => + fixer.replaceText(node, getFlippedString(node)) }); } - } }; - } }; diff --git a/tools/node_modules/eslint/lib/shared/relative-module-resolver.js b/tools/node_modules/eslint/lib/shared/relative-module-resolver.js index fa6cca72361df5..80335c5cfca7c8 100644 --- a/tools/node_modules/eslint/lib/shared/relative-module-resolver.js +++ b/tools/node_modules/eslint/lib/shared/relative-module-resolver.js @@ -11,6 +11,7 @@ const Module = require("module"); * `Module.createRequire` is added in v12.2.0. It supports URL as well. * We only support the case where the argument is a filepath, not a URL. */ +// eslint-disable-next-line node/no-unsupported-features/node-builtins, node/no-deprecated-api const createRequire = Module.createRequire || Module.createRequireFromPath; module.exports = { diff --git a/tools/node_modules/eslint/lib/shared/types.js b/tools/node_modules/eslint/lib/shared/types.js index bf37327fa240ca..bbd95d1b37862f 100644 --- a/tools/node_modules/eslint/lib/shared/types.js +++ b/tools/node_modules/eslint/lib/shared/types.js @@ -141,3 +141,10 @@ module.exports = {}; * @property {Record} [processors] The definition of plugin processors. * @property {Record} [rules] The definition of plugin rules. */ + +/** + * Information of deprecated rules. + * @typedef {Object} DeprecatedRuleInfo + * @property {string} ruleId The rule ID. + * @property {string[]} replacedBy The rule IDs that replace this deprecated rule. + */ diff --git a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/lib/identifier.js b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/lib/identifier.js index 92043ce6630710..51ec76370ccfc6 100644 --- a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/lib/identifier.js +++ b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/lib/identifier.js @@ -73,5 +73,5 @@ function isIdentifierName(name) { } } - return true; + return !isFirst; } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json index bdc69e6c6f8926..da8c4e12d40ff7 100644 --- a/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json +++ b/tools/node_modules/eslint/node_modules/@babel/helper-validator-identifier/package.json @@ -7,7 +7,7 @@ "unicode-13.0.0": "^0.8.0" }, "exports": "./lib/index.js", - "gitHead": "8d5e422be27251cfaadf8dd2536b31b4a5024b02", + "gitHead": "5b97e77e030cf3853a147fdff81844ea4026219d", "license": "MIT", "main": "./lib/index.js", "name": "@babel/helper-validator-identifier", @@ -18,5 +18,5 @@ "type": "git", "url": "https://github.com/babel/babel/tree/master/packages/babel-helper-validator-identifier" }, - "version": "7.9.0" + "version": "7.9.5" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/ajv/README.md b/tools/node_modules/eslint/node_modules/ajv/README.md index 9bd1f571872a26..e13fdec2939c92 100644 --- a/tools/node_modules/eslint/node_modules/ajv/README.md +++ b/tools/node_modules/eslint/node_modules/ajv/README.md @@ -8,8 +8,49 @@ The fastest JSON Schema validator for Node.js and browser. Supports draft-04/06/ [![npm](https://img.shields.io/npm/v/ajv.svg)](https://www.npmjs.com/package/ajv) [![npm downloads](https://img.shields.io/npm/dm/ajv.svg)](https://www.npmjs.com/package/ajv) [![Coverage Status](https://coveralls.io/repos/epoberezkin/ajv/badge.svg?branch=master&service=github)](https://coveralls.io/github/epoberezkin/ajv?branch=master) -[![Greenkeeper badge](https://badges.greenkeeper.io/epoberezkin/ajv.svg)](https://greenkeeper.io/) [![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv) +[![GitHub Sponsors](https://img.shields.io/badge/$-sponsors-brightgreen)](https://github.com/sponsors/epoberezkin) + +## Please [sponsor Ajv](https://github.com/sponsors/epoberezkin) + +Dear Ajv users! ❤️ + +I ask you to support the development of Ajv with donations. 🙏 + +Since 2015 Ajv has become widely used, thanks to your help and contributions: + +- **90** contributors 🏗 +- **5,000** dependent npm packages ⚙️ +- **7,000** github stars, from GitHub users [all over the world](https://www.google.com/maps/d/u/0/viewer?mid=1MGRV8ciFUGIbO1l0EKFWNJGYE7iSkDxP&ll=-3.81666561775622e-14%2C4.821737100000007&z=2) ⭐️ +- **5,000,000** dependent repositories on GitHub 🚀 +- **120,000,000** npm downloads per month! 💯 + +Your donations will fund futher development - small and large improvements, support of the next versions of JSON Schema specification, and, possibly, the code should be migrated to TypeScript to make it more maintainable. + +I will greatly appreciate anything you can help with to make it happen: + +- a **personal** donation - from $2 ☕️ +- your **company** donation - from $10 🍔 +- a **sponsorship** to get promoted on Ajv or related packages - from $50 💰 +- an **introduction** to a sponsor who would benefit from the promotion on Ajv page 🤝 + +| Please [make donations via my GitHub sponsors page](https://github.com/sponsors/epoberezkin)
‼️ **GitHub will DOUBLE them** ‼️ | +|---| + +#### Open Collective sponsors + + + + + + + + + + + + + ## Using version 6 @@ -273,7 +314,7 @@ The following formats are implemented for string validation with "format" keywor __Please note__: JSON Schema draft-07 also defines formats `iri`, `iri-reference`, `idn-hostname` and `idn-email` for URLs, hostnames and emails with international characters. Ajv does not implement these formats. If you create Ajv plugin that implements them please make a PR to mention this plugin here. -There are two modes of format validation: `fast` and `full`. This mode affects formats `date`, `time`, `date-time`, `uri`, `uri-reference`, `email`, and `hostname`. See [Options](#options) for details. +There are two modes of format validation: `fast` and `full`. This mode affects formats `date`, `time`, `date-time`, `uri`, `uri-reference`, and `email`. See [Options](#options) for details. You can add additional formats and replace any of the formats above using [addFormat](#api-addformat) method. @@ -1340,7 +1381,7 @@ If you have published a useful plugin please submit a PR to add it to the next s - [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) - plugin with custom validation keywords (select, typeof, etc.) - [ajv-merge-patch](https://github.com/epoberezkin/ajv-merge-patch) - plugin with keywords $merge and $patch - [ajv-pack](https://github.com/epoberezkin/ajv-pack) - produces a compact module exporting validation functions - +- [ajv-formats-draft2019](https://github.com/luzlab/ajv-formats-draft2019) - format validators for draft2019 that aren't already included in ajv (ie. `idn-hostname`, `idn-email`, `iri`, `iri-reference` and `duration`). ## Some packages using Ajv diff --git a/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js b/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js index 157af21a92cda5..1c72a75ecfc321 100644 --- a/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js +++ b/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js @@ -1,3 +1,3 @@ -/* ajv 6.12.0: Another JSON Schema Validator */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Ajv=e()}}(function(){return function o(i,n,l){function c(r,e){if(!n[r]){if(!i[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(u)return u(r,!0);var a=new Error("Cannot find module '"+r+"'");throw a.code="MODULE_NOT_FOUND",a}var s=n[r]={exports:{}};i[r][0].call(s.exports,function(e){return c(i[r][1][e]||e)},s,s.exports,o,i,n,l)}return n[r].exports}for(var u="function"==typeof require&&require,e=0;e%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,u=/^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,h=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,d=/^(?:\/(?:[^~/]|~0|~1)*)*$/,f=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,p=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;function m(e){return a.copy(m[e="full"==e?"full":"fast"])}function v(e){var r=e.match(o);if(!r)return!1;var t,a=+r[2],s=+r[3];return 1<=a&&a<=12&&1<=s&&s<=(2!=a||((t=+r[1])%4!=0||t%100==0&&t%400!=0)?i[a]:29)}function y(e,r){var t=e.match(n);if(!t)return!1;var a=t[1],s=t[2],o=t[3];return(a<=23&&s<=59&&o<=59||23==a&&59==s&&60==o)&&(!r||t[5])}(r.exports=m).fast={date:/^\d\d\d\d-[0-1]\d-[0-3]\d$/,time:/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i,"date-time":/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i,uri:/^(?:[a-z][a-z0-9+-.]*:)(?:\/?\/)?[^\s]*$/i,"uri-reference":/^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p},m.full={date:v,time:y,"date-time":function(e){var r=e.split(g);return 2==r.length&&v(r[0])&&y(r[1],!0)},uri:function(e){return P.test(e)&&l.test(e)},"uri-reference":/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p};var g=/t|\s/i;var P=/\/|:/;var E=/[^\\]\\Z/;function w(e){if(E.test(e))return!1;try{return new RegExp(e),!0}catch(e){return!1}}},{"./util":10}],5:[function(e,r,t){"use strict";var j=e("./resolve"),O=e("./util"),I=e("./error_classes"),A=e("fast-json-stable-stringify"),C=e("../dotjs/validate"),k=O.ucs2length,L=e("fast-deep-equal"),z=I.Validation;function T(e,r,t){var a=s.call(this,e,r,t);return 0<=a?{index:a,compiling:!0}:{index:a=this._compilations.length,compiling:!(this._compilations[a]={schema:e,root:r,baseId:t})}}function q(e,r,t){var a=s.call(this,e,r,t);0<=a&&this._compilations.splice(a,1)}function s(e,r,t){for(var a=0;a",y=d?">":"<",g=void 0;if(m){var P=e.util.getData(p.$data,o,e.dataPathArr),E="exclusive"+s,w="exclType"+s,b="exclIsNumber"+s,S="' + "+(x="op"+s)+" + '";a+=" var schemaExcl"+s+" = "+P+"; ";var _;g=f;(_=_||[]).push(a+=" var "+E+"; var "+w+" = typeof "+(P="schemaExcl"+s)+"; if ("+w+" != 'boolean' && "+w+" != 'undefined' && "+w+" != 'number') { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(g||"_exclusiveLimit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: '"+f+" should be boolean' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var F=a;a=_.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+F+"]); ":" validate.errors = ["+F+"]; return false; ":" var err = "+F+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } else if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" "+w+" == 'number' ? ( ("+E+" = "+t+" === undefined || "+P+" "+v+"= "+t+") ? "+u+" "+y+"= "+P+" : "+u+" "+y+" "+t+" ) : ( ("+E+" = "+P+" === true) ? "+u+" "+y+"= "+t+" : "+u+" "+y+" "+t+" ) || "+u+" !== "+u+") { var op"+s+" = "+E+" ? '"+v+"' : '"+v+"='; ",void 0===i&&(l=e.errSchemaPath+"/"+(g=f),t=P,h=m)}else{S=v;if((b="number"==typeof p)&&h){var x="'"+S+"'";a+=" if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" ( "+t+" === undefined || "+p+" "+v+"= "+t+" ? "+u+" "+y+"= "+p+" : "+u+" "+y+" "+t+" ) || "+u+" !== "+u+") { "}else{b&&void 0===i?(E=!0,l=e.errSchemaPath+"/"+(g=f),t=p,y+="="):(b&&(t=Math[d?"min":"max"](p,i)),p===(!b||t)?(E=!0,l=e.errSchemaPath+"/"+(g=f),y+="="):(E=!1,S+="="));x="'"+S+"'";a+=" if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" "+u+" "+y+" "+t+" || "+u+" !== "+u+") { "}}g=g||r,(_=_||[]).push(a),a="",!1!==e.createErrors?(a+=" { keyword: '"+(g||"_limit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { comparison: "+x+", limit: "+t+", exclusive: "+E+" } ",!1!==e.opts.messages&&(a+=" , message: 'should be "+S+" ",a+=h?"' + "+t:t+"'"),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";F=a;return a=_.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+F+"]); ":" validate.errors = ["+F+"]; return false; ":" var err = "+F+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } ",c&&(a+=" else { "),a}},{}],14:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || ");var d=r,f=f||[];f.push(a+=" "+u+".length "+("maxItems"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitItems")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have ",a+="maxItems"==r?"more":"fewer",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" items' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],15:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=!1===e.opts.unicode?" "+u+".length ":" ucs2length("+u+") ";var d=r,f=f||[];f.push(a+=" "+("maxLength"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitLength")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be ",a+="maxLength"==r?"longer":"shorter",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" characters' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],16:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || ");var d=r,f=f||[];f.push(a+=" Object.keys("+u+").length "+("maxProperties"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitProperties")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have ",a+="maxProperties"==r?"more":"fewer",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" properties' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],17:[function(e,r,t){"use strict";r.exports=function(e,r){var t=" ",a=e.schema[r],s=e.schemaPath+e.util.getProperty(r),o=e.errSchemaPath+"/"+r,i=!e.opts.allErrors,n=e.util.copy(e),l="";n.level++;var c="valid"+n.level,u=n.baseId,h=!0,d=a;if(d)for(var f,p=-1,m=d.length-1;p "+F+") { ";var $=c+"["+F+"]";d.schema=_,d.schemaPath=i+"["+F+"]",d.errSchemaPath=n+"/"+F,d.errorPath=e.util.getPathExpr(e.errorPath,F,e.opts.jsonPointers,!0),d.dataPathArr[v]=F;var R=e.validate(d);d.baseId=g,e.util.varOccurences(R,y)<2?t+=" "+e.util.varReplace(R,y,$)+" ":t+=" var "+y+" = "+$+"; "+R+" ",t+=" } ",l&&(t+=" if ("+p+") { ",f+="}")}if("object"==typeof P&&(e.opts.strictKeywords?"object"==typeof P&&0 "+o.length+") { for (var "+m+" = "+o.length+"; "+m+" < "+c+".length; "+m+"++) { ",d.errorPath=e.util.getPathExpr(e.errorPath,m,e.opts.jsonPointers,!0);$=c+"["+m+"]";d.dataPathArr[v]=m;R=e.validate(d);d.baseId=g,e.util.varOccurences(R,y)<2?t+=" "+e.util.varReplace(R,y,$)+" ":t+=" var "+y+" = "+$+"; "+R+" ",l&&(t+=" if (!"+p+") break; "),t+=" } } ",l&&(t+=" if ("+p+") { ",f+="}")}}else if(e.opts.strictKeywords?"object"==typeof o&&0 1e-"+e.opts.multipleOfPrecision+" ":" division"+s+" !== parseInt(division"+s+") ",a+=" ) ",h&&(a+=" ) ");var d=d||[];d.push(a+=" ) { "),a="",!1!==e.createErrors?(a+=" { keyword: 'multipleOf' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { multipleOf: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should be multiple of ",a+=h?"' + "+t:t+"'"),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var f=a;return a=d.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+f+"]); ":" validate.errors = ["+f+"]; return false; ":" var err = "+f+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],30:[function(e,r,t){"use strict";r.exports=function(e,r){var t=" ",a=e.level,s=e.dataLevel,o=e.schema[r],i=e.schemaPath+e.util.getProperty(r),n=e.errSchemaPath+"/"+r,l=!e.opts.allErrors,c="data"+(s||""),u="errs__"+a,h=e.util.copy(e);h.level++;var d="valid"+h.level;if(e.opts.strictKeywords?"object"==typeof o&&0 1) { ";var f=e.schema.items&&e.schema.items.type,p=Array.isArray(f);if(!f||"object"==f||"array"==f||p&&(0<=f.indexOf("object")||0<=f.indexOf("array")))a+=" outer: for (;i--;) { for (j = i; j--;) { if (equal("+u+"[i], "+u+"[j])) { "+h+" = false; break outer; } } } ";else a+=" var itemIndices = {}, item; for (;i--;) { var item = "+u+"[i]; ",a+=" if ("+e.util["checkDataType"+(p?"s":"")](f,"item",!0)+") continue; ",p&&(a+=" if (typeof item == 'string') item = '\"' + item; "),a+=" if (typeof itemIndices[item] == 'number') { "+h+" = false; j = itemIndices[item]; break; } itemIndices[item] = i; } ";a+=" } ",d&&(a+=" } ");var m=m||[];m.push(a+=" if (!"+h+") { "),a="",!1!==e.createErrors?(a+=" { keyword: 'uniqueItems' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { i: i, j: j } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)' "),e.opts.verbose&&(a+=" , schema: ",a+=d?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var v=a;a=m.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+v+"]); ":" validate.errors = ["+v+"]; return false; ":" var err = "+v+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } ",c&&(a+=" else { ")}else c&&(a+=" if (true) { ");return a}},{}],38:[function(e,r,t){"use strict";r.exports=function(a,e){var r="",t=!0===a.schema.$async,s=a.util.schemaHasRulesExcept(a.schema,a.RULES.all,"$ref"),o=a.self._getId(a.schema);if(a.opts.strictKeywords){var i=a.util.schemaUnknownRules(a.schema,a.RULES.keywords);if(i){var n="unknown keyword: "+i;if("log"!==a.opts.strictKeywords)throw new Error(n);a.logger.warn(n)}}if(a.isTop&&(r+=" var validate = ",t&&(a.async=!0,r+="async "),r+="function(data, dataPath, parentData, parentDataProperty, rootData) { 'use strict'; ",o&&(a.opts.sourceCode||a.opts.processCode)&&(r+=" /*# sourceURL="+o+" */ ")),"boolean"==typeof a.schema||!s&&!a.schema.$ref){var l=a.level,c=a.dataLevel,u=a.schema[e="false schema"],h=a.schemaPath+a.util.getProperty(e),d=a.errSchemaPath+"/"+e,f=!a.opts.allErrors,p="data"+(c||""),m="valid"+l;if(!1===a.schema){a.isTop?f=!0:r+=" var "+m+" = false; ",(Z=Z||[]).push(r),r="",!1!==a.createErrors?(r+=" { keyword: 'false schema' , dataPath: (dataPath || '') + "+a.errorPath+" , schemaPath: "+a.util.toQuotedString(d)+" , params: {} ",!1!==a.opts.messages&&(r+=" , message: 'boolean schema is false' "),a.opts.verbose&&(r+=" , schema: false , parentSchema: validate.schema"+a.schemaPath+" , data: "+p+" "),r+=" } "):r+=" {} ";var v=r;r=Z.pop(),r+=!a.compositeRule&&f?a.async?" throw new ValidationError(["+v+"]); ":" validate.errors = ["+v+"]; return false; ":" var err = "+v+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; "}else r+=a.isTop?t?" return data; ":" validate.errors = null; return true; ":" var "+m+" = true; ";return a.isTop&&(r+=" }; return validate; "),r}if(a.isTop){var y=a.isTop;l=a.level=0,c=a.dataLevel=0,p="data";if(a.rootId=a.resolve.fullPath(a.self._getId(a.root.schema)),a.baseId=a.baseId||a.rootId,delete a.isTop,a.dataPathArr=[void 0],void 0!==a.schema.default&&a.opts.useDefaults&&a.opts.strictDefaults){var g="default is ignored in the schema root";if("log"!==a.opts.strictDefaults)throw new Error(g);a.logger.warn(g)}r+=" var vErrors = null; ",r+=" var errors = 0; ",r+=" if (rootData === undefined) rootData = data; "}else{l=a.level,p="data"+((c=a.dataLevel)||"");if(o&&(a.baseId=a.resolve.url(a.baseId,o)),t&&!a.async)throw new Error("async schema in sync schema");r+=" var errs_"+l+" = errors;"}m="valid"+l,f=!a.opts.allErrors;var P="",E="",w=a.schema.type,b=Array.isArray(w);if(w&&a.opts.nullable&&!0===a.schema.nullable&&(b?-1==w.indexOf("null")&&(w=w.concat("null")):"null"!=w&&(w=[w,"null"],b=!0)),b&&1==w.length&&(w=w[0],b=!1),a.schema.$ref&&s){if("fail"==a.opts.extendRefs)throw new Error('$ref: validation keywords used in schema at path "'+a.errSchemaPath+'" (see option extendRefs)');!0!==a.opts.extendRefs&&(s=!1,a.logger.warn('$ref: keywords ignored in schema at path "'+a.errSchemaPath+'"'))}if(a.schema.$comment&&a.opts.$comment&&(r+=" "+a.RULES.all.$comment.code(a,"$comment")),w){if(a.opts.coerceTypes)var S=a.util.coerceToTypes(a.opts.coerceTypes,w);var _=a.RULES.types[w];if(S||b||!0===_||_&&!G(_)){h=a.schemaPath+".type",d=a.errSchemaPath+"/type",h=a.schemaPath+".type",d=a.errSchemaPath+"/type";if(r+=" if ("+a.util[b?"checkDataTypes":"checkDataType"](w,p,!0)+") { ",S){var F="dataType"+l,x="coerced"+l;r+=" var "+F+" = typeof "+p+"; ","array"==a.opts.coerceTypes&&(r+=" if ("+F+" == 'object' && Array.isArray("+p+")) "+F+" = 'array'; "),r+=" var "+x+" = undefined; ";var $="",R=S;if(R)for(var D,j=-1,O=R.length-1;j= 0x80 (not a basic code point)","invalid-input":"Invalid input"},C=Math.floor,k=String.fromCharCode;function L(e){throw new RangeError(i[e])}function n(e,r){var t=e.split("@"),a="";return 1>1,e+=C(e/r);455C((A-s)/h))&&L("overflow"),s+=f*h;var p=d<=i?1:i+26<=d?26:d-i;if(fC(A/m)&&L("overflow"),h*=m}var v=t.length+1;i=q(s-u,v,0==u),C(s/v)>A-o&&L("overflow"),o+=C(s/v),s%=v,t.splice(s++,0,o)}return String.fromCodePoint.apply(String,t)}function c(e){var r=[],t=(e=z(e)).length,a=128,s=0,o=72,i=!0,n=!1,l=void 0;try{for(var c,u=e[Symbol.iterator]();!(i=(c=u.next()).done);i=!0){var h=c.value;h<128&&r.push(k(h))}}catch(e){n=!0,l=e}finally{try{!i&&u.return&&u.return()}finally{if(n)throw l}}var d=r.length,f=d;for(d&&r.push("-");fC((A-s)/w)&&L("overflow"),s+=(p-a)*w,a=p;var b=!0,S=!1,_=void 0;try{for(var F,x=e[Symbol.iterator]();!(b=(F=x.next()).done);b=!0){var $=F.value;if($A&&L("overflow"),$==a){for(var R=s,D=36;;D+=36){var j=D<=o?1:o+26<=D?26:D-o;if(R>6|192).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase():"%"+(r>>12|224).toString(16).toUpperCase()+"%"+(r>>6&63|128).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase()}function f(e){for(var r="",t=0,a=e.length;tA-Z\\x5E-\\x7E]",'[\\"\\\\]')),M=new RegExp(V,"g"),B=new RegExp("(?:(?:%[EFef][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f])|(?:%[89A-Fa-f][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f])|(?:%[0-9A-Fa-f][0-9A-Fa-f]))","g"),G=new RegExp(J("[^]","[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]","[\\.]",'[\\"]',K),"g"),Y=new RegExp(J("[^]",V,"[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"),"g"),W=Y;function X(e){var r=f(e);return r.match(M)?r:e}var ee={scheme:"mailto",parse:function(e,r){var t=e,a=t.to=t.path?t.path.split(","):[];if(t.path=void 0,t.query){for(var s=!1,o={},i=t.query.split("&"),n=0,l=i.length;n%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,u=/^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,h=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,d=/^(?:\/(?:[^~/]|~0|~1)*)*$/,f=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,p=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;function m(e){return a.copy(m[e="full"==e?"full":"fast"])}function v(e){var r=e.match(o);if(!r)return!1;var t,a=+r[2],s=+r[3];return 1<=a&&a<=12&&1<=s&&s<=(2!=a||((t=+r[1])%4!=0||t%100==0&&t%400!=0)?i[a]:29)}function y(e,r){var t=e.match(n);if(!t)return!1;var a=t[1],s=t[2],o=t[3];return(a<=23&&s<=59&&o<=59||23==a&&59==s&&60==o)&&(!r||t[5])}(r.exports=m).fast={date:/^\d\d\d\d-[0-1]\d-[0-3]\d$/,time:/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i,"date-time":/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i,uri:/^(?:[a-z][a-z0-9+-.]*:)(?:\/?\/)?[^\s]*$/i,"uri-reference":/^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p},m.full={date:v,time:y,"date-time":function(e){var r=e.split(g);return 2==r.length&&v(r[0])&&y(r[1],!0)},uri:function(e){return P.test(e)&&l.test(e)},"uri-reference":/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p};var g=/t|\s/i;var P=/\/|:/;var E=/[^\\]\\Z/;function w(e){if(E.test(e))return!1;try{return new RegExp(e),!0}catch(e){return!1}}},{"./util":10}],5:[function(e,r,t){"use strict";var $=e("./resolve"),R=e("./util"),D=e("./error_classes"),j=e("fast-json-stable-stringify"),O=e("../dotjs/validate"),I=R.ucs2length,A=e("fast-deep-equal"),C=D.Validation;function k(e,c,u,r){var d=this,f=this._opts,h=[void 0],p={},l=[],t={},m=[],a={},v=[],s=function(e,r,t){var a=L.call(this,e,r,t);return 0<=a?{index:a,compiling:!0}:{index:a=this._compilations.length,compiling:!(this._compilations[a]={schema:e,root:r,baseId:t})}}.call(this,e,c=c||{schema:e,refVal:h,refs:p},r),o=this._compilations[s.index];if(s.compiling)return o.callValidate=P;var y=this._formats,g=this.RULES;try{var i=E(e,c,u,r);o.validate=i;var n=o.callValidate;return n&&(n.schema=i.schema,n.errors=null,n.refs=i.refs,n.refVal=i.refVal,n.root=i.root,n.$async=i.$async,f.sourceCode&&(n.source=i.source)),i}finally{(function(e,r,t){var a=L.call(this,e,r,t);0<=a&&this._compilations.splice(a,1)}).call(this,e,c,r)}function P(){var e=o.validate,r=e.apply(this,arguments);return P.errors=e.errors,r}function E(e,r,t,a){var s=!r||r&&r.schema==e;if(r.schema!=c.schema)return k.call(d,e,r,t,a);var o,i=!0===e.$async,n=O({isTop:!0,schema:e,isRoot:s,baseId:a,root:r,schemaPath:"",errSchemaPath:"#",errorPath:'""',MissingRefError:D.MissingRef,RULES:g,validate:O,util:R,resolve:$,resolveRef:w,usePattern:_,useDefault:F,useCustomRule:x,opts:f,formats:y,logger:d.logger,self:d});n=Q(h,q)+Q(l,z)+Q(m,T)+Q(v,N)+n,f.processCode&&(n=f.processCode(n));try{o=new Function("self","RULES","formats","root","refVal","defaults","customRules","equal","ucs2length","ValidationError",n)(d,g,y,c,h,m,v,A,I,C),h[0]=o}catch(e){throw d.logger.error("Error compiling schema, function code:",n),e}return o.schema=e,o.errors=null,o.refs=p,o.refVal=h,o.root=s?o:r,i&&(o.$async=!0),!0===f.sourceCode&&(o.source={code:n,patterns:l,defaults:m}),o}function w(e,r,t){r=$.url(e,r);var a,s,o=p[r];if(void 0!==o)return S(a=h[o],s="refVal["+o+"]");if(!t&&c.refs){var i=c.refs[r];if(void 0!==i)return S(a=c.refVal[i],s=b(r,a))}s=b(r);var n=$.call(d,E,c,r);if(void 0===n){var l=u&&u[r];l&&(n=$.inlineRef(l,f.inlineRefs)?l:k.call(d,l,c,u,e))}if(void 0!==n)return h[p[r]]=n,S(n,s);delete p[r]}function b(e,r){var t=h.length;return h[t]=r,"refVal"+(p[e]=t)}function S(e,r){return"object"==typeof e||"boolean"==typeof e?{code:r,schema:e,inline:!0}:{code:r,$async:e&&!!e.$async}}function _(e){var r=t[e];return void 0===r&&(r=t[e]=l.length,l[r]=e),"pattern"+r}function F(e){switch(typeof e){case"boolean":case"number":return""+e;case"string":return R.toQuotedString(e);case"object":if(null===e)return"null";var r=j(e),t=a[r];return void 0===t&&(t=a[r]=m.length,m[t]=e),"default"+t}}function x(e,r,t,a){if(!1!==d._opts.validateSchema){var s=e.definition.dependencies;if(s&&!s.every(function(e){return Object.prototype.hasOwnProperty.call(t,e)}))throw new Error("parent schema must have all required keywords: "+s.join(","));var o=e.definition.validateSchema;if(o)if(!o(r)){var i="keyword schema is invalid: "+d.errorsText(o.errors);if("log"!=d._opts.validateSchema)throw new Error(i);d.logger.error(i)}}var n,l=e.definition.compile,c=e.definition.inline,u=e.definition.macro;if(l)n=l.call(d,r,t,a);else if(u)n=u.call(d,r,t,a),!1!==f.validateSchema&&d.validateSchema(n,!0);else if(c)n=c.call(d,a,e.keyword,r,t);else if(!(n=e.definition.validate))return;if(void 0===n)throw new Error('custom keyword "'+e.keyword+'"failed to compile');var h=v.length;return{code:"customRule"+h,validate:v[h]=n}}}function L(e,r,t){for(var a=0;a",y=d?">":"<",g=void 0;if(m){var P=e.util.getData(p.$data,o,e.dataPathArr),E="exclusive"+s,w="exclType"+s,b="exclIsNumber"+s,S="' + "+(x="op"+s)+" + '";a+=" var schemaExcl"+s+" = "+P+"; ";var _;g=f;(_=_||[]).push(a+=" var "+E+"; var "+w+" = typeof "+(P="schemaExcl"+s)+"; if ("+w+" != 'boolean' && "+w+" != 'undefined' && "+w+" != 'number') { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(g||"_exclusiveLimit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: '"+f+" should be boolean' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var F=a;a=_.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+F+"]); ":" validate.errors = ["+F+"]; return false; ":" var err = "+F+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } else if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" "+w+" == 'number' ? ( ("+E+" = "+t+" === undefined || "+P+" "+v+"= "+t+") ? "+u+" "+y+"= "+P+" : "+u+" "+y+" "+t+" ) : ( ("+E+" = "+P+" === true) ? "+u+" "+y+"= "+t+" : "+u+" "+y+" "+t+" ) || "+u+" !== "+u+") { var op"+s+" = "+E+" ? '"+v+"' : '"+v+"='; ",void 0===i&&(l=e.errSchemaPath+"/"+(g=f),t=P,h=m)}else{S=v;if((b="number"==typeof p)&&h){var x="'"+S+"'";a+=" if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" ( "+t+" === undefined || "+p+" "+v+"= "+t+" ? "+u+" "+y+"= "+p+" : "+u+" "+y+" "+t+" ) || "+u+" !== "+u+") { "}else{b&&void 0===i?(E=!0,l=e.errSchemaPath+"/"+(g=f),t=p,y+="="):(b&&(t=Math[d?"min":"max"](p,i)),p===(!b||t)?(E=!0,l=e.errSchemaPath+"/"+(g=f),y+="="):(E=!1,S+="="));x="'"+S+"'";a+=" if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=" "+u+" "+y+" "+t+" || "+u+" !== "+u+") { "}}g=g||r,(_=_||[]).push(a),a="",!1!==e.createErrors?(a+=" { keyword: '"+(g||"_limit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { comparison: "+x+", limit: "+t+", exclusive: "+E+" } ",!1!==e.opts.messages&&(a+=" , message: 'should be "+S+" ",a+=h?"' + "+t:t+"'"),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";F=a;return a=_.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+F+"]); ":" validate.errors = ["+F+"]; return false; ":" var err = "+F+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } ",c&&(a+=" else { "),a}},{}],14:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || ");var d=r,f=f||[];f.push(a+=" "+u+".length "+("maxItems"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitItems")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have ",a+="maxItems"==r?"more":"fewer",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" items' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],15:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || "),a+=!1===e.opts.unicode?" "+u+".length ":" ucs2length("+u+") ";var d=r,f=f||[];f.push(a+=" "+("maxLength"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitLength")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be ",a+="maxLength"==r?"longer":"shorter",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" characters' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],16:[function(e,r,t){"use strict";r.exports=function(e,r){var t,a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h=e.opts.$data&&i&&i.$data;t=h?(a+=" var schema"+s+" = "+e.util.getData(i.$data,o,e.dataPathArr)+"; ","schema"+s):i,a+="if ( ",h&&(a+=" ("+t+" !== undefined && typeof "+t+" != 'number') || ");var d=r,f=f||[];f.push(a+=" Object.keys("+u+").length "+("maxProperties"==r?">":"<")+" "+t+") { "),a="",!1!==e.createErrors?(a+=" { keyword: '"+(d||"_limitProperties")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { limit: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have ",a+="maxProperties"==r?"more":"fewer",a+=" than ",a+=h?"' + "+t+" + '":""+i,a+=" properties' "),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var p=a;return a=f.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],17:[function(e,r,t){"use strict";r.exports=function(e,r){var t=" ",a=e.schema[r],s=e.schemaPath+e.util.getProperty(r),o=e.errSchemaPath+"/"+r,i=!e.opts.allErrors,n=e.util.copy(e),l="";n.level++;var c="valid"+n.level,u=n.baseId,h=!0,d=a;if(d)for(var f,p=-1,m=d.length-1;p "+F+") { ";var $=c+"["+F+"]";d.schema=_,d.schemaPath=i+"["+F+"]",d.errSchemaPath=n+"/"+F,d.errorPath=e.util.getPathExpr(e.errorPath,F,e.opts.jsonPointers,!0),d.dataPathArr[v]=F;var R=e.validate(d);d.baseId=g,e.util.varOccurences(R,y)<2?t+=" "+e.util.varReplace(R,y,$)+" ":t+=" var "+y+" = "+$+"; "+R+" ",t+=" } ",l&&(t+=" if ("+p+") { ",f+="}")}if("object"==typeof P&&(e.opts.strictKeywords?"object"==typeof P&&0 "+o.length+") { for (var "+m+" = "+o.length+"; "+m+" < "+c+".length; "+m+"++) { ",d.errorPath=e.util.getPathExpr(e.errorPath,m,e.opts.jsonPointers,!0);$=c+"["+m+"]";d.dataPathArr[v]=m;R=e.validate(d);d.baseId=g,e.util.varOccurences(R,y)<2?t+=" "+e.util.varReplace(R,y,$)+" ":t+=" var "+y+" = "+$+"; "+R+" ",l&&(t+=" if (!"+p+") break; "),t+=" } } ",l&&(t+=" if ("+p+") { ",f+="}")}}else if(e.opts.strictKeywords?"object"==typeof o&&0 1e-"+e.opts.multipleOfPrecision+" ":" division"+s+" !== parseInt(division"+s+") ",a+=" ) ",h&&(a+=" ) ");var d=d||[];d.push(a+=" ) { "),a="",!1!==e.createErrors?(a+=" { keyword: 'multipleOf' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { multipleOf: "+t+" } ",!1!==e.opts.messages&&(a+=" , message: 'should be multiple of ",a+=h?"' + "+t:t+"'"),e.opts.verbose&&(a+=" , schema: ",a+=h?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var f=a;return a=d.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+f+"]); ":" validate.errors = ["+f+"]; return false; ":" var err = "+f+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+="} ",c&&(a+=" else { "),a}},{}],30:[function(e,r,t){"use strict";r.exports=function(e,r){var t=" ",a=e.level,s=e.dataLevel,o=e.schema[r],i=e.schemaPath+e.util.getProperty(r),n=e.errSchemaPath+"/"+r,l=!e.opts.allErrors,c="data"+(s||""),u="errs__"+a,h=e.util.copy(e);h.level++;var d="valid"+h.level;if(e.opts.strictKeywords?"object"==typeof o&&0 1) { ";var f=e.schema.items&&e.schema.items.type,p=Array.isArray(f);if(!f||"object"==f||"array"==f||p&&(0<=f.indexOf("object")||0<=f.indexOf("array")))a+=" outer: for (;i--;) { for (j = i; j--;) { if (equal("+u+"[i], "+u+"[j])) { "+h+" = false; break outer; } } } ";else a+=" var itemIndices = {}, item; for (;i--;) { var item = "+u+"[i]; ",a+=" if ("+e.util["checkDataType"+(p?"s":"")](f,"item",!0)+") continue; ",p&&(a+=" if (typeof item == 'string') item = '\"' + item; "),a+=" if (typeof itemIndices[item] == 'number') { "+h+" = false; j = itemIndices[item]; break; } itemIndices[item] = i; } ";a+=" } ",d&&(a+=" } ");var m=m||[];m.push(a+=" if (!"+h+") { "),a="",!1!==e.createErrors?(a+=" { keyword: 'uniqueItems' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: { i: i, j: j } ",!1!==e.opts.messages&&(a+=" , message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)' "),e.opts.verbose&&(a+=" , schema: ",a+=d?"validate.schema"+n:""+i,a+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var v=a;a=m.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+v+"]); ":" validate.errors = ["+v+"]; return false; ":" var err = "+v+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } ",c&&(a+=" else { ")}else c&&(a+=" if (true) { ");return a}},{}],38:[function(e,r,t){"use strict";r.exports=function(a,e){var r="",t=!0===a.schema.$async,s=a.util.schemaHasRulesExcept(a.schema,a.RULES.all,"$ref"),o=a.self._getId(a.schema);if(a.opts.strictKeywords){var i=a.util.schemaUnknownRules(a.schema,a.RULES.keywords);if(i){var n="unknown keyword: "+i;if("log"!==a.opts.strictKeywords)throw new Error(n);a.logger.warn(n)}}if(a.isTop&&(r+=" var validate = ",t&&(a.async=!0,r+="async "),r+="function(data, dataPath, parentData, parentDataProperty, rootData) { 'use strict'; ",o&&(a.opts.sourceCode||a.opts.processCode)&&(r+=" /*# sourceURL="+o+" */ ")),"boolean"==typeof a.schema||!s&&!a.schema.$ref){var l=a.level,c=a.dataLevel,u=a.schema[e="false schema"],h=a.schemaPath+a.util.getProperty(e),d=a.errSchemaPath+"/"+e,f=!a.opts.allErrors,p="data"+(c||""),m="valid"+l;if(!1===a.schema){a.isTop?f=!0:r+=" var "+m+" = false; ",(Z=Z||[]).push(r),r="",!1!==a.createErrors?(r+=" { keyword: 'false schema' , dataPath: (dataPath || '') + "+a.errorPath+" , schemaPath: "+a.util.toQuotedString(d)+" , params: {} ",!1!==a.opts.messages&&(r+=" , message: 'boolean schema is false' "),a.opts.verbose&&(r+=" , schema: false , parentSchema: validate.schema"+a.schemaPath+" , data: "+p+" "),r+=" } "):r+=" {} ";var v=r;r=Z.pop(),r+=!a.compositeRule&&f?a.async?" throw new ValidationError(["+v+"]); ":" validate.errors = ["+v+"]; return false; ":" var err = "+v+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; "}else r+=a.isTop?t?" return data; ":" validate.errors = null; return true; ":" var "+m+" = true; ";return a.isTop&&(r+=" }; return validate; "),r}if(a.isTop){var y=a.isTop;l=a.level=0,c=a.dataLevel=0,p="data";if(a.rootId=a.resolve.fullPath(a.self._getId(a.root.schema)),a.baseId=a.baseId||a.rootId,delete a.isTop,a.dataPathArr=[void 0],void 0!==a.schema.default&&a.opts.useDefaults&&a.opts.strictDefaults){var g="default is ignored in the schema root";if("log"!==a.opts.strictDefaults)throw new Error(g);a.logger.warn(g)}r+=" var vErrors = null; ",r+=" var errors = 0; ",r+=" if (rootData === undefined) rootData = data; "}else{l=a.level,p="data"+((c=a.dataLevel)||"");if(o&&(a.baseId=a.resolve.url(a.baseId,o)),t&&!a.async)throw new Error("async schema in sync schema");r+=" var errs_"+l+" = errors;"}m="valid"+l,f=!a.opts.allErrors;var P="",E="",w=a.schema.type,b=Array.isArray(w);if(w&&a.opts.nullable&&!0===a.schema.nullable&&(b?-1==w.indexOf("null")&&(w=w.concat("null")):"null"!=w&&(w=[w,"null"],b=!0)),b&&1==w.length&&(w=w[0],b=!1),a.schema.$ref&&s){if("fail"==a.opts.extendRefs)throw new Error('$ref: validation keywords used in schema at path "'+a.errSchemaPath+'" (see option extendRefs)');!0!==a.opts.extendRefs&&(s=!1,a.logger.warn('$ref: keywords ignored in schema at path "'+a.errSchemaPath+'"'))}if(a.schema.$comment&&a.opts.$comment&&(r+=" "+a.RULES.all.$comment.code(a,"$comment")),w){if(a.opts.coerceTypes)var S=a.util.coerceToTypes(a.opts.coerceTypes,w);var _=a.RULES.types[w];if(S||b||!0===_||_&&!G(_)){h=a.schemaPath+".type",d=a.errSchemaPath+"/type",h=a.schemaPath+".type",d=a.errSchemaPath+"/type";if(r+=" if ("+a.util[b?"checkDataTypes":"checkDataType"](w,p,!0)+") { ",S){var F="dataType"+l,x="coerced"+l;r+=" var "+F+" = typeof "+p+"; ","array"==a.opts.coerceTypes&&(r+=" if ("+F+" == 'object' && Array.isArray("+p+")) "+F+" = 'array'; "),r+=" var "+x+" = undefined; ";var $="",R=S;if(R)for(var D,j=-1,O=R.length-1;j= 0x80 (not a basic code point)","invalid-input":"Invalid input"},C=Math.floor,k=String.fromCharCode;function L(e){throw new RangeError(i[e])}function n(e,r){var t=e.split("@"),a="";return 1>1,e+=C(e/r);455C((A-s)/h))&&L("overflow"),s+=f*h;var p=d<=i?1:i+26<=d?26:d-i;if(fC(A/m)&&L("overflow"),h*=m}var v=t.length+1;i=q(s-u,v,0==u),C(s/v)>A-o&&L("overflow"),o+=C(s/v),s%=v,t.splice(s++,0,o)}return String.fromCodePoint.apply(String,t)}function c(e){var r=[],t=(e=z(e)).length,a=128,s=0,o=72,i=!0,n=!1,l=void 0;try{for(var c,u=e[Symbol.iterator]();!(i=(c=u.next()).done);i=!0){var h=c.value;h<128&&r.push(k(h))}}catch(e){n=!0,l=e}finally{try{!i&&u.return&&u.return()}finally{if(n)throw l}}var d=r.length,f=d;for(d&&r.push("-");fC((A-s)/w)&&L("overflow"),s+=(p-a)*w,a=p;var b=!0,S=!1,_=void 0;try{for(var F,x=e[Symbol.iterator]();!(b=(F=x.next()).done);b=!0){var $=F.value;if($A&&L("overflow"),$==a){for(var R=s,D=36;;D+=36){var j=D<=o?1:o+26<=D?26:D-o;if(R>6|192).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase():"%"+(r>>12|224).toString(16).toUpperCase()+"%"+(r>>6&63|128).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase()}function f(e){for(var r="",t=0,a=e.length;tA-Z\\x5E-\\x7E]",'[\\"\\\\]')),M=new RegExp(V,"g"),B=new RegExp("(?:(?:%[EFef][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f])|(?:%[89A-Fa-f][0-9A-Fa-f]%[0-9A-Fa-f][0-9A-Fa-f])|(?:%[0-9A-Fa-f][0-9A-Fa-f]))","g"),G=new RegExp(J("[^]","[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]","[\\.]",'[\\"]',K),"g"),Y=new RegExp(J("[^]",V,"[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"),"g"),W=Y;function X(e){var r=f(e);return r.match(M)?r:e}var ee={scheme:"mailto",parse:function(e,r){var t=e,a=t.to=t.path?t.path.split(","):[];if(t.path=void 0,t.query){for(var s=!1,o={},i=t.query.split("&"),n=0,l=i.length;n=8" + "node": ">=10" }, "files": [ "source", "index.d.ts" ], + "funding": "https://github.com/chalk/chalk?sponsor=1", "homepage": "https://github.com/chalk/chalk#readme", "keywords": [ "color", @@ -62,11 +63,15 @@ "bench": "matcha benchmark.js", "test": "xo && nyc ava && tsd" }, - "version": "3.0.0", + "version": "4.0.0", "xo": { "rules": { "unicorn/prefer-string-slice": "off", - "unicorn/prefer-includes": "off" + "unicorn/prefer-includes": "off", + "@typescript-eslint/member-ordering": "off", + "no-redeclare": "off", + "unicorn/string-content": "off", + "unicorn/better-regex": "off" } } } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/chalk/readme.md b/tools/node_modules/eslint/node_modules/chalk/readme.md index 877cb93b7861f7..a0ca245604033b 100644 --- a/tools/node_modules/eslint/node_modules/chalk/readme.md +++ b/tools/node_modules/eslint/node_modules/chalk/readme.md @@ -9,11 +9,10 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) [![run on repl.it](http://repl.it/badge/github/chalk/chalk)](https://repl.it/github/chalk/chalk) - ## Highlights - Expressive API @@ -24,8 +23,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~46,000 packages](https://www.npmjs.com/browse/depended/chalk) as of October 1, 2019 - +- [Used by ~50,000 packages](https://www.npmjs.com/browse/depended/chalk) as of January 1, 2020 ## Install @@ -33,7 +31,6 @@ $ npm install chalk ``` - ## Usage ```js @@ -107,7 +104,6 @@ console.log(chalk.green('Hello %s'), name); //=> 'Hello Sindre' ``` - ## API ### chalk.`