From e31ab7c1ed006406bcdf5d91cd12db7136ec10b9 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Sun, 23 Apr 2017 23:52:41 -0400 Subject: [PATCH 001/128] inspector: enable --inspect-brk PR-URL: https://github.com/nodejs/node/pull/12615 Reviewed-By: Sam Roberts Reviewed-By: Gibson Fahnestock Reviewed-By: James M Snell --- src/node.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/node.cc b/src/node.cc index 33d97a0fcc8664..def8e60b42c236 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3616,6 +3616,15 @@ static bool ParseDebugOpt(const char* arg) { use_debug_agent = true; use_inspector = true; port = arg + sizeof("--inspect=") - 1; + } else if (!strcmp(arg, "--inspect-brk")) { + use_debug_agent = true; + use_inspector = true; + debug_wait_connect = true; + } else if (!strncmp(arg, "--inspect-brk=", sizeof("--inspect-brk=") - 1)) { + use_debug_agent = true; + use_inspector = true; + debug_wait_connect = true; + port = arg + sizeof("--inspect-brk=") - 1; #else } else if (!strncmp(arg, "--inspect", sizeof("--inspect") - 1)) { fprintf(stderr, From a7d4cade46e7c51d02ffbd00f0c6c32101fc85f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Mon, 6 Mar 2017 00:41:26 +0100 Subject: [PATCH 002/128] crypto: add sign/verify support for RSASSA-PSS Adds support for the PSS padding scheme. Until now, the sign/verify functions used the old EVP_Sign*/EVP_Verify* OpenSSL API, making it impossible to change the padding scheme. Fixed by first computing the message digest and then signing/verifying with a custom EVP_PKEY_CTX, allowing us to specify options such as the padding scheme and the PSS salt length. Fixes: https://github.com/nodejs/node/issues/1127 PR-URL: https://github.com/nodejs/node/pull/11705 Reviewed-By: Shigeki Ohtsu Reviewed-By: Sam Roberts Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- doc/api/crypto.md | 61 ++++++- lib/crypto.js | 49 +++++- src/node_constants.cc | 12 ++ src/node_constants.h | 13 ++ src/node_crypto.cc | 123 ++++++++++++-- src/node_crypto.h | 6 +- test/fixtures/pss-vectors.json | 89 ++++++++++ test/parallel/test-crypto-sign-verify.js | 202 +++++++++++++++++++++++ 8 files changed, 537 insertions(+), 18 deletions(-) create mode 100644 test/fixtures/pss-vectors.json diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 7d94ffd6c77f72..f49d055d820bff 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -898,6 +898,10 @@ console.log(sign.sign(privateKey).toString('hex')); ### sign.sign(private_key[, output_format]) Calculates the signature on all the data passed through using either @@ -905,10 +909,21 @@ Calculates the signature on all the data passed through using either The `private_key` argument can be an object or a string. If `private_key` is a string, it is treated as a raw key with no passphrase. If `private_key` is an -object, it is interpreted as a hash containing two properties: +object, it must contain one or more of the following properties: -* `key`: {string} - PEM encoded private key +* `key`: {string} - PEM encoded private key (required) * `passphrase`: {string} - passphrase for the private key +* `padding`: {integer} - Optional padding value for RSA, one of the following: + * `crypto.constants.RSA_PKCS1_PADDING` (default) + * `crypto.constants.RSA_PKCS1_PSS_PADDING` + + Note that `RSA_PKCS1_PSS_PADDING` will use MGF1 with the same hash function + used to sign the message as specified in section 3.1 of [RFC 4055][]. +* `saltLength`: {integer} - salt length for when padding is + `RSA_PKCS1_PSS_PADDING`. The special value + `crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest + size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the + maximum permissible value. The `output_format` can specify one of `'latin1'`, `'hex'` or `'base64'`. If `output_format` is provided a string is returned; otherwise a [`Buffer`][] is @@ -991,11 +1006,33 @@ This can be called many times with new data as it is streamed. ### verifier.verify(object, signature[, signature_format]) +- `object` {string | Object} +- `signature` {string | Buffer | Uint8Array} +- `signature_format` {string} Verifies the provided data using the given `object` and `signature`. -The `object` argument is a string containing a PEM encoded object, which can be -one an RSA public key, a DSA public key, or an X.509 certificate. +The `object` argument can be either a string containing a PEM encoded object, +which can be an RSA public key, a DSA public key, or an X.509 certificate, +or an object with one or more of the following properties: + +* `key`: {string} - PEM encoded public key (required) +* `padding`: {integer} - Optional padding value for RSA, one of the following: + * `crypto.constants.RSA_PKCS1_PADDING` (default) + * `crypto.constants.RSA_PKCS1_PSS_PADDING` + + Note that `RSA_PKCS1_PSS_PADDING` will use MGF1 with the same hash function + used to verify the message as specified in section 3.1 of [RFC 4055][]. +* `saltLength`: {integer} - salt length for when padding is + `RSA_PKCS1_PSS_PADDING`. The special value + `crypto.constants.RSA_PSS_SALTLEN_DIGEST` sets the salt length to the digest + size, `crypto.constants.RSA_PSS_SALTLEN_AUTO` (default) causes it to be + determined automatically. + The `signature` argument is the previously calculated signature for the data, in the `signature_format` which can be `'latin1'`, `'hex'` or `'base64'`. If a `signature_format` is specified, the `signature` is expected to be a @@ -1902,6 +1939,21 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. RSA_PKCS1_PSS_PADDING + + RSA_PSS_SALTLEN_DIGEST + Sets the salt length for `RSA_PKCS1_PSS_PADDING` to the digest size + when signing or verifying. + + + RSA_PSS_SALTLEN_MAX_SIGN + Sets the salt length for `RSA_PKCS1_PSS_PADDING` to the maximum + permissible value when signing data. + + + RSA_PSS_SALTLEN_AUTO + Causes the salt length for `RSA_PKCS1_PSS_PADDING` to be determined + automatically when verifying a signature. + POINT_CONVERSION_COMPRESSED @@ -1977,6 +2029,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. [publicly trusted list of CAs]: https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt [RFC 2412]: https://www.rfc-editor.org/rfc/rfc2412.txt [RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt +[RFC 4055]: https://www.rfc-editor.org/rfc/rfc4055.txt [stream]: stream.html [stream-writable-write]: stream.html#stream_writable_write_chunk_encoding_callback [Crypto Constants]: #crypto_crypto_constants_1 diff --git a/lib/crypto.js b/lib/crypto.js index f2dede115487b0..f4eeb7baa3aad5 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -283,7 +283,28 @@ Sign.prototype.sign = function sign(options, encoding) { var key = options.key || options; var passphrase = options.passphrase || null; - var ret = this._handle.sign(toBuf(key), null, passphrase); + + // Options specific to RSA + var rsaPadding = constants.RSA_PKCS1_PADDING; + if (options.hasOwnProperty('padding')) { + if (options.padding === options.padding >> 0) { + rsaPadding = options.padding; + } else { + throw new TypeError('padding must be an integer'); + } + } + + var pssSaltLength = constants.RSA_PSS_SALTLEN_AUTO; + if (options.hasOwnProperty('saltLength')) { + if (options.saltLength === options.saltLength >> 0) { + pssSaltLength = options.saltLength; + } else { + throw new TypeError('saltLength must be an integer'); + } + } + + var ret = this._handle.sign(toBuf(key), null, passphrase, rsaPadding, + pssSaltLength); encoding = encoding || exports.DEFAULT_ENCODING; if (encoding && encoding !== 'buffer') @@ -309,9 +330,31 @@ util.inherits(Verify, stream.Writable); Verify.prototype._write = Sign.prototype._write; Verify.prototype.update = Sign.prototype.update; -Verify.prototype.verify = function verify(object, signature, sigEncoding) { +Verify.prototype.verify = function verify(options, signature, sigEncoding) { + var key = options.key || options; sigEncoding = sigEncoding || exports.DEFAULT_ENCODING; - return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding)); + + // Options specific to RSA + var rsaPadding = constants.RSA_PKCS1_PADDING; + if (options.hasOwnProperty('padding')) { + if (options.padding === options.padding >> 0) { + rsaPadding = options.padding; + } else { + throw new TypeError('padding must be an integer'); + } + } + + var pssSaltLength = constants.RSA_PSS_SALTLEN_AUTO; + if (options.hasOwnProperty('saltLength')) { + if (options.saltLength === options.saltLength >> 0) { + pssSaltLength = options.saltLength; + } else { + throw new TypeError('saltLength must be an integer'); + } + } + + return this._handle.verify(toBuf(key), toBuf(signature, sigEncoding), null, + rsaPadding, pssSaltLength); }; function rsaPublic(method, defaultPadding) { diff --git a/src/node_constants.cc b/src/node_constants.cc index 750df9c669bad3..be6e034a923a92 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -974,6 +974,18 @@ void DefineOpenSSLConstants(Local target) { NODE_DEFINE_CONSTANT(target, RSA_PKCS1_PSS_PADDING); #endif +#ifdef RSA_PSS_SALTLEN_DIGEST + NODE_DEFINE_CONSTANT(target, RSA_PSS_SALTLEN_DIGEST); +#endif + +#ifdef RSA_PSS_SALTLEN_MAX_SIGN + NODE_DEFINE_CONSTANT(target, RSA_PSS_SALTLEN_MAX_SIGN); +#endif + +#ifdef RSA_PSS_SALTLEN_AUTO + NODE_DEFINE_CONSTANT(target, RSA_PSS_SALTLEN_AUTO); +#endif + #if HAVE_OPENSSL // NOTE: These are not defines NODE_DEFINE_CONSTANT(target, POINT_CONVERSION_COMPRESSED); diff --git a/src/node_constants.h b/src/node_constants.h index 7ba6ec3bd1b015..db365f3d87a7fc 100644 --- a/src/node_constants.h +++ b/src/node_constants.h @@ -7,6 +7,19 @@ #include "v8.h" #if HAVE_OPENSSL + +#ifndef RSA_PSS_SALTLEN_DIGEST +#define RSA_PSS_SALTLEN_DIGEST -1 +#endif + +#ifndef RSA_PSS_SALTLEN_MAX_SIGN +#define RSA_PSS_SALTLEN_MAX_SIGN -2 +#endif + +#ifndef RSA_PSS_SALTLEN_AUTO +#define RSA_PSS_SALTLEN_AUTO -2 +#endif + #define DEFAULT_CIPHER_LIST_CORE "ECDHE-RSA-AES128-GCM-SHA256:" \ "ECDHE-ECDSA-AES128-GCM-SHA256:" \ "ECDHE-RSA-AES256-GCM-SHA384:" \ diff --git a/src/node_crypto.cc b/src/node_crypto.cc index aa2dafebc5cf81..335972bab2a466 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1,5 +1,6 @@ #include "node.h" #include "node_buffer.h" +#include "node_constants.h" #include "node_crypto.h" #include "node_crypto_bio.h" #include "node_crypto_groups.h" @@ -80,6 +81,7 @@ using v8::HandleScope; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::Maybe; using v8::Null; using v8::Object; using v8::Persistent; @@ -3990,6 +3992,19 @@ void SignBase::CheckThrow(SignBase::Error error) { } } +static bool ApplyRSAOptions(EVP_PKEY* pkey, EVP_PKEY_CTX* pkctx, int padding, + int salt_len) { + if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA2) { + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0) + return false; + if (padding == RSA_PKCS1_PSS_PADDING) { + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, salt_len) <= 0) + return false; + } + } + + return true; +} @@ -4019,7 +4034,7 @@ SignBase::Error Sign::SignInit(const char* sign_type) { return kSignUnknownDigest; EVP_MD_CTX_init(&mdctx_); - if (!EVP_SignInit_ex(&mdctx_, md, nullptr)) + if (!EVP_DigestInit_ex(&mdctx_, md, nullptr)) return kSignInit; initialised_ = true; @@ -4046,7 +4061,7 @@ void Sign::SignInit(const FunctionCallbackInfo& args) { SignBase::Error Sign::SignUpdate(const char* data, int len) { if (!initialised_) return kSignNotInitialised; - if (!EVP_SignUpdate(&mdctx_, data, len)) + if (!EVP_DigestUpdate(&mdctx_, data, len)) return kSignUpdate; return kSignOk; } @@ -4076,12 +4091,54 @@ void Sign::SignUpdate(const FunctionCallbackInfo& args) { sign->CheckThrow(err); } +static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md, + unsigned int* sig_len, EVP_PKEY* pkey, int padding, + int pss_salt_len) { + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int rv = 0; + EVP_PKEY_CTX* pkctx = nullptr; + + *sig_len = 0; + if (!EVP_DigestFinal_ex(mdctx, m, &m_len)) + return rv; + + if (mdctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + size_t sltmp = static_cast(EVP_PKEY_size(pkey)); + pkctx = EVP_PKEY_CTX_new(pkey, nullptr); + if (pkctx == nullptr) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (!ApplyRSAOptions(pkey, pkctx, padding, pss_salt_len)) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, mdctx->digest) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, md, &sltmp, m, m_len) <= 0) + goto err; + *sig_len = sltmp; + rv = 1; + err: + EVP_PKEY_CTX_free(pkctx); + return rv; + } + + if (mdctx->digest->sign == nullptr) { + EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED); + return 0; + } + + return mdctx->digest->sign(mdctx->digest->type, m, m_len, md, sig_len, + pkey->pkey.ptr); +} SignBase::Error Sign::SignFinal(const char* key_pem, int key_pem_len, const char* passphrase, unsigned char** sig, - unsigned int *sig_len) { + unsigned int* sig_len, + int padding, + int salt_len) { if (!initialised_) return kSignNotInitialised; @@ -4127,7 +4184,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem, } #endif // NODE_FIPS_MODE - if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey)) + if (Node_SignFinal(&mdctx_, *sig, sig_len, pkey, padding, salt_len)) fatal = false; initialised_ = false; @@ -4168,6 +4225,16 @@ void Sign::SignFinal(const FunctionCallbackInfo& args) { size_t buf_len = Buffer::Length(args[0]); char* buf = Buffer::Data(args[0]); + CHECK(args[3]->IsInt32()); + Maybe maybe_padding = args[3]->Int32Value(env->context()); + CHECK(maybe_padding.IsJust()); + int padding = maybe_padding.FromJust(); + + CHECK(args[4]->IsInt32()); + Maybe maybe_salt_len = args[4]->Int32Value(env->context()); + CHECK(maybe_salt_len.IsJust()); + int salt_len = maybe_salt_len.FromJust(); + md_len = 8192; // Maximum key size is 8192 bits md_value = new unsigned char[md_len]; @@ -4179,7 +4246,9 @@ void Sign::SignFinal(const FunctionCallbackInfo& args) { buf_len, len >= 3 && !args[2]->IsNull() ? *passphrase : nullptr, &md_value, - &md_len); + &md_len, + padding, + salt_len); if (err != kSignOk) { delete[] md_value; md_value = nullptr; @@ -4223,7 +4292,7 @@ SignBase::Error Verify::VerifyInit(const char* verify_type) { return kSignUnknownDigest; EVP_MD_CTX_init(&mdctx_); - if (!EVP_VerifyInit_ex(&mdctx_, md, nullptr)) + if (!EVP_DigestInit_ex(&mdctx_, md, nullptr)) return kSignInit; initialised_ = true; @@ -4251,7 +4320,7 @@ SignBase::Error Verify::VerifyUpdate(const char* data, int len) { if (!initialised_) return kSignNotInitialised; - if (!EVP_VerifyUpdate(&mdctx_, data, len)) + if (!EVP_DigestUpdate(&mdctx_, data, len)) return kSignUpdate; return kSignOk; @@ -4287,6 +4356,8 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem, int key_pem_len, const char* sig, int siglen, + int padding, + int saltlen, bool* verify_result) { if (!initialised_) return kSignNotInitialised; @@ -4298,7 +4369,10 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem, BIO* bp = nullptr; X509* x509 = nullptr; bool fatal = true; + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; int r = 0; + EVP_PKEY_CTX* pkctx = nullptr; bp = BIO_new_mem_buf(const_cast(key_pem), key_pem_len); if (bp == nullptr) @@ -4333,11 +4407,29 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem, goto exit; } + if (!EVP_DigestFinal_ex(&mdctx_, m, &m_len)) { + goto exit; + } + fatal = false; - r = EVP_VerifyFinal(&mdctx_, + + pkctx = EVP_PKEY_CTX_new(pkey, nullptr); + if (pkctx == nullptr) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (!ApplyRSAOptions(pkey, pkctx, padding, saltlen)) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, mdctx_.digest) <= 0) + goto err; + r = EVP_PKEY_verify(pkctx, reinterpret_cast(sig), siglen, - pkey); + m, + m_len); + + err: + EVP_PKEY_CTX_free(pkctx); exit: if (pkey != nullptr) @@ -4391,8 +4483,19 @@ void Verify::VerifyFinal(const FunctionCallbackInfo& args) { hbuf = Buffer::Data(args[1]); } + CHECK(args[3]->IsInt32()); + Maybe maybe_padding = args[3]->Int32Value(env->context()); + CHECK(maybe_padding.IsJust()); + int padding = maybe_padding.FromJust(); + + CHECK(args[4]->IsInt32()); + Maybe maybe_salt_len = args[4]->Int32Value(env->context()); + CHECK(maybe_salt_len.IsJust()); + int salt_len = maybe_salt_len.FromJust(); + bool verify_result; - Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, &verify_result); + Error err = verify->VerifyFinal(kbuf, klen, hbuf, hlen, padding, salt_len, + &verify_result); if (args[1]->IsString()) delete[] hbuf; if (err != kSignOk) diff --git a/src/node_crypto.h b/src/node_crypto.h index 746c954b26fb43..373d859530bcf5 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -569,7 +569,9 @@ class Sign : public SignBase { int key_pem_len, const char* passphrase, unsigned char** sig, - unsigned int *sig_len); + unsigned int *sig_len, + int padding, + int saltlen); protected: static void New(const v8::FunctionCallbackInfo& args); @@ -592,6 +594,8 @@ class Verify : public SignBase { int key_pem_len, const char* sig, int siglen, + int padding, + int saltlen, bool* verify_result); protected: diff --git a/test/fixtures/pss-vectors.json b/test/fixtures/pss-vectors.json new file mode 100644 index 00000000000000..b540d13a540646 --- /dev/null +++ b/test/fixtures/pss-vectors.json @@ -0,0 +1,89 @@ +{ + "example01": { + "publicKey": [ + "-----BEGIN PUBLIC KEY-----", + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClbkoOcBAXWJpRh9x+qEHRVvLs", + "DjatUqRN/rHmH3rZkdjFEFb/7bFitMDyg6EqiKOU3/Umq3KRy7MHzqv84LHf1c2V", + "CAltWyuLbfXWce9jd8CSHLI8Jwpw4lmOb/idGfEFrMLT8Ms18pKA4Thrb2TE7yLh", + "4fINDOjP+yJJvZohNwIDAQAB", + "-----END PUBLIC KEY-----" + ], + "tests": [ + { + "message": "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b62371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb769757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb061a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d6193c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0", + "salt": "dee959c7e06411361420ff80185ed57f3e6776af", + "signature": "9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c" + }, + { + "message": "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f71a1cca582d43ecc72b1bca16dfc7013226b9e", + "salt": "ef2869fa40c346cb183dab3d7bffc98fd56df42d", + "signature": "3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843" + }, + { + "message": "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c745e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef416971338e7d470", + "salt": "710b9c4747d800d4de87f12afdce6df18107cc77", + "signature": "666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1" + }, + { + "message": "bc656747fa9eafb3f0", + "salt": "056f00985de14d8ef5cea9e82f8c27bef720335e", + "signature": "4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87" + }, + { + "message": "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4", + "salt": "80e70ff86a08de3ec60972b39b4fbfdcea67ae8e", + "signature": "1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad" + }, + { + "message": "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b705a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb8794c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6138d144f8ce4e2da73", + "salt": "a8ab69dd801f0074c2a1fc60649836c616d99681", + "signature": "2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58" + } + ] + }, + "example10": { + "publicKey": [ + "-----BEGIN PUBLIC KEY-----", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApd2GesTLAvkLlFfUjBSn", + "cO+ZHFbDnA7GX9Ea+ok3zqV7m+esc7RcABdhW4LWIuMYdTtgJ8D9FXvhL4CQ/uKn", + "rc0O73WfiLpJl8ekLVjJqhLLma4AH+UhwTu1QxRFqNWuT15MfpSKwifTYEBx8g5X", + "fpBfvrFd+vBtHeWuYlPWOmohILMaXaXavJVQYA4g8n03OeJieSX+o8xQnyHf8E5u", + "6kVJxUDWgJ/5MH7t6R//WHM9g4WiN9bTcFoz45GQCZIHDfet8TV89+NwDONmfeg/", + "F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGu", + "BQIDAQAB", + "-----END PUBLIC KEY-----" + ], + "tests": [ + { + "message": "883177e5126b9be2d9a9680327d5370c6f26861f5820c43da67a3ad609", + "salt": "04e215ee6ff934b9da70d7730c8734abfcecde89", + "signature": "82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666" + }, + { + "message": "dd670a01465868adc93f26131957a50c52fb777cdbaa30892c9e12361164ec13979d43048118e4445db87bee58dd987b3425d02071d8dbae80708b039dbb64dbd1de5657d9fed0c118a54143742e0ff3c87f74e45857647af3f79eb0a14c9d75ea9a1a04b7cf478a897a708fd988f48e801edb0b7039df8c23bb3c56f4e821ac", + "salt": "8b2bdd4b40faf545c778ddf9bc1a49cb57f9b71b", + "signature": "14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3" + }, + { + "message": "48b2b6a57a63c84cea859d65c668284b08d96bdcaabe252db0e4a96cb1bac6019341db6fbefb8d106b0e90eda6bcc6c6262f37e7ea9c7e5d226bd7df85ec5e71efff2f54c5db577ff729ff91b842491de2741d0c631607df586b905b23b91af13da12304bf83eca8a73e871ff9db", + "salt": "4e96fc1b398f92b44671010c0dc3efd6e20c2d73", + "signature": "6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb" + }, + { + "message": "0b8777c7f839baf0a64bbbdbc5ce79755c57a205b845c174e2d2e90546a089c4e6ec8adffa23a7ea97bae6b65d782b82db5d2b5a56d22a29a05e7c4433e2b82a621abba90add05ce393fc48a840542451a", + "salt": "c7cd698d84b65128d8835e3a8b1eb0e01cb541ec", + "signature": "34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb" + }, + { + "message": "f1036e008e71e964dadc9219ed30e17f06b4b68a955c16b312b1eddf028b74976bed6b3f6a63d4e77859243c9cccdc98016523abb02483b35591c33aad81213bb7c7bb1a470aabc10d44256c4d4559d916", + "salt": "efa8bff96212b2f4a3f371a10d574152655f5dfb", + "signature": "7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc" + }, + { + "message": "25f10895a87716c137450bb9519dfaa1f207faa942ea88abf71e9c17980085b555aebab76264ae2a3ab93c2d12981191ddac6fb5949eb36aee3c5da940f00752c916d94608fa7d97ba6a2915b688f20323d4e9d96801d89a72ab5892dc2117c07434fcf972e058cf8c41ca4b4ff554f7d5068ad3155fced0f3125bc04f9193378a8f5c4c3b8cb4dd6d1cc69d30ecca6eaa51e36a05730e9e342e855baf099defb8afd7", + "salt": "ad8b1523703646224b660b550885917ca2d1df28", + "signature": "6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f" + } + ] + } +} \ No newline at end of file diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index a9a2cac78828ab..fa410de4a62b4f 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -4,12 +4,20 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); +const exec = require('child_process').exec; const fs = require('fs'); +const path = require('path'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} const crypto = require('crypto'); // Test certificates const certPem = fs.readFileSync(`${common.fixturesDir}/test_cert.pem`, 'ascii'); const keyPem = fs.readFileSync(`${common.fixturesDir}/test_key.pem`, 'ascii'); +const modSize = 1024; // Test signing and verifying { @@ -69,9 +77,203 @@ const keyPem = fs.readFileSync(`${common.fixturesDir}/test_key.pem`, 'ascii'); assert.strictEqual(verified, true, 'sign and verify (stream)'); } +// Special tests for RSA_PKCS1_PSS_PADDING +{ + function testPSS(algo, hLen) { + // Maximum permissible salt length + const max = modSize / 8 - hLen - 2; + + function getEffectiveSaltLength(saltLength) { + switch (saltLength) { + case crypto.constants.RSA_PSS_SALTLEN_DIGEST: + return hLen; + case crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN: + return max; + default: + return saltLength; + } + } + + const signSaltLengths = [ + crypto.constants.RSA_PSS_SALTLEN_DIGEST, + getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_DIGEST), + crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN, + getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN), + 0, 16, 32, 64, 128 + ]; + + const verifySaltLengths = [ + crypto.constants.RSA_PSS_SALTLEN_DIGEST, + getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_DIGEST), + getEffectiveSaltLength(crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN), + 0, 16, 32, 64, 128 + ]; + + signSaltLengths.forEach((signSaltLength) => { + if (signSaltLength > max) { + // If the salt length is too big, an Error should be thrown + assert.throws(() => { + crypto.createSign(algo) + .update('Test123') + .sign({ + key: keyPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: signSaltLength + }); + }, /^Error:.*data too large for key size$/); + } else { + // Otherwise, a valid signature should be generated + const s4 = crypto.createSign(algo) + .update('Test123') + .sign({ + key: keyPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: signSaltLength + }); + + let verified; + verifySaltLengths.forEach((verifySaltLength) => { + // Verification should succeed if and only if the salt length is + // correct + verified = crypto.createVerify(algo) + .update('Test123') + .verify({ + key: certPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: verifySaltLength + }, s4); + const saltLengthCorrect = getEffectiveSaltLength(signSaltLength) == + getEffectiveSaltLength(verifySaltLength); + assert.strictEqual(verified, saltLengthCorrect, 'verify (PSS)'); + }); + + // Verification using RSA_PSS_SALTLEN_AUTO should always work + verified = crypto.createVerify(algo) + .update('Test123') + .verify({ + key: certPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO + }, s4); + assert.strictEqual(verified, true, 'verify (PSS with SALTLEN_AUTO)'); + + // Verifying an incorrect message should never work + verified = crypto.createVerify(algo) + .update('Test1234') + .verify({ + key: certPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO + }, s4); + assert.strictEqual(verified, false, 'verify (PSS, incorrect)'); + } + }); + } + + testPSS('RSA-SHA1', 20); + testPSS('RSA-SHA256', 32); +} + +// Test vectors for RSA_PKCS1_PSS_PADDING provided by the RSA Laboratories: +// https://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-rsa-cryptography-standard.htm +{ + // We only test verification as we cannot specify explicit salts when signing + function testVerify(cert, vector) { + const verified = crypto.createVerify('RSA-SHA1') + .update(Buffer.from(vector.message, 'hex')) + .verify({ + key: cert, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: vector.salt.length / 2 + }, vector.signature, 'hex'); + assert.strictEqual(verified, true, 'verify (PSS)'); + } + + const vectorfile = path.join(common.fixturesDir, 'pss-vectors.json'); + const examples = JSON.parse(fs.readFileSync(vectorfile, { + encoding: 'utf8' + })); + + for (const key in examples) { + const example = examples[key]; + const publicKey = example.publicKey.join('\n'); + example.tests.forEach((test) => testVerify(publicKey, test)); + } +} + +// Test exceptions for invalid `padding` and `saltLength` values +{ + [null, undefined, NaN, 'boom', {}, [], true, false] + .forEach((invalidValue) => { + assert.throws(() => { + crypto.createSign('RSA-SHA256') + .update('Test123') + .sign({ + key: keyPem, + padding: invalidValue + }); + }, /^TypeError: padding must be an integer$/); + + assert.throws(() => { + crypto.createSign('RSA-SHA256') + .update('Test123') + .sign({ + key: keyPem, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength: invalidValue + }); + }, /^TypeError: saltLength must be an integer$/); + }); + + assert.throws(() => { + crypto.createSign('RSA-SHA1') + .update('Test123') + .sign({ + key: keyPem, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING + }); + }, /^Error:.*illegal or unsupported padding mode$/); +} + // Test throws exception when key options is null { assert.throws(() => { crypto.createSign('RSA-SHA1').update('Test123').sign(null, 'base64'); }, /^Error: No key provided to sign$/); } + +// RSA-PSS Sign test by verifying with 'openssl dgst -verify' +{ + if (!common.opensslCli) { + common.skip('node compiled without OpenSSL CLI.'); + return; + } + + const pubfile = path.join(common.fixturesDir, 'keys/rsa_public_2048.pem'); + const privfile = path.join(common.fixturesDir, 'keys/rsa_private_2048.pem'); + const privkey = fs.readFileSync(privfile); + + const msg = 'Test123'; + const s5 = crypto.createSign('RSA-SHA256') + .update(msg) + .sign({ + key: privkey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING + }); + + common.refreshTmpDir(); + + const sigfile = path.join(common.tmpDir, 's5.sig'); + fs.writeFileSync(sigfile, s5); + const msgfile = path.join(common.tmpDir, 's5.msg'); + fs.writeFileSync(msgfile, msg); + + const cmd = '"' + common.opensslCli + '" dgst -sha256 -verify "' + pubfile + + '" -signature "' + sigfile + + '" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "' + + msgfile + '"'; + + exec(cmd, common.mustCall((err, stdout, stderr) => { + assert(stdout.includes('Verified OK')); + })); +} From 4917d8cfef828b77bdd8f15cb4cdb7f5ee6babb3 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 9 Apr 2017 10:36:14 -0700 Subject: [PATCH 003/128] assert: improve assert.fail() API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit assert.fail() has two possible function signatures, both of which are not intuitive. It virtually guarantees that people who try to use assert.fail() without carefully reading the docs will end up using it incorrectly. This change maintains backwards compatibility with the two valid uses (arguments 1 2 and 4 supplied but argument 3 falsy, and argument 3 supplied but arguments 1 2 and 4 all falsy) but also adds the far more intuitive first-argument-only and first-two-arguments-only possibilities. assert.fail('boom'); // AssertionError: boom assert.fail('a', 'b'); // AssertionError: 'a' != 'b' Backport-PR-URL: https://github.com/nodejs/node/pull/15479 PR-URL: https://github.com/nodejs/node/pull/12293 Reviewed-By: Anna Henningsen Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/api/assert.md | 9 ++++++++- lib/assert.js | 4 ++++ test/parallel/test-assert-fail.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index a0eb8d7a4a188e..b742e69d7fb312 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -194,6 +194,7 @@ If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. +## assert.fail(message) ## assert.fail(actual, expected[, message[, operator[, stackStartFunction]]]) + +Write process warnings to the given file instead of printing to stderr. The +file will be created if it does not exist, and will be appended to if it does. +If an error occurs while attempting to write the warning to the file, the +warning will be written to stderr instead. + ### `--trace-sync-io` + +When set, process warnings will be emitted to the given file instead of +printing to stderr. The file will be created if it does not exist, and will be +appended to if it does. If an error occurs while attempting to write the +warning to the file, the warning will be written to stderr instead. This is +equivalent to using the `--redirect-warnings=file` command-line flag. + [emit_warning]: process.html#process_process_emitwarning_warning_name_ctor [Buffer]: buffer.html#buffer_buffer [debugger]: debugger.html diff --git a/doc/node.1 b/doc/node.1 index 2167f245216e04..469735eebae9bf 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -112,6 +112,10 @@ Silence all process warnings (including deprecations). .BR \-\-trace\-warnings Print stack traces for process warnings (including deprecations). +.TP +.BR \-\-redirect\-warnings=\fIfile\fR +Write process warnings to the given file instead of printing to stderr. + .TP .BR \-\-trace\-sync\-io Print a stack trace whenever synchronous I/O is detected after the first turn @@ -255,6 +259,12 @@ containing trusted certificates. If \fB\-\-use\-openssl\-ca\fR is enabled, this overrides and sets OpenSSL's file containing trusted certificates. +.TP +.BR NODE_REDIRECT_WARNINGS=\fIfile\fR +Write process warnings to the given file instead of printing to stderr. +(equivalent to using the \-\-redirect\-warnings=\fIfile\fR command-line +argument). + .SH BUGS Bugs are tracked in GitHub Issues: .ur https://github.com/nodejs/node/issues diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index bce470cd1c50ac..dd9aa484b7ea21 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -4,10 +4,81 @@ const traceWarnings = process.traceProcessWarnings; const noDeprecation = process.noDeprecation; const traceDeprecation = process.traceDeprecation; const throwDeprecation = process.throwDeprecation; +const config = process.binding('config'); const prefix = `(${process.release.name}:${process.pid}) `; exports.setup = setupProcessWarnings; +var fs; +var cachedFd; +var acquiringFd = false; +function nop() {} + +function lazyFs() { + if (!fs) + fs = require('fs'); + return fs; +} + +function writeOut(message) { + if (console && typeof console.error === 'function') + return console.error(message); + process._rawDebug(message); +} + +function onClose(fd) { + return function() { + lazyFs().close(fd, nop); + }; +} + +function onOpen(cb) { + return function(err, fd) { + acquiringFd = false; + if (fd !== undefined) { + cachedFd = fd; + process.on('exit', onClose(fd)); + } + cb(err, fd); + process.emit('_node_warning_fd_acquired', err, fd); + }; +} + +function onAcquired(message) { + // make a best effort attempt at writing the message + // to the fd. Errors are ignored at this point. + return function(err, fd) { + if (err) + return writeOut(message); + lazyFs().appendFile(fd, `${message}\n`, nop); + }; +} + +function acquireFd(cb) { + if (cachedFd === undefined && !acquiringFd) { + acquiringFd = true; + lazyFs().open(config.warningFile, 'a', onOpen(cb)); + } else if (cachedFd !== undefined && !acquiringFd) { + cb(null, cachedFd); + } else { + process.once('_node_warning_fd_acquired', cb); + } +} + +function output(message) { + if (typeof config.warningFile === 'string') { + acquireFd(onAcquired(message)); + return; + } + writeOut(message); +} + +function doEmitWarning(warning) { + return function() { + process.emit('warning', warning); + }; +} + function setupProcessWarnings() { if (!process.noProcessWarnings && process.env.NODE_NO_WARNINGS !== '1') { process.on('warning', (warning) => { @@ -21,7 +92,7 @@ function setupProcessWarnings() { var toString = warning.toString; if (typeof toString !== 'function') toString = Error.prototype.toString; - console.error(`${prefix}${toString.apply(warning)}`); + output(`${prefix}${toString.apply(warning)}`); } }); } @@ -44,6 +115,6 @@ function setupProcessWarnings() { if (throwDeprecation && warning.name === 'DeprecationWarning') throw warning; else - process.nextTick(() => process.emit('warning', warning)); + process.nextTick(doEmitWarning(warning)); }; } diff --git a/src/node.cc b/src/node.cc index def8e60b42c236..c5be22a7251330 100644 --- a/src/node.cc +++ b/src/node.cc @@ -199,12 +199,16 @@ bool trace_warnings = false; // that is used by lib/module.js bool config_preserve_symlinks = false; + // Set in node.cc by ParseArgs when --expose-internals or --expose_internals is // used. // Used in node_config.cc to set a constant on process.binding('config') // that is used by lib/internal/bootstrap_node.js bool config_expose_internals = false; +// Set in node.cc by ParseArgs when --redirect-warnings= is used. +const char* config_warning_file; + // process-relative uptime base, initialized at start-up static double prog_start_time; static bool debugger_running; @@ -3701,6 +3705,8 @@ static void PrintHelp() { "function is used\n" " --no-warnings silence all process warnings\n" " --trace-warnings show stack traces on process warnings\n" + " --redirect-warnings=path\n" + " write warnings to path instead of stderr\n" " --trace-sync-io show stack trace when use of sync IO\n" " is detected after the first tick\n" " --track-heap-objects track heap object allocations for heap " @@ -3765,6 +3771,7 @@ static void PrintHelp() { " prefixed to the module search path\n" "NODE_REPL_HISTORY path to the persistent REPL history file\n" "OPENSSL_CONF load OpenSSL configuration from file\n" + "NODE_REDIRECT_WARNINGS write warnings to path instead of stderr\n" "\n" "Documentation can be found at https://nodejs.org/\n"); } @@ -3866,6 +3873,8 @@ static void ParseArgs(int* argc, no_process_warnings = true; } else if (strcmp(arg, "--trace-warnings") == 0) { trace_warnings = true; + } else if (strncmp(arg, "--redirect-warnings=", 20) == 0) { + config_warning_file = arg + 20; } else if (strcmp(arg, "--trace-deprecation") == 0) { trace_deprecation = true; } else if (strcmp(arg, "--trace-sync-io") == 0) { @@ -4401,6 +4410,10 @@ void Init(int* argc, if (openssl_config.empty()) SafeGetenv("OPENSSL_CONF", &openssl_config); + if (auto redirect_warnings = secure_getenv("NODE_REDIRECT_WARNINGS")) { + config_warning_file = redirect_warnings; + } + // Parse a few arguments which are specific to Node. int v8_argc; const char** v8_argv; diff --git a/src/node_config.cc b/src/node_config.cc index 4408bc3cf33ffc..c80e3f640da99a 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -12,6 +12,7 @@ using v8::Context; using v8::Local; using v8::Object; using v8::ReadOnly; +using v8::String; using v8::Value; // The config binding is used to provide an internal view of compile or runtime @@ -47,6 +48,15 @@ void InitConfig(Local target, if (config_expose_internals) READONLY_BOOLEAN_PROPERTY("exposeInternals"); + + if (config_warning_file != nullptr) { + Local name = OneByteString(env->isolate(), "warningFile"); + Local value = String::NewFromUtf8(env->isolate(), + config_warning_file, + v8::NewStringType::kNormal) + .ToLocalChecked(); + target->DefineOwnProperty(env->context(), name, value).FromJust(); + } } // InitConfig } // namespace node diff --git a/src/node_internals.h b/src/node_internals.h index e93244a94c6927..642e61c2c26939 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -49,6 +49,11 @@ extern bool config_preserve_symlinks; // that is used by lib/internal/bootstrap_node.js extern bool config_expose_internals; +// Set in node.cc by ParseArgs when --redirect-warnings= is used. +// Used to redirect warning output to a file rather than sending +// it to stderr. +extern const char* config_warning_file; + // Forward declaration class Environment; diff --git a/test/parallel/test-process-redirect-warnings-env.js b/test/parallel/test-process-redirect-warnings-env.js new file mode 100644 index 00000000000000..86942dc9e88e11 --- /dev/null +++ b/test/parallel/test-process-redirect-warnings-env.js @@ -0,0 +1,25 @@ +'use strict'; + +// Tests the NODE_REDIRECT_WARNINGS environment variable by spawning +// a new child node process that emits a warning into a temporary +// warnings file. Once the process completes, the warning file is +// opened and the contents are validated + +const common = require('../common'); +const fs = require('fs'); +const fork = require('child_process').fork; +const path = require('path'); +const assert = require('assert'); + +common.refreshTmpDir(); + +const warnmod = require.resolve(common.fixturesDir + '/warnings.js'); +const warnpath = path.join(common.tmpDir, 'warnings.txt'); + +fork(warnmod, {env: {NODE_REDIRECT_WARNINGS: warnpath}}) + .on('exit', common.mustCall(() => { + fs.readFile(warnpath, 'utf8', common.mustCall((err, data) => { + assert.ifError(err); + assert(/\(node:\d+\) Warning: a bad practice warning/.test(data)); + })); + })); diff --git a/test/parallel/test-process-redirect-warnings.js b/test/parallel/test-process-redirect-warnings.js new file mode 100644 index 00000000000000..b798e41bf6b5e4 --- /dev/null +++ b/test/parallel/test-process-redirect-warnings.js @@ -0,0 +1,25 @@ +'use strict'; + +// Tests the --redirect-warnings command line flag by spawning +// a new child node process that emits a warning into a temporary +// warnings file. Once the process completes, the warning file is +// opened and the contents are validated + +const common = require('../common'); +const fs = require('fs'); +const fork = require('child_process').fork; +const path = require('path'); +const assert = require('assert'); + +common.refreshTmpDir(); + +const warnmod = require.resolve(common.fixturesDir + '/warnings.js'); +const warnpath = path.join(common.tmpDir, 'warnings.txt'); + +fork(warnmod, {execArgv: [`--redirect-warnings=${warnpath}`]}) + .on('exit', common.mustCall(() => { + fs.readFile(warnpath, 'utf8', common.mustCall((err, data) => { + assert.ifError(err); + assert(/\(node:\d+\) Warning: a bad practice warning/.test(data)); + })); + })); From 68f698c05a2097afccdf22525b3e4d591d2c9fdf Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Tue, 10 Oct 2017 16:17:34 -0700 Subject: [PATCH 011/128] src: use SafeGetenv() for NODE_REDIRECT_WARNINGS Mutations of the environment can invalidate pointers to environment variables, so make `secure_getenv()` copy them out instead of returning pointers. This is the part of https://github.com/nodejs/node/pull/11051 that applies to be11fb48d2f1b3f6. This part wasn't backported to 6.x when #11051 was backported because the semver-minor introduction of NODE_REDIRECT_WARNINGS hadn't been backported yet. Now that the env var is backported, this last bit of #11051 is needed. PR-URL: https://github.com/nodejs/node/pull/12677 Reviewed-By: Gibson Fahnestock Reviewed-By: Michael Dawson --- src/node.cc | 7 +++---- src/node_config.cc | 7 ++++--- src/node_internals.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/node.cc b/src/node.cc index c5be22a7251330..4d21f971117dbc 100644 --- a/src/node.cc +++ b/src/node.cc @@ -207,7 +207,7 @@ bool config_preserve_symlinks = false; bool config_expose_internals = false; // Set in node.cc by ParseArgs when --redirect-warnings= is used. -const char* config_warning_file; +std::string config_warning_file; // NOLINT(runtime/string) // process-relative uptime base, initialized at start-up static double prog_start_time; @@ -4410,9 +4410,8 @@ void Init(int* argc, if (openssl_config.empty()) SafeGetenv("OPENSSL_CONF", &openssl_config); - if (auto redirect_warnings = secure_getenv("NODE_REDIRECT_WARNINGS")) { - config_warning_file = redirect_warnings; - } + if (config_warning_file.empty()) + SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file); // Parse a few arguments which are specific to Node. int v8_argc; diff --git a/src/node_config.cc b/src/node_config.cc index c80e3f640da99a..0e6184709642ea 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -49,11 +49,12 @@ void InitConfig(Local target, if (config_expose_internals) READONLY_BOOLEAN_PROPERTY("exposeInternals"); - if (config_warning_file != nullptr) { + if (!config_warning_file.empty()) { Local name = OneByteString(env->isolate(), "warningFile"); Local value = String::NewFromUtf8(env->isolate(), - config_warning_file, - v8::NewStringType::kNormal) + config_warning_file.data(), + v8::NewStringType::kNormal, + config_warning_file.size()) .ToLocalChecked(); target->DefineOwnProperty(env->context(), name, value).FromJust(); } diff --git a/src/node_internals.h b/src/node_internals.h index 642e61c2c26939..adcb7f835a3451 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -52,7 +52,7 @@ extern bool config_expose_internals; // Set in node.cc by ParseArgs when --redirect-warnings= is used. // Used to redirect warning output to a file rather than sending // it to stderr. -extern const char* config_warning_file; +extern std::string config_warning_file; // Forward declaration class Environment; From 8f4214836e6201dcc19aab1741572c72844b36a8 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Wed, 5 Apr 2017 11:45:52 -0700 Subject: [PATCH 012/128] src: use a std::vector for preload_modules A dynamically allocated array was being used, simplify the memory management by using std::vector. Backport-PR-URL: https://github.com/nodejs/node/pull/12677 PR-URL: https://github.com/nodejs/node/pull/12241 Reviewed-By: Richard Lau Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen --- src/node.cc | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/node.cc b/src/node.cc index 4d21f971117dbc..3214d58f48fcf3 100644 --- a/src/node.cc +++ b/src/node.cc @@ -142,8 +142,7 @@ static bool throw_deprecation = false; static bool trace_sync_io = false; static bool track_heap_objects = false; static const char* eval_string = nullptr; -static unsigned int preload_module_count = 0; -static const char** preload_modules = nullptr; +static std::vector preload_modules; #if HAVE_INSPECTOR static bool use_inspector = false; #else @@ -3328,21 +3327,18 @@ void SetupProcessObject(Environment* env, } // -r, --require - if (preload_module_count) { - CHECK(preload_modules); + if (!preload_modules.empty()) { Local array = Array::New(env->isolate()); - for (unsigned int i = 0; i < preload_module_count; ++i) { + for (unsigned int i = 0; i < preload_modules.size(); ++i) { Local module = String::NewFromUtf8(env->isolate(), - preload_modules[i]); + preload_modules[i].c_str()); array->Set(i, module); } READONLY_PROPERTY(process, "_preload_modules", array); - delete[] preload_modules; - preload_modules = nullptr; - preload_module_count = 0; + preload_modules.clear(); } // --no-deprecation @@ -3798,13 +3794,11 @@ static void ParseArgs(int* argc, const char** new_exec_argv = new const char*[nargs]; const char** new_v8_argv = new const char*[nargs]; const char** new_argv = new const char*[nargs]; - const char** local_preload_modules = new const char*[nargs]; for (unsigned int i = 0; i < nargs; ++i) { new_exec_argv[i] = nullptr; new_v8_argv[i] = nullptr; new_argv[i] = nullptr; - local_preload_modules[i] = nullptr; } // exec_argv starts with the first option, the other two start with argv[0]. @@ -3862,7 +3856,7 @@ static void ParseArgs(int* argc, exit(9); } args_consumed += 1; - local_preload_modules[preload_module_count++] = module; + preload_modules.push_back(module); } else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) { syntax_check_only = true; } else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) { @@ -3952,16 +3946,6 @@ static void ParseArgs(int* argc, memcpy(argv, new_argv, new_argc * sizeof(*argv)); delete[] new_argv; *argc = static_cast(new_argc); - - // Copy the preload_modules from the local array to an appropriately sized - // global array. - if (preload_module_count > 0) { - CHECK(!preload_modules); - preload_modules = new const char*[preload_module_count]; - memcpy(preload_modules, local_preload_modules, - preload_module_count * sizeof(*preload_modules)); - } - delete[] local_preload_modules; } From dd6ea892172cf78eb65024851662ba787f3afc72 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Mon, 20 Feb 2017 06:18:43 -0800 Subject: [PATCH 013/128] src: allow CLI args in env with NODE_OPTIONS Not all CLI options are supported, those that are problematic from a security or implementation point of view are disallowed, as are ones that are inappropriate (for example, -e, -p, --i), or that only make sense when changed with code changes (such as options that change the javascript syntax or add new APIs). Backport-PR-URL: https://github.com/nodejs/node/pull/12677 PR-URL: https://github.com/nodejs/node/pull/12028 Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Refael Ackermann Reviewed-By: Gibson Fahnestock Reviewed-By: Bradley Farias --- configure | 8 ++ doc/api/cli.md | 35 +++++ doc/node.1 | 7 + src/node.cc | 169 +++++++++++++++++++------ test/parallel/test-cli-node-options.js | 74 +++++++++++ vcbuild.bat | 6 +- 6 files changed, 260 insertions(+), 39 deletions(-) create mode 100644 test/parallel/test-cli-node-options.js diff --git a/configure b/configure index 7272e19261b238..1eaf26c0955575 100755 --- a/configure +++ b/configure @@ -444,6 +444,11 @@ parser.add_option('--without-ssl', dest='without_ssl', help='build without SSL (disables crypto, https, inspector, etc.)') +parser.add_option('--without-node-options', + action='store_true', + dest='without_node_options', + help='build without NODE_OPTIONS support') + parser.add_option('--xcode', action='store_true', dest='use_xcode', @@ -975,6 +980,9 @@ def configure_openssl(o): o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 if options.use_openssl_ca_store: o['defines'] += ['NODE_OPENSSL_CERT_STORE'] + o['variables']['node_without_node_options'] = b(options.without_node_options) + if options.without_node_options: + o['defines'] += ['NODE_WITHOUT_NODE_OPTIONS'] if options.openssl_fips: o['variables']['openssl_fips'] = options.openssl_fips fips_dir = os.path.join(root_dir, 'deps', 'openssl', 'fips') diff --git a/doc/api/cli.md b/doc/api/cli.md index 09fabb77334ff3..8346a262d9c433 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -332,6 +332,41 @@ added: v6.11.0 When set to `1`, process warnings are silenced. +### `NODE_OPTIONS=options...` + + +`options...` are interpreted as if they had been specified on the command line +before the actual command line (so they can be overriden). Node will exit with +an error if an option that is not allowed in the environment is used, such as +`-p` or a script file. + +Node options that are allowed are: +- `--enable-fips` +- `--force-fips` +- `--icu-data-dir` +- `--no-deprecation` +- `--no-warnings` +- `--openssl-config` +- `--prof-process` +- `--redirect-warnings` +- `--require`, `-r` +- `--throw-deprecation` +- `--trace-deprecation` +- `--trace-events-enabled` +- `--trace-sync-io` +- `--trace-warnings` +- `--track-heap-objects` +- `--use-bundled-ca` +- `--use-openssl-ca` +- `--v8-pool-size` +- `--zero-fill-buffers` + +V8 options that are allowed are: +- `--max_old_space_size` + + ### `NODE_REPL_HISTORY=file` * `fd` {integer} -* `buffer` {string | Buffer} +* `buffer` {Buffer} * `offset` {integer} * `length` {integer} * `position` {integer} @@ -1908,19 +1908,19 @@ On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. -## fs.write(fd, data[, position[, encoding]], callback) +## fs.write(fd, string[, position[, encoding]], callback) * `fd` {integer} -* `data` {string | Buffer} +* `string` {string} * `position` {integer} * `encoding` {string} * `callback` {Function} -Write `data` to the file specified by `fd`. If `data` is not a Buffer instance -then the value will be coerced to a string. +Write `string` to the file specified by `fd`. If `string` is not a string, then +the value will be coerced to one. `position` refers to the offset from the beginning of the file where this data should be written. If `typeof position !== 'number'` the data will be written at @@ -2001,24 +2001,24 @@ added: v0.1.29 The synchronous version of [`fs.writeFile()`][]. Returns `undefined`. -## fs.writeSync(fd, buffer, offset, length[, position]) +## fs.writeSync(fd, buffer[, offset[, length[, position]]]) * `fd` {integer} -* `buffer` {string | Buffer} +* `buffer` {Buffer} * `offset` {integer} * `length` {integer} * `position` {integer} -## fs.writeSync(fd, data[, position[, encoding]]) +## fs.writeSync(fd, string[, position[, encoding]]) * `fd` {integer} -* `data` {string | Buffer} +* `string` {string} * `position` {integer} * `encoding` {string} diff --git a/lib/fs.js b/lib/fs.js index 10e960504a79bc..e6ab7ba6d6986d 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -740,7 +740,7 @@ fs.readSync = function(fd, buffer, offset, length, position) { }; // usage: -// fs.write(fd, buffer, offset, length[, position], callback); +// fs.write(fd, buffer[, offset[, length[, position]]], callback); // OR // fs.write(fd, string[, position[, encoding]], callback); fs.write = function(fd, buffer, offset, length, position, callback) { @@ -753,12 +753,16 @@ fs.write = function(fd, buffer, offset, length, position, callback) { req.oncomplete = wrapper; if (buffer instanceof Buffer) { - // if no position is passed then assume null - if (typeof position === 'function') { - callback = position; + callback = maybeCallback(callback || position || length || offset); + if (typeof offset !== 'number') { + offset = 0; + } + if (typeof length !== 'number') { + length = buffer.length - offset; + } + if (typeof position !== 'number') { position = null; } - callback = maybeCallback(callback); return binding.writeBuffer(fd, buffer, offset, length, position, req); } @@ -778,13 +782,17 @@ fs.write = function(fd, buffer, offset, length, position, callback) { }; // usage: -// fs.writeSync(fd, buffer, offset, length[, position]); +// fs.writeSync(fd, buffer[, offset[, length[, position]]]); // OR // fs.writeSync(fd, string[, position[, encoding]]); fs.writeSync = function(fd, buffer, offset, length, position) { if (buffer instanceof Buffer) { if (position === undefined) position = null; + if (typeof offset !== 'number') + offset = 0; + if (typeof length !== 'number') + length = buffer.length - offset; return binding.writeBuffer(fd, buffer, offset, length, position); } if (typeof buffer !== 'string') diff --git a/test/parallel/test-fs-write-buffer.js b/test/parallel/test-fs-write-buffer.js index 61b00c9baba452..d52ccf263980ec 100644 --- a/test/parallel/test-fs-write-buffer.js +++ b/test/parallel/test-fs-write-buffer.js @@ -2,29 +2,107 @@ const common = require('../common'); const assert = require('assert'); const path = require('path'); -const Buffer = require('buffer').Buffer; const fs = require('fs'); -const filename = path.join(common.tmpDir, 'write.txt'); const expected = Buffer.from('hello'); common.refreshTmpDir(); -fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { - if (err) throw err; - - fs.write(fd, - expected, - 0, - expected.length, - null, - common.mustCall(function(err, written) { - if (err) throw err; - - assert.strictEqual(expected.length, written); - fs.closeSync(fd); - - const found = fs.readFileSync(filename, 'utf8'); - assert.deepStrictEqual(expected.toString(), found); - fs.unlinkSync(filename); - })); -})); +// fs.write with all parameters provided: +{ + const filename = path.join(common.tmpDir, 'write1.txt'); + fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { + assert.ifError(err); + + const cb = common.mustCall(function(err, written) { + assert.ifError(err); + + assert.strictEqual(expected.length, written); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, 0, expected.length, null, cb); + })); +} + +// fs.write with a buffer, without the length parameter: +{ + const filename = path.join(common.tmpDir, 'write2.txt'); + fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { + assert.ifError(err); + + const cb = common.mustCall(function(err, written) { + assert.ifError(err); + + assert.strictEqual(2, written); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual('lo', found); + }); + + fs.write(fd, Buffer.from('hello'), 3, cb); + })); +} + +// fs.write with a buffer, without the offset and length parameters: +{ + const filename = path.join(common.tmpDir, 'write3.txt'); + fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { + assert.ifError(err); + + const cb = common.mustCall(function(err, written) { + assert.ifError(err); + + assert.strictEqual(expected.length, written); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, cb); + })); +} + +// fs.write with the offset passed as undefined followed by the callback: +{ + const filename = path.join(common.tmpDir, 'write4.txt'); + fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { + assert.ifError(err); + + const cb = common.mustCall(function(err, written) { + assert.ifError(err); + + assert.strictEqual(expected.length, written); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, undefined, cb); + })); +} + +// fs.write with offset and length passed as undefined followed by the callback: +{ + const filename = path.join(common.tmpDir, 'write5.txt'); + fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { + assert.ifError(err); + + const cb = common.mustCall(function(err, written) { + assert.ifError(err); + + assert.strictEqual(expected.length, written); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, undefined, undefined, cb); + })); +} diff --git a/test/parallel/test-fs-write-sync.js b/test/parallel/test-fs-write-sync.js index fb97deb268f093..f663d4a5bfe5f5 100644 --- a/test/parallel/test-fs-write-sync.js +++ b/test/parallel/test-fs-write-sync.js @@ -3,21 +3,54 @@ const common = require('../common'); const assert = require('assert'); const path = require('path'); const fs = require('fs'); -const fn = path.join(common.tmpDir, 'write.txt'); +const filename = path.join(common.tmpDir, 'write.txt'); common.refreshTmpDir(); -const foo = 'foo'; -const fd = fs.openSync(fn, 'w'); +// fs.writeSync with all parameters provided: +{ + const fd = fs.openSync(filename, 'w'); -let written = fs.writeSync(fd, ''); -assert.strictEqual(0, written); + let written = fs.writeSync(fd, ''); + assert.strictEqual(0, written); -fs.writeSync(fd, foo); + fs.writeSync(fd, 'foo'); -const bar = 'bár'; -written = fs.writeSync(fd, Buffer.from(bar), 0, Buffer.byteLength(bar)); -assert.ok(written > 3); -fs.closeSync(fd); + written = fs.writeSync(fd, Buffer.from('bár'), 0, Buffer.byteLength('bár')); + assert.ok(written > 3); + fs.closeSync(fd); -assert.strictEqual(fs.readFileSync(fn, 'utf8'), 'foobár'); + assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár'); +} + +// fs.writeSync with a buffer, without the length parameter: +{ + const fd = fs.openSync(filename, 'w'); + + let written = fs.writeSync(fd, ''); + assert.strictEqual(0, written); + + fs.writeSync(fd, 'foo'); + + written = fs.writeSync(fd, Buffer.from('bár'), 0); + assert.ok(written > 3); + fs.closeSync(fd); + + assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár'); +} + +// fs.writeSync with a buffer, without the offset and length parameters: +{ + const fd = fs.openSync(filename, 'w'); + + let written = fs.writeSync(fd, ''); + assert.strictEqual(0, written); + + fs.writeSync(fd, 'foo'); + + written = fs.writeSync(fd, Buffer.from('bár')); + assert.ok(written > 3); + fs.closeSync(fd); + + assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár'); +} From c9d440e8bd87eda968c4946a77381ebec1c6600c Mon Sep 17 00:00:00 2001 From: Fabio Campinho Date: Thu, 13 Apr 2017 17:26:00 -0300 Subject: [PATCH 020/128] test: change == to === in crypto test Changed the equality comparison from == to identity operator === PR-URL: https://github.com/nodejs/node/pull/12405 Reviewed-By: Anna Henningsen Reviewed-By: Vse Mozhet Byt Reviewed-By: Rich Trott Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Alexey Orlenko --- test/parallel/test-crypto-sign-verify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index fa410de4a62b4f..bb436c340e312a 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -142,7 +142,7 @@ const modSize = 1024; padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: verifySaltLength }, s4); - const saltLengthCorrect = getEffectiveSaltLength(signSaltLength) == + const saltLengthCorrect = getEffectiveSaltLength(signSaltLength) === getEffectiveSaltLength(verifySaltLength); assert.strictEqual(verified, saltLengthCorrect, 'verify (PSS)'); }); From 7b9710d0df4283ac24371bd195c802e0d48d4732 Mon Sep 17 00:00:00 2001 From: dave-k Date: Tue, 18 Apr 2017 19:09:27 -0700 Subject: [PATCH 021/128] test: add inspect-brk option to cluster module Ensure that cluster interoperates with the --inspect-brk option. This does not test for --debug-brk. Fixes: https://github.com/nodejs/node/issues/11420 PR-URL: https://github.com/nodejs/node/pull/12503 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Colin Ihrig --- test/sequential/test-cluster-inspect-brk.js | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/sequential/test-cluster-inspect-brk.js diff --git a/test/sequential/test-cluster-inspect-brk.js b/test/sequential/test-cluster-inspect-brk.js new file mode 100644 index 00000000000000..0fb0b9eaab5b68 --- /dev/null +++ b/test/sequential/test-cluster-inspect-brk.js @@ -0,0 +1,36 @@ +'use strict'; +const common = require('../common'); + +// A test to ensure that cluster properly interoperates with the +// --inspect-brk option. + +const assert = require('assert'); +const cluster = require('cluster'); +const debuggerPort = common.PORT; + +if (cluster.isMaster) { + function test(execArgv) { + + cluster.setupMaster({ + execArgv: execArgv, + stdio: ['pipe', 'pipe', 'pipe', 'ipc', 'pipe'] + }); + + const worker = cluster.fork(); + + // Debugger listening on port [port]. + worker.process.stderr.once('data', common.mustCall(function() { + worker.process.kill('SIGTERM'); + })); + + worker.process.on('exit', common.mustCall(function(code, signal) { + assert.strictEqual(signal, 'SIGTERM'); + })); + } + + test(['--inspect-brk']); + test([`--inspect-brk=${debuggerPort}`]); +} else { + // Cluster worker is at a breakpoint, should not reach here. + assert.fail('Test failed: cluster worker should be at a breakpoint.'); +} From d25dc797f4f7c58876560ba0b8ce0527c7021cbb Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Sun, 30 Apr 2017 08:18:23 +0200 Subject: [PATCH 022/128] test: skipIfInspectorDisabled cluster-inspect-brk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When configured --without-ssl the inspect-brk option will not be available and the process will exit with a exit value of 9 "Invalid Argument/Bad option". This commit adds a skipIfInspectorDisabled check since --without-ssl implies that no inspector support is build as well. PR-URL: https://github.com/nodejs/node/pull/12757 Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- test/common/index.js | 7 +++++++ test/sequential/test-cluster-inspect-brk.js | 1 + 2 files changed, 8 insertions(+) diff --git a/test/common/index.js b/test/common/index.js index 96e2b12c7a8193..7b4d2014f6bc23 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -575,3 +575,10 @@ exports.crashOnUnhandledRejection = function() { process.on('unhandledRejection', (err) => process.nextTick(() => { throw err; })); }; + +exports.skipIfInspectorDisabled = function skipIfInspectorDisabled() { + if (!exports.hasCrypto) { + exports.skip('missing ssl support so inspector is disabled'); + process.exit(0); + } +}; diff --git a/test/sequential/test-cluster-inspect-brk.js b/test/sequential/test-cluster-inspect-brk.js index 0fb0b9eaab5b68..95c9b3c51177e1 100644 --- a/test/sequential/test-cluster-inspect-brk.js +++ b/test/sequential/test-cluster-inspect-brk.js @@ -1,5 +1,6 @@ 'use strict'; const common = require('../common'); +common.skipIfInspectorDisabled(); // A test to ensure that cluster properly interoperates with the // --inspect-brk option. From 326584050487a56a760614a96684e184c16ba6f7 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Tue, 30 May 2017 13:19:11 -0400 Subject: [PATCH 023/128] deps: upgrade libuv to 1.12.0 Fixes: https://github.com/nodejs/node/issues/12853 Fixes: https://github.com/nodejs/node/issues/854 PR-URL: https://github.com/nodejs/node/pull/13306 Reviewed-By: Santiago Gimeno Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson --- deps/uv/.mailmap | 2 + deps/uv/AUTHORS | 8 + deps/uv/ChangeLog | 175 +++++ deps/uv/LICENSE-docs | 396 ++++++++++++ deps/uv/MAINTAINERS.md | 1 + deps/uv/Makefile.am | 62 +- deps/uv/Makefile.mingw | 1 + deps/uv/README.md | 6 +- deps/uv/SUPPORTED_PLATFORMS.md | 2 +- deps/uv/appveyor.yml | 2 +- deps/uv/checksparse.sh | 3 + deps/uv/common.gypi | 1 + deps/uv/configure.ac | 9 +- deps/uv/docs/src/api.rst | 35 + deps/uv/docs/src/conf.py | 18 +- deps/uv/docs/src/design.rst | 19 +- deps/uv/docs/src/fs.rst | 28 +- deps/uv/docs/src/fs_event.rst | 12 +- deps/uv/docs/src/fs_poll.rst | 9 +- deps/uv/docs/src/guide.rst | 22 + deps/uv/docs/src/handle.rst | 4 +- deps/uv/docs/src/index.rst | 63 +- deps/uv/docs/src/loop.rst | 59 +- deps/uv/docs/src/misc.rst | 56 +- deps/uv/docs/src/signal.rst | 7 + deps/uv/docs/src/threadpool.rst | 2 +- deps/uv/docs/src/upgrading.rst | 11 + deps/uv/include/uv-posix.h | 31 + deps/uv/include/uv-unix.h | 17 +- deps/uv/include/uv-version.h | 2 +- deps/uv/include/uv.h | 11 + deps/uv/samples/socks5-proxy/client.c | 5 +- deps/uv/src/threadpool.c | 35 +- deps/uv/src/unix/aix.c | 7 + deps/uv/src/unix/async.c | 121 ++-- deps/uv/src/unix/bsd-ifaddrs.c | 139 ++++ deps/uv/src/unix/core.c | 96 ++- deps/uv/src/unix/cygwin.c | 54 ++ deps/uv/src/unix/darwin.c | 104 --- deps/uv/src/unix/freebsd.c | 114 ---- deps/uv/src/unix/fsevents.c | 3 - deps/uv/src/unix/internal.h | 25 +- deps/uv/src/unix/kqueue.c | 36 +- deps/uv/src/unix/linux-core.c | 102 +-- deps/uv/src/unix/linux-inotify.c | 67 ++ deps/uv/src/unix/loop.c | 38 +- deps/uv/src/unix/netbsd.c | 108 ---- deps/uv/src/unix/no-fsevents.c | 42 ++ deps/uv/src/unix/no-proctitle.c | 42 ++ deps/uv/src/unix/openbsd.c | 114 +--- deps/uv/src/unix/os390-syscalls.c | 2 +- deps/uv/src/unix/os390.c | 28 +- deps/uv/src/unix/pipe.c | 16 +- deps/uv/src/unix/posix-hrtime.c | 35 + deps/uv/src/unix/posix-poll.c | 324 ++++++++++ deps/uv/src/unix/procfs-exepath.c | 45 ++ deps/uv/src/unix/signal.c | 100 ++- deps/uv/src/unix/stream.c | 24 +- deps/uv/src/unix/sunos.c | 57 +- deps/uv/src/unix/sysinfo-loadavg.c | 36 ++ deps/uv/src/unix/sysinfo-memory.c | 42 ++ deps/uv/src/unix/udp.c | 33 +- deps/uv/src/uv-common.h | 35 +- deps/uv/src/win/async.c | 3 +- deps/uv/src/win/atomicops-inl.h | 3 +- deps/uv/src/win/core.c | 21 +- deps/uv/src/win/detect-wakeup.c | 6 +- deps/uv/src/win/fs-event.c | 36 +- deps/uv/src/win/fs.c | 10 +- deps/uv/src/win/getaddrinfo.c | 4 +- deps/uv/src/win/getnameinfo.c | 3 +- deps/uv/src/win/handle.c | 5 + deps/uv/src/win/internal.h | 23 +- deps/uv/src/win/pipe.c | 17 +- deps/uv/src/win/poll.c | 10 +- deps/uv/src/win/process.c | 3 +- deps/uv/src/win/req-inl.h | 9 +- deps/uv/src/win/signal.c | 45 +- deps/uv/src/win/stream-inl.h | 3 +- deps/uv/src/win/stream.c | 3 +- deps/uv/src/win/tcp.c | 13 +- deps/uv/src/win/tty.c | 5 +- deps/uv/src/win/udp.c | 6 +- deps/uv/src/win/util.c | 195 +++++- deps/uv/src/win/winapi.c | 2 +- deps/uv/src/win/winsock.c | 2 +- deps/uv/test/runner-win.c | 24 +- deps/uv/test/task.h | 20 + deps/uv/test/test-env-vars.c | 90 +++ deps/uv/test/test-fork.c | 677 ++++++++++++++++++++ deps/uv/test/test-fs-event.c | 66 +- deps/uv/test/test-fs.c | 69 +- deps/uv/test/test-gethostname.c | 62 ++ deps/uv/test/test-ip6-addr.c | 4 + deps/uv/test/test-ipc-send-recv.c | 14 +- deps/uv/test/test-ipc.c | 12 + deps/uv/test/test-list.h | 44 ++ deps/uv/test/test-ping-pong.c | 4 + deps/uv/test/test-pipe-bind-error.c | 3 + deps/uv/test/test-pipe-connect-multiple.c | 3 + deps/uv/test/test-pipe-getsockname.c | 3 + deps/uv/test/test-pipe-sendmsg.c | 3 + deps/uv/test/test-pipe-server-close.c | 3 + deps/uv/test/test-platform-output.c | 8 + deps/uv/test/test-poll.c | 9 +- deps/uv/test/test-process-title.c | 4 +- deps/uv/test/test-ref.c | 4 +- deps/uv/test/test-shutdown-twice.c | 1 + deps/uv/test/test-signal-multiple-loops.c | 7 + deps/uv/test/test-signal.c | 146 ++++- deps/uv/test/test-spawn.c | 30 +- deps/uv/test/test-tcp-create-socket-early.c | 2 +- deps/uv/test/test-tcp-write-queue-order.c | 6 +- deps/uv/test/test-threadpool-cancel.c | 5 +- deps/uv/test/test-tty.c | 2 +- deps/uv/test/test-udp-create-socket-early.c | 2 +- deps/uv/test/test-udp-ipv6.c | 5 + deps/uv/test/test-udp-send-hang-loop.c | 99 +++ deps/uv/test/test-udp-send-immediate.c | 1 + deps/uv/test/test-watcher-cross-stop.c | 5 + deps/uv/tools/make_dist_html.py | 124 ++++ deps/uv/uv.gyp | 25 +- 122 files changed, 4134 insertions(+), 982 deletions(-) create mode 100644 deps/uv/LICENSE-docs create mode 100644 deps/uv/docs/src/api.rst create mode 100644 deps/uv/docs/src/guide.rst create mode 100644 deps/uv/docs/src/upgrading.rst create mode 100644 deps/uv/include/uv-posix.h create mode 100644 deps/uv/src/unix/bsd-ifaddrs.c create mode 100644 deps/uv/src/unix/cygwin.c create mode 100644 deps/uv/src/unix/no-fsevents.c create mode 100644 deps/uv/src/unix/no-proctitle.c create mode 100644 deps/uv/src/unix/posix-hrtime.c create mode 100644 deps/uv/src/unix/posix-poll.c create mode 100644 deps/uv/src/unix/procfs-exepath.c create mode 100644 deps/uv/src/unix/sysinfo-loadavg.c create mode 100644 deps/uv/src/unix/sysinfo-memory.c create mode 100644 deps/uv/test/test-env-vars.c create mode 100644 deps/uv/test/test-fork.c create mode 100644 deps/uv/test/test-gethostname.c create mode 100644 deps/uv/test/test-udp-send-hang-loop.c create mode 100644 deps/uv/tools/make_dist_html.py diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index 8acf8fecd14003..618274c0d2e242 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -1,3 +1,4 @@ +A. Hauptmann Aaron Bieber Alan Gutierrez Andrius Bentkus @@ -39,3 +40,4 @@ Timothy J. Fontaine Yasuhiro Matsumoto Yazhong Liu Yuki Okumura +jBarz diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 4719d2368aec9d..ab4e099f167379 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -284,3 +284,11 @@ muflub Daniel Bevenius Howard Hellyer Chris Araman +Vladimir Matveev +Jason Madden +Jamie Davis +Daniel Kahn Gillmor +Keane +James McCoy +Bernardo Ramos +Juan Cruz Viotti diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index da4c3b13f14eb2..71b210f44bddf1 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,178 @@ +2017.05.31, Version 1.12.0 (Stable), d6ac141ac674657049598c36604f26e031fae917 + +Changes since version 1.11.0: + +* Now working on version 1.11.1 (cjihrig) + +* test: fix tests on OpenBSD (Santiago Gimeno) + +* test: fix -Wformat warning (Santiago Gimeno) + +* win,fs: avoid double freeing uv_fs_event_t.dirw (Vladimir Matveev) + +* unix: remove unused code in `uv__io_start` (Fedor Indutny) + +* signal: add uv_signal_start_oneshot method (Santiago Gimeno) + +* unix: factor out reusable POSIX hrtime impl (Brad King) + +* unix,win: add uv_os_{get,set,unset}env() (cjihrig) + +* win: add uv__convert_utf8_to_utf16() (cjihrig) + +* docs: improve UV_ENOBUFS scenario documentation (cjihrig) + +* unix: return UV_EINVAL for NULL env name (jBarz) + +* unix: filter getifaddrs results consistently (Brad King) + +* unix: factor out getifaddrs result filter (Brad King) + +* unix: factor out reusable BSD ifaddrs impl (Brad King) + +* unix: use union to follow strict aliasing rules (jBarz) + +* unix: simplify async watcher dispatch logic (Ben Noordhuis) + +* samples: update timer callback prototype (Ben Noordhuis) + +* unix: make loops and watchers usable after fork() (Jason Madden) + +* win: free uv__loops once empty (cjihrig) + +* tools: add make_dist_html.py script (Ben Noordhuis) + +* win,sunos: stop handle on uv_fs_event_start() err (cjihrig) + +* unix,windows: refactor request init logic (Ben Noordhuis) + +* win: fix memory leak inside uv__pipe_getname (A. Hauptmann) + +* fsevent: support for files without short name (Bartosz Sosnowski) + +* doc: fix multiple doc typos (Jamie Davis) + +* test,osx: fix flaky kill test (Santiago Gimeno) + +* unix: inline uv_pipe_bind() err_bind goto target (cjihrig) + +* unix,test: deadstore fixes (Rasmus Christian Pedersen) + +* win: fix memory leak inside uv_fs_access() (A. Hauptmann) + +* doc: fix docs/src/fs.rst build warning (Daniel Bevenius) + +* doc: minor grammar fix in Installation section (Daniel Bevenius) + +* doc: suggestions for design page (Daniel Bevenius) + +* doc: libuv does not touch uv_loop_t.data (Ben Noordhuis) + +* github: add ISSUE_TEMPLATE.md (Ben Noordhuis) + +* doc: add link to libuv/help to README (Ben Noordhuis) + +* udp: fix fast path in uv_udp_send() on unix (Fedor Indutny) + +* test: add test for uv_udp_send() fix (Trevor Norris) + +* doc: fix documentation for uv_handle_t.type (Daniel Kahn Gillmor) + +* zos: use proper prototype for epoll_init() (Ben Noordhuis) + +* doc: rename docs to "libuv documentation" (Saúl Ibarra Corretgé) + +* doc: update copyright years (Saúl Ibarra Corretgé) + +* doc: move TOC to a dedicated document (Saúl Ibarra Corretgé) + +* doc: move documentation section up (Saúl Ibarra Corretgé) + +* doc: move "upgrading" to a standalone document (Saúl Ibarra Corretgé) + +* doc: add initial version of the User Guide (Saúl Ibarra Corretgé) + +* doc: removed unused file (Saúl Ibarra Corretgé) + +* doc: update guide/about and mention new maintainership (Saúl Ibarra Corretgé) + +* doc: remove licensing note from guide/about (Saúl Ibarra Corretgé) + +* doc: add warning note to user guide (Saúl Ibarra Corretgé) + +* doc: change license to CC BY 4.0 (Saúl Ibarra Corretgé) + +* doc: remove ubvook reference from README (Saúl Ibarra Corretgé) + +* doc: add code samples from uvbook (unadapted) (Saúl Ibarra Corretgé) + +* doc: update supported linux/glibc baseline (Ben Noordhuis) + +* win: avoid leaking pipe handles to child processes (Jameson Nash) + +* win,test: support stdout output larger than 1kb (Bartosz Sosnowski) + +* win: remove __declspec(inline) from atomic op (Keane) + +* test: fix VC++ compilation warning (Rasmus Christian Pedersen) + +* build: add -Wstrict-prototypes (Jameson Nash) + +* zos: implement uv__io_fork, skip fs event tests (jBarz) + +* unix: do not close udp sockets on bind error (Marc Schlaich) + +* unix: remove FSEventStreamFlushSync() call (cjihrig) + +* build,openbsd: remove kvm-related code (James McCoy) + +* test: fix flaky tcp-write-queue-order (Santiago Gimeno) + +* unix,win: add uv_os_gethostname() (cjihrig) + +* zos: increase timeout for tcp_writealot (jBarz) + +* zos: do not inline OOB data by default (jBarz) + +* test: fix -Wstrict-prototypes compiler warnings (Ben Noordhuis) + +* unix: factor out reusable no-proctitle impl (Brad King) + +* test: factor out fsevents skip explanation (Brad King) + +* test: skip fork fsevent cases when lacking support (Brad King) + +* unix: factor out reusable no-fsevents impl (Brad King) + +* unix: factor out reusable sysinfo memory lookup (Brad King) + +* unix: factor out reusable sysinfo loadavg impl (Brad King) + +* unix: factor out reusable procfs exepath impl (Brad King) + +* unix: add a uv__io_poll impl using POSIX poll(2) (Brad King) + +* cygwin: implement support for cygwin and msys2 (Brad King) + +* cygwin: recognize EOF on named pipe closure (Brad King) + +* cygwin: fix uv_pipe_connect report of ENOTSOCK (Brad King) + +* cygwin: disable non-functional ipc handle send (Brad King) + +* test: skip self-connecting tests on cygwin (Brad King) + +* doc: mark uv_loop_fork() as experimental (cjihrig) + +* doc: add bzoz to maintainers (Bartosz Sosnowski) + +* doc: fix memory leak in tcp-echo-server example (Bernardo Ramos) + +* win: make uv__get_osfhandle() public (Juan Cruz Viotti) + +* doc: use valid pipe name in pipe-echo-server (Bernardo Ramos) + + 2017.02.02, Version 1.11.0 (Stable), 7452ef4e06a4f99ee26b694c65476401534f2725 Changes since version 1.10.2: diff --git a/deps/uv/LICENSE-docs b/deps/uv/LICENSE-docs new file mode 100644 index 00000000000000..53883b1c7add1f --- /dev/null +++ b/deps/uv/LICENSE-docs @@ -0,0 +1,396 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md index 27a3523ea455b2..d85deb0066b131 100644 --- a/deps/uv/MAINTAINERS.md +++ b/deps/uv/MAINTAINERS.md @@ -3,6 +3,7 @@ libuv is currently managed by the following individuals: +* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz)) * **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis)) - GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis) * **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus)) diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 036464e71ecc48..404674baf211d5 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -166,16 +166,19 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-eintr-handling.c \ test/test-embed.c \ test/test-emfile.c \ + test/test-env-vars.c \ test/test-error.c \ test/test-fail-always.c \ test/test-fs-event.c \ test/test-fs-poll.c \ test/test-fs.c \ + test/test-fork.c \ test/test-get-currentexe.c \ test/test-get-loadavg.c \ test/test-get-memory.c \ test/test-get-passwd.c \ test/test-getaddrinfo.c \ + test/test-gethostname.c \ test/test-getnameinfo.c \ test/test-getsockname.c \ test/test-handle-fileno.c \ @@ -272,6 +275,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-udp-open.c \ test/test-udp-options.c \ test/test-udp-send-and-recv.c \ + test/test-udp-send-hang-loop.c \ test/test-udp-send-immediate.c \ test/test-udp-send-unreachable.c \ test/test-udp-try-send.c \ @@ -333,12 +337,26 @@ libuv_la_SOURCES += src/unix/android-ifaddrs.c \ src/unix/pthread-barrier.c endif +if CYGWIN +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + if DARWIN include_HEADERS += include/uv-darwin.h \ include/pthread-barrier.h libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1 -libuv_la_SOURCES += src/unix/darwin.c \ +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/darwin.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ @@ -349,13 +367,19 @@ endif if DRAGONFLY include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if FREEBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif @@ -366,26 +390,49 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/linux-inotify.c \ src/unix/linux-syscalls.c \ src/unix/linux-syscalls.h \ - src/unix/proctitle.c + src/unix/procfs-exepath.c \ + src/unix/proctitle.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c test_run_tests_LDFLAGS += -lutil endif +if MSYS +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + if NETBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/netbsd.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/kqueue.c \ + src/unix/netbsd.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if OPENBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/openbsd.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/kqueue.c \ + src/unix/openbsd.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if SUNOS include_HEADERS += include/uv-sunos.h libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 -libuv_la_SOURCES += src/unix/sunos.c +libuv_la_SOURCES += src/unix/no-proctitle.c \ + src/unix/sunos.c endif if OS390 @@ -407,6 +454,7 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \ libuv_la_LDFLAGS += -qXPLINK libuv_la_SOURCES += src/unix/pthread-fixes.c \ src/unix/pthread-barrier.c \ + src/unix/no-fsevents.c \ src/unix/os390.c \ src/unix/os390-syscalls.c \ src/unix/proctitle.c diff --git a/deps/uv/Makefile.mingw b/deps/uv/Makefile.mingw index 8139138fccf654..3acf9e14a9eab4 100644 --- a/deps/uv/Makefile.mingw +++ b/deps/uv/Makefile.mingw @@ -17,6 +17,7 @@ CC ?= gcc CFLAGS += -Wall \ -Wextra \ -Wno-unused-parameter \ + -Wstrict-prototypes \ -Iinclude \ -Isrc \ -Isrc/win \ diff --git a/deps/uv/README.md b/deps/uv/README.md index 284dfb47c3d951..e5d94faf0fa38e 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -44,15 +44,17 @@ The ABI/API changes can be tracked [here](http://abi-laboratory.pro/tracker/time ## Licensing libuv is licensed under the MIT license. Check the [LICENSE file](LICENSE). +The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-docs file](LICENSE-docs). ## Community + * [Support](https://github.com/libuv/help) * [Mailing list](http://groups.google.com/group/libuv) * [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4) ## Documentation -### Official API documentation +### Official documentation Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/) framework, which makes it possible to build the documentation in multiple @@ -88,8 +90,6 @@ also serve as API specification and usage examples. ### Other resources - * [An Introduction to libuv](http://nikhilm.github.com/uvbook/) - — An overview of libuv with tutorials. * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) — High-level introductory talk about libuv. * [libuv-dox](https://github.com/thlorenz/libuv-dox) diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index bff1050d6331c0..3a000c5dd25e35 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -2,7 +2,7 @@ | System | Support type | Supported versions | Notes | |---|---|---|---| -| GNU/Linux | Tier 1 | Linux >= 2.6.18 with glibc >= 2.5 | | +| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | | Windows | Tier 1 | Windows >= XP SP1 | MSVC 2008 and later are supported | | FreeBSD | Tier 1 | >= 9 (see note) | | diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index e8e79f051e89dc..c542e34b991168 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -1,4 +1,4 @@ -version: v1.11.0.build{build} +version: v1.12.0.build{build} install: - cinst -y nsis diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index 68e3bde39305da..9782718a23266c 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -93,6 +93,7 @@ test/test-cwd-and-chdir.c test/test-delayed-accept.c test/test-dlerror.c test/test-embed.c +test/test-env-vars.c test/test-error.c test/test-fail-always.c test/test-fs-event.c @@ -103,6 +104,7 @@ test/test-get-loadavg.c test/test-get-memory.c test/test-get-passwd.c test/test-getaddrinfo.c +test/test-gethostname.c test/test-getsockname.c test/test-homedir.c test/test-hrtime.c @@ -165,6 +167,7 @@ test/test-udp-multicast-ttl.c test/test-udp-open.c test/test-udp-options.c test/test-udp-send-and-recv.c +test/test-udp-send-hang-loop.c test/test-walk-handles.c test/test-watcher-cross-stop.c " diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi index 470b73385d8398..94e760030335bc 100644 --- a/deps/uv/common.gypi +++ b/deps/uv/common.gypi @@ -180,6 +180,7 @@ '-Wendif-labels', '-W', '-Wno-unused-parameter', + '-Wstrict-prototypes', ], }, 'conditions': [ diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 360652198e5acb..8ac06f7fc8c84e 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.11.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.12.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -33,6 +33,7 @@ CC_CHECK_CFLAGS_APPEND([-std=gnu89]) CC_CHECK_CFLAGS_APPEND([-Wall]) CC_CHECK_CFLAGS_APPEND([-Wextra]) CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) +CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes]) # AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) # autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR. @@ -42,7 +43,6 @@ LT_INIT # TODO(bnoordhuis) Check for -pthread vs. -pthreads AC_CHECK_LIB([dl], [dlopen]) AC_CHECK_LIB([kstat], [kstat_lookup]) -AC_CHECK_LIB([kvm], [kvm_open]) AC_CHECK_LIB([nsl], [gethostbyname]) AC_CHECK_LIB([perfstat], [perfstat_cpu]) AC_CHECK_LIB([pthread], [pthread_mutex_init]) @@ -52,10 +52,12 @@ AC_CHECK_LIB([socket], [socket]) AC_SYS_LARGEFILE AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])]) AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])]) +AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])]) AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])]) AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])]) AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])]) AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])]) +AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])]) AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])]) AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])]) AM_CONDITIONAL([OS390], [AS_CASE([$host_os],[openedition*], [true], [false])]) @@ -64,6 +66,9 @@ AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false]) AS_CASE([$host_os],[mingw*], [ LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32" ]) +AS_CASE([$host_os], [openbsd*], [], [ + AC_CHECK_LIB([kvm], [kvm_open]) +]) AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) diff --git a/deps/uv/docs/src/api.rst b/deps/uv/docs/src/api.rst new file mode 100644 index 00000000000000..22f0640f549ec8 --- /dev/null +++ b/deps/uv/docs/src/api.rst @@ -0,0 +1,35 @@ +.. _api: + +API documentation +================= + +.. toctree:: + :maxdepth: 1 + + errors + version + loop + handle + request + timer + prepare + check + idle + async + poll + signal + process + stream + tcp + pipe + tty + udp + fs_event + fs_poll + fs + threadpool + dns + dll + threading + misc + diff --git a/deps/uv/docs/src/conf.py b/deps/uv/docs/src/conf.py index 3f8689d2e5c699..c9b4ea38c310a5 100644 --- a/deps/uv/docs/src/conf.py +++ b/deps/uv/docs/src/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# libuv API documentation documentation build configuration file, created by +# libuv documentation documentation build configuration file, created by # sphinx-quickstart on Sun Jul 27 11:47:51 2014. # # This file is execfile()d with the current directory set to its @@ -64,7 +64,7 @@ def get_libuv_version(): # General information about the project. project = u'libuv API documentation' -copyright = u'libuv contributors' +copyright = u'2014-present, libuv contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -130,10 +130,10 @@ def get_libuv_version(): # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = 'libuv API documentation' +html_title = 'libuv documentation' # A shorter title for the navigation bar. Default is the same as html_title. -html_short_title = 'libuv %s API documentation' % version +html_short_title = 'libuv %s documentation' % version # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -216,7 +216,7 @@ def get_libuv_version(): # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'libuv.tex', u'libuv API documentation', + ('index', 'libuv.tex', u'libuv documentation', u'libuv contributors', 'manual'), ] @@ -246,7 +246,7 @@ def get_libuv_version(): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'libuv', u'libuv API documentation', + ('index', 'libuv', u'libuv documentation', [u'libuv contributors'], 1) ] @@ -260,7 +260,7 @@ def get_libuv_version(): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'libuv', u'libuv API documentation', + ('index', 'libuv', u'libuv documentation', u'libuv contributors', 'libuv', 'Cross-platform asynchronous I/O', 'Miscellaneous'), ] @@ -281,10 +281,10 @@ def get_libuv_version(): # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u'libuv API documentation' +epub_title = u'libuv documentation' epub_author = u'libuv contributors' epub_publisher = u'libuv contributors' -epub_copyright = u'2014, libuv contributors' +epub_copyright = u'2014-present, libuv contributors' # The basename for the epub file. It defaults to the project name. epub_basename = u'libuv' diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst index 34c3cff68e54ca..487d08ba6255ad 100644 --- a/deps/uv/docs/src/design.rst +++ b/deps/uv/docs/src/design.rst @@ -7,7 +7,7 @@ Design overview libuv is cross-platform support library which was originally written for NodeJS. It's designed around the event-driven asynchronous I/O model. -The library provides much more than simply abstraction over different I/O polling mechanisms: +The library provides much more than a simple abstraction over different I/O polling mechanisms: 'handles' and 'streams' provide a high level abstraction for sockets and other entities; cross-platform file I/O and threading functionality is also provided, amongst other things. @@ -25,9 +25,10 @@ Handles and requests libuv provides users with 2 abstractions to work with, in combination with the event loop: handles and requests. -Handles represent long-lived objects capable of performing certain operations while active. Some -examples: a prepare handle gets its callback called once every loop iteration when active, and -a TCP server handle get its connection callback called every time there is a new connection. +Handles represent long-lived objects capable of performing certain operations while active. Some examples: + +- A prepare handle gets its callback called once every loop iteration when active. +- A TCP server handle that gets its connection callback called every time there is a new connection. Requests represent (typically) short-lived operations. These operations can be performed over a handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests @@ -85,11 +86,11 @@ stages of a loop iteration: * If there are no active handles or requests, the timeout is 0. * If there are any idle handles active, the timeout is 0. * If there are any handles pending to be closed, the timeout is 0. - * If none of the above cases was matched, the timeout of the closest timer is taken, or + * If none of the above cases matches, the timeout of the closest timer is taken, or if there are no active timers, infinity. -#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated - on the previous step. All I/O related handles that were monitoring a given file descriptor +#. The loop blocks for I/O. At this point the loop will block for I/O for the duration calculated + in the previous step. All I/O related handles that were monitoring a given file descriptor for a read or write operation get their callbacks called at this point. #. Check handle callbacks are called. Check handles get their callbacks called right after the @@ -103,7 +104,7 @@ stages of a loop iteration: so there might be timers which are due, those timers get their callbacks called. #. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the - iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` + iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` it will continue from the start if it's still *alive*, otherwise it will also end. @@ -128,7 +129,7 @@ For a thorough explanation of the cross-platform file I/O landscape, checkout libuv currently uses a global thread pool on which all loops can queue work on. 3 types of operations are currently run on this pool: - * Filesystem operations + * File system operations * DNS functions (getaddrinfo and getnameinfo) * User specified code via :c:func:`uv_queue_work` diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index 192ecc7056de8e..3f766e393f2fa7 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -1,15 +1,15 @@ .. _fs: -Filesystem operations -===================== +File system operations +====================== -libuv provides a wide variety of cross-platform sync and async filesystem +libuv provides a wide variety of cross-platform sync and async file system operations. All functions defined in this document take a callback, which is allowed to be NULL. If the callback is NULL the request is completed synchronously, otherwise it will be performed asynchronously. -All file operations are run on the threadpool, see :ref:`threadpool` for information +All file operations are run on the threadpool. See :ref:`threadpool` for information on the threadpool size. @@ -18,7 +18,7 @@ Data types .. c:type:: uv_fs_t - Filesystem request type. + File system request type. .. c:type:: uv_timespec_t @@ -58,7 +58,7 @@ Data types .. c:type:: uv_fs_type - Filesystem request type. + File system request type. :: @@ -216,7 +216,7 @@ API Unlike `scandir(3)`, this function does not return the "." and ".." entries. .. note:: - On Linux, getting the type of an entry is only supported by some filesystems (btrfs, ext2, + On Linux, getting the type of an entry is only supported by some file systems (btrfs, ext2, ext3 and ext4 at the time of this writing), check the :man:`getdents(2)` man page. .. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) @@ -291,7 +291,7 @@ API Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandle `_. .. warning:: - This function has certain platform specific caveats that were discovered when used in Node. + This function has certain platform-specific caveats that were discovered when used in Node. * macOS and other BSDs: this function will fail with UV_ELOOP if more than 32 symlinks are found while resolving the given path. This limit is hardcoded and cannot be sidestepped. @@ -324,3 +324,15 @@ API These functions are not implemented on Windows. .. seealso:: The :c:type:`uv_req_t` API functions also apply. + +Helper functions +---------------- + +.. c:function:: uv_os_fd_t uv_get_osfhandle(int fd) + + For a file descriptor in the C runtime, get the OS-dependent handle. + On UNIX, returns the ``fd`` intact. On Windows, this calls `_get_osfhandle `_. + Note that the return value is still owned by the C runtime, + any attempts to close it or to use it after closing the fd may lead to malfunction. + + .. versionadded:: 1.12.0 diff --git a/deps/uv/docs/src/fs_event.rst b/deps/uv/docs/src/fs_event.rst index c08ade2ef597be..2af3e9802bd0a1 100644 --- a/deps/uv/docs/src/fs_event.rst +++ b/deps/uv/docs/src/fs_event.rst @@ -66,7 +66,7 @@ Data types UV_FS_EVENT_WATCH_ENTRY = 1, /* * By default uv_fs_event will try to use a kernel interface such as inotify - * or kqueue to detect events. This may not work on remote filesystems such + * or kqueue to detect events. This may not work on remote file systems such * as NFS mounts. This flag makes fs_event fall back to calling stat() on a * regular interval. * This flag is currently not implemented yet on any backend. @@ -74,7 +74,7 @@ Data types UV_FS_EVENT_STAT = 2, /* * By default, event watcher, when watching directory, is not registering - * (is ignoring) changes in it's subdirectories. + * (is ignoring) changes in its subdirectories. * This flag will override this behaviour on platforms that support it. */ UV_FS_EVENT_RECURSIVE = 4 @@ -113,10 +113,14 @@ API Get the path being monitored by the handle. The buffer must be preallocated by the user. Returns 0 on success or an error code < 0 in case of failure. On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size, including the null terminator. .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, and the buffer is not null terminated. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/fs_poll.rst b/deps/uv/docs/src/fs_poll.rst index 4efb2440e0baf2..2912bad9349a35 100644 --- a/deps/uv/docs/src/fs_poll.rst +++ b/deps/uv/docs/src/fs_poll.rst @@ -63,10 +63,15 @@ API Get the path being monitored by the handle. The buffer must be preallocated by the user. Returns 0 on success or an error code < 0 in case of failure. On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size. .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, and the buffer is not null terminated. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/guide.rst b/deps/uv/docs/src/guide.rst new file mode 100644 index 00000000000000..126e08082c228b --- /dev/null +++ b/deps/uv/docs/src/guide.rst @@ -0,0 +1,22 @@ +.. _guide: + +User guide +========== + +.. warning:: + The contents of this guide have been recently incorporated into the libuv documentation + and it hasn't gone through thorough review yet. If you spot a mistake please file an + issue, or better yet, open a pull request! + +.. toctree:: + :maxdepth: 2 + + guide/introduction + guide/basics + guide/filesystem + guide/networking + guide/threads + guide/processes + guide/eventloops + guide/utilities + guide/about diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index 14aec51fff1692..a0f3d05fdb1b4a 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -86,9 +86,9 @@ Public members Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly. -.. c:member:: uv_loop_t* uv_handle_t.type +.. c:member:: uv_handle_type uv_handle_t.type - Pointer to the :c:type:`uv_handle_type`. Readonly. + The :c:type:`uv_handle_type`, indicating the type of the underlying handle. Readonly. .. c:member:: void* uv_handle_t.data diff --git a/deps/uv/docs/src/index.rst b/deps/uv/docs/src/index.rst index fa89c4bffe580c..5ec2beb511cb00 100644 --- a/deps/uv/docs/src/index.rst +++ b/deps/uv/docs/src/index.rst @@ -1,6 +1,6 @@ -Welcome to the libuv API documentation -====================================== +Welcome to the libuv documentation +================================== Overview -------- @@ -37,59 +37,26 @@ Features * Threading and synchronization primitives -Downloads ---------- - -libuv can be downloaded from `here `_. - +Documentation +------------- -Installation ------------- +.. toctree:: + :maxdepth: 1 -Installation instructions can be found on `the README `_. + design + api + guide + upgrading -Upgrading +Downloads --------- -Migration guides for different libuv versions, starting with 1.0. - -.. toctree:: - :maxdepth: 1 - - migration_010_100 +libuv can be downloaded from `here `_. -Documentation -------------- +Installation +------------ -.. toctree:: - :maxdepth: 1 +Installation instructions can be found in `the README `_. - design - errors - version - loop - handle - request - timer - prepare - check - idle - async - poll - signal - process - stream - tcp - pipe - tty - udp - fs_event - fs_poll - fs - threadpool - dns - dll - threading - misc diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst index 1f504cb391f169..02543171de488b 100644 --- a/deps/uv/docs/src/loop.rst +++ b/deps/uv/docs/src/loop.rst @@ -38,9 +38,8 @@ Public members .. c:member:: void* uv_loop_t.data - Space for user-defined arbitrary data. libuv does not use this field. libuv does, however, - initialize it to NULL in :c:func:`uv_loop_init`, and it poisons the value (on debug builds) - on :c:func:`uv_loop_close`. + Space for user-defined arbitrary data. libuv does not use and does not + touch this field. API @@ -165,3 +164,57 @@ API .. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) Walk the list of handles: `walk_cb` will be executed with the given `arg`. + +.. c:function:: int uv_loop_fork(uv_loop_t* loop) + + .. versionadded:: 1.12.0 + + Reinitialize any kernel state necessary in the child process after + a :man:`fork(2)` system call. + + Previously started watchers will continue to be started in the + child process. + + It is necessary to explicitly call this function on every event + loop created in the parent process that you plan to continue to + use in the child, including the default loop (even if you don't + continue to use it in the parent). This function must be called + before calling :c:func:`uv_run` or any other API function using + the loop in the child. Failure to do so will result in undefined + behaviour, possibly including duplicate events delivered to both + parent and child or aborting the child process. + + When possible, it is preferred to create a new loop in the child + process instead of reusing a loop created in the parent. New loops + created in the child process after the fork should not use this + function. + + This function is not implemented on Windows, where it returns ``UV_ENOSYS``. + + .. caution:: + + This function is experimental. It may contain bugs, and is subject to + change or removal. API and ABI stability is not guaranteed. + + .. note:: + + On Mac OS X, if directory FS event handles were in use in the + parent process *for any event loop*, the child process will no + longer be able to use the most efficient FSEvent + implementation. Instead, uses of directory FS event handles in + the child will fall back to the same implementation used for + files and on other kqueue-based systems. + + .. caution:: + + On AIX and SunOS, FS event handles that were already started in + the parent process at the time of forking will *not* deliver + events in the child process; they must be closed and restarted. + On all other platforms, they will continue to work normally + without any further intervention. + + .. caution:: + + Any previous value returned from :c:func`uv_backend_fd` is now + invalid. That function must be called again to determine the + correct backend file descriptor. diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 71934694623d9b..9d7c3617e864bb 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -270,12 +270,20 @@ API .. c:function:: int uv_cwd(char* buffer, size_t* size) - Gets the current working directory. + Gets the current working directory, and stores it in `buffer`. If the + current working directory is too large to fit in `buffer`, this function + returns `UV_ENOBUFS`, and sets `size` to the required length, including the + null terminator. .. versionchanged:: 1.1.0 On Unix the path no longer ends in a slash. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + .. c:function:: int uv_chdir(const char* dir) Changes the current working directory. @@ -386,3 +394,49 @@ API stability guarantees. .. versionadded:: 1.8.0 + +.. c:function:: int uv_os_getenv(const char* name, char* buffer, size_t* size) + + Retrieves the environment variable specified by `name`, copies its value + into `buffer`, and sets `size` to the string length of the value. When + calling this function, `size` must be set to the amount of storage available + in `buffer`, including the null terminator. If the environment variable + exceeds the storage available in `buffer`, `UV_ENOBUFS` is returned, and + `size` is set to the amount of storage required to hold the value. If no + matching environment variable exists, `UV_ENOENT` is returned. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_setenv(const char* name, const char* value) + + Creates or updates the environment variable specified by `name` with + `value`. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_unsetenv(const char* name) + + Deletes the environment variable specified by `name`. If no such environment + variable exists, this function returns successfully. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_gethostname(char* buffer, size_t* size) + + Returns the hostname as a null-terminated string in `buffer`, and sets + `size` to the string length of the hostname. When calling this function, + `size` must be set to the amount of storage available in `buffer`, including + the null terminator. If the hostname exceeds the storage available in + `buffer`, `UV_ENOBUFS` is returned, and `size` is set to the amount of + storage required to hold the value. + + .. versionadded:: 1.12.0 diff --git a/deps/uv/docs/src/signal.rst b/deps/uv/docs/src/signal.rst index dc1223b90ac5e2..5b3b352bdd257d 100644 --- a/deps/uv/docs/src/signal.rst +++ b/deps/uv/docs/src/signal.rst @@ -70,6 +70,13 @@ API Start the handle with the given callback, watching for the given signal. +.. c:function:: int uv_signal_start_oneshot(uv_signal_t* signal, uv_signal_cb cb, int signum) + + .. versionadded:: 1.12.0 + + Same functionality as :c:func:`uv_signal_start` but the signal handler is reset the moment + the signal is received. + .. c:function:: int uv_signal_stop(uv_signal_t* signal) Stop the handle, the callback will no longer be called. diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst index 18949507e75004..93bd236d35e9f5 100644 --- a/deps/uv/docs/src/threadpool.rst +++ b/deps/uv/docs/src/threadpool.rst @@ -5,7 +5,7 @@ Thread pool work scheduling =========================== libuv provides a threadpool which can be used to run user code and get notified -in the loop thread. This thread pool is internally used to run all filesystem +in the loop thread. This thread pool is internally used to run all file system operations, as well as getaddrinfo and getnameinfo requests. Its default size is 4, but it can be changed at startup time by setting the diff --git a/deps/uv/docs/src/upgrading.rst b/deps/uv/docs/src/upgrading.rst new file mode 100644 index 00000000000000..32840c2696a12e --- /dev/null +++ b/deps/uv/docs/src/upgrading.rst @@ -0,0 +1,11 @@ +.. _upgrading: + +Upgrading +========= + +Migration guides for different libuv versions, starting with 1.0. + +.. toctree:: + :maxdepth: 1 + + migration_010_100 diff --git a/deps/uv/include/uv-posix.h b/deps/uv/include/uv-posix.h new file mode 100644 index 00000000000000..9a96634db0e3a5 --- /dev/null +++ b/deps/uv/include/uv-posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h index 3030f719a27148..d7754509b1e27b 100644 --- a/deps/uv/include/uv-unix.h +++ b/deps/uv/include/uv-unix.h @@ -60,6 +60,8 @@ defined(__OpenBSD__) || \ defined(__NetBSD__) # include "uv-bsd.h" +#elif defined(__CYGWIN__) || defined(__MSYS__) +# include "uv-posix.h" #endif #ifndef PTHREAD_BARRIER_SERIAL_THREAD @@ -79,7 +81,6 @@ #endif struct uv__io_s; -struct uv__async; struct uv_loop_s; typedef void (*uv__io_cb)(struct uv_loop_s* loop, @@ -97,16 +98,6 @@ struct uv__io_s { UV_IO_PRIVATE_PLATFORM_FIELDS }; -typedef void (*uv__async_cb)(struct uv_loop_s* loop, - struct uv__async* w, - unsigned int nevents); - -struct uv__async { - uv__async_cb cb; - uv__io_t io_watcher; - int wfd; -}; - #ifndef UV_PLATFORM_SEM_T # define UV_PLATFORM_SEM_T sem_t #endif @@ -216,7 +207,9 @@ typedef struct { void* check_handles[2]; \ void* idle_handles[2]; \ void* async_handles[2]; \ - struct uv__async async_watcher; \ + void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ + uv__io_t async_io_watcher; \ + int async_wfd; \ struct { \ void* min; \ unsigned int nelts; \ diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index cf000487909477..34d4a43f9e5f22 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 11 +#define UV_VERSION_MINOR 12 #define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 31f09f0f6af34a..f076094ccdc24c 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -274,6 +274,7 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*); UV_EXTERN size_t uv_loop_size(void); UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); UV_EXTERN void uv_stop(uv_loop_t*); @@ -1033,6 +1034,7 @@ UV_EXTERN int uv_get_process_title(char* buffer, size_t size); UV_EXTERN int uv_set_process_title(const char* title); UV_EXTERN int uv_resident_set_memory(size_t* rss); UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); typedef struct { long tv_sec; @@ -1073,6 +1075,12 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + typedef enum { UV_FS_UNKNOWN = -1, @@ -1324,6 +1332,9 @@ UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); UV_EXTERN int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); UV_EXTERN int uv_signal_stop(uv_signal_t* handle); UV_EXTERN void uv_loadavg(double avg[3]); diff --git a/deps/uv/samples/socks5-proxy/client.c b/deps/uv/samples/socks5-proxy/client.c index ae9913a1c6e125..aa2a91c9a12e9f 100644 --- a/deps/uv/samples/socks5-proxy/client.c +++ b/deps/uv/samples/socks5-proxy/client.c @@ -95,7 +95,7 @@ static int do_kill(client_ctx *cx); static int do_almost_dead(client_ctx *cx); static int conn_cycle(const char *who, conn *a, conn *b); static void conn_timer_reset(conn *c); -static void conn_timer_expire(uv_timer_t *handle, int status); +static void conn_timer_expire(uv_timer_t *handle); static void conn_getaddrinfo(conn *c, const char *hostname); static void conn_getaddrinfo_done(uv_getaddrinfo_t *req, int status, @@ -582,10 +582,9 @@ static void conn_timer_reset(conn *c) { 0)); } -static void conn_timer_expire(uv_timer_t *handle, int status) { +static void conn_timer_expire(uv_timer_t *handle) { conn *c; - CHECK(0 == status); c = CONTAINER_OF(handle, conn, timer_handle); c->result = UV_ETIMEDOUT; do_next(c->client); diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 2c5152b4200875..108934112c582a 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -23,18 +23,6 @@ #if !defined(_WIN32) # include "unix/internal.h" -#else -# include "win/req-inl.h" -/* TODO(saghul): unify internal req functions */ -static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type) { - uv_req_init(loop, req); - req->type = type; - uv__req_register(loop, req); -} -# define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) #endif #include @@ -139,7 +127,7 @@ UV_DESTRUCTOR(static void cleanup(void)) { #endif -static void init_once(void) { +static void init_threads(void) { unsigned int i; const char* val; @@ -177,6 +165,27 @@ static void init_once(void) { } +#ifndef _WIN32 +static void reset_once(void) { + uv_once_t child_once = UV_ONCE_INIT; + memcpy(&once, &child_once, sizeof(child_once)); +} +#endif + + +static void init_once(void) { +#ifndef _WIN32 + /* Re-initialize the threadpool after fork. + * Note that this discards the global mutex and condition as well + * as the work queue. + */ + if (pthread_atfork(NULL, NULL, &reset_once)) + abort(); +#endif + init_threads(); +} + + void uv__work_submit(uv_loop_t* loop, struct uv__work* w, void (*work)(struct uv__work* w), diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 1d2cd4a80e97f6..388c9cca9707ee 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -96,6 +96,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct poll_ctl pc; diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c index 393cdebd4ea3fc..45c088ea1b39bc 100644 --- a/deps/uv/src/unix/async.c +++ b/deps/uv/src/unix/async.c @@ -33,16 +33,15 @@ #include #include -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents); +static void uv__async_send(uv_loop_t* loop); +static int uv__async_start(uv_loop_t* loop); static int uv__async_eventfd(void); int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; - err = uv__async_start(loop, &loop->async_watcher, uv__async_event); + err = uv__async_start(loop); if (err) return err; @@ -63,7 +62,7 @@ int uv_async_send(uv_async_t* handle) { return 0; if (cmpxchgi(&handle->pending, 0, 1) == 0) - uv__async_send(&handle->loop->async_watcher); + uv__async_send(handle->loop); return 0; } @@ -75,44 +74,18 @@ void uv__async_close(uv_async_t* handle) { } -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents) { +static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + char buf[1024]; + ssize_t r; QUEUE queue; QUEUE* q; uv_async_t* h; - QUEUE_MOVE(&loop->async_handles, &queue); - while (!QUEUE_EMPTY(&queue)) { - q = QUEUE_HEAD(&queue); - h = QUEUE_DATA(q, uv_async_t, queue); - - QUEUE_REMOVE(q); - QUEUE_INSERT_TAIL(&loop->async_handles, q); - - if (cmpxchgi(&h->pending, 1, 0) == 0) - continue; - - if (h->async_cb == NULL) - continue; - h->async_cb(h); - } -} - + assert(w == &loop->async_io_watcher); -static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - struct uv__async* wa; - char buf[1024]; - unsigned n; - ssize_t r; - - n = 0; for (;;) { r = read(w->fd, buf, sizeof(buf)); - if (r > 0) - n += r; - if (r == sizeof(buf)) continue; @@ -128,23 +101,26 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { abort(); } - wa = container_of(w, struct uv__async, io_watcher); + QUEUE_MOVE(&loop->async_handles, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_async_t, queue); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&loop->async_handles, q); -#if defined(__linux__) - if (wa->wfd == -1) { - uint64_t val; - assert(n == sizeof(val)); - memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */ - wa->cb(loop, wa, val); - return; - } -#endif + if (cmpxchgi(&h->pending, 1, 0) == 0) + continue; + + if (h->async_cb == NULL) + continue; - wa->cb(loop, wa, n); + h->async_cb(h); + } } -void uv__async_send(struct uv__async* wa) { +static void uv__async_send(uv_loop_t* loop) { const void* buf; ssize_t len; int fd; @@ -152,14 +128,14 @@ void uv__async_send(struct uv__async* wa) { buf = ""; len = 1; - fd = wa->wfd; + fd = loop->async_wfd; #if defined(__linux__) if (fd == -1) { static const uint64_t val = 1; buf = &val; len = sizeof(val); - fd = wa->io_watcher.fd; /* eventfd */ + fd = loop->async_io_watcher.fd; /* eventfd */ } #endif @@ -178,17 +154,11 @@ void uv__async_send(struct uv__async* wa) { } -void uv__async_init(struct uv__async* wa) { - wa->io_watcher.fd = -1; - wa->wfd = -1; -} - - -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { +static int uv__async_start(uv_loop_t* loop) { int pipefd[2]; int err; - if (wa->io_watcher.fd != -1) + if (loop->async_io_watcher.fd != -1) return 0; err = uv__async_eventfd(); @@ -222,32 +192,41 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { if (err < 0) return err; - uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]); - uv__io_start(loop, &wa->io_watcher, POLLIN); - wa->wfd = pipefd[1]; - wa->cb = cb; + uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]); + uv__io_start(loop, &loop->async_io_watcher, POLLIN); + loop->async_wfd = pipefd[1]; return 0; } -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) { - if (wa->io_watcher.fd == -1) +int uv__async_fork(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) /* never started */ + return 0; + + uv__async_stop(loop); + + return uv__async_start(loop); +} + + +void uv__async_stop(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) return; - if (wa->wfd != -1) { - if (wa->wfd != wa->io_watcher.fd) - uv__close(wa->wfd); - wa->wfd = -1; + if (loop->async_wfd != -1) { + if (loop->async_wfd != loop->async_io_watcher.fd) + uv__close(loop->async_wfd); + loop->async_wfd = -1; } - uv__io_stop(loop, &wa->io_watcher, POLLIN); - uv__close(wa->io_watcher.fd); - wa->io_watcher.fd = -1; + uv__io_stop(loop, &loop->async_io_watcher, POLLIN); + uv__close(loop->async_io_watcher.fd); + loop->async_io_watcher.fd = -1; } -static int uv__async_eventfd() { +static int uv__async_eventfd(void) { #if defined(__linux__) static int no_eventfd2; static int no_eventfd; diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c new file mode 100644 index 00000000000000..414789451ab3d6 --- /dev/null +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -0,0 +1,139 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#include +#include +#if !defined(__CYGWIN__) && !defined(__MSYS__) +#include +#endif + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) + /* + * On BSD getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information. + */ + if (ent->ifa_addr->sa_family == AF_LINK) + return 1; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + if (ent->ifa_addr->sa_family != PF_INET) + return 1; +#endif + return 0; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + struct ifaddrs* addrs; + struct ifaddrs* ent; + uv_interface_address_t* address; + int i; + + if (getifaddrs(&addrs) != 0) + return -errno; + + *count = 0; + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + (*count)++; + } + + *addresses = uv__malloc(*count * sizeof(**addresses)); + + if (*addresses == NULL) { + freeifaddrs(addrs); + return -ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); + + address++; + } + + /* Fill in physical addresses for each interface */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address = *addresses; + + for (i = 0; i < *count; i++) { + if (strcmp(address->name, ent->ifa_name) == 0) { +#if defined(__CYGWIN__) || defined(__MSYS__) + memset(address->phys_addr, 0, sizeof(address->phys_addr)); +#else + struct sockaddr_dl* sa_addr; + sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); +#endif + } + address++; + } + } + + freeifaddrs(addrs); + + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 1ec549cccb5cfe..8276c604132995 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -28,6 +28,7 @@ #include #include #include +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ #include #include #include @@ -42,6 +43,7 @@ #include #ifdef __sun +# include /* MAXHOSTNAMELEN on Solaris */ # include # include # include @@ -80,6 +82,11 @@ #include #endif +/* Fallback for the maximum hostname length */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ @@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) { } +#if !defined(__CYGWIN__) && !defined(__MSYS__) int uv__cloexec_ioctl(int fd, int set) { int r; @@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) { return 0; } +#endif int uv__nonblock_fcntl(int fd, int set) { @@ -839,13 +848,8 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { * every tick of the event loop but the other backends allow us to * short-circuit here if the event mask is unchanged. */ - if (w->events == w->pevents) { - if (w->events == 0 && !QUEUE_EMPTY(&w->watcher_queue)) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - } + if (w->events == w->pevents) return; - } #endif if (QUEUE_EMPTY(&w->watcher_queue)) @@ -1245,3 +1249,83 @@ int uv_translate_sys_error(int sys_errno) { /* If < 0 then it's already a libuv error. */ return sys_errno <= 0 ? sys_errno : -sys_errno; } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + char* var; + size_t len; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + var = getenv(name); + + if (var == NULL) + return -ENOENT; + + len = strlen(var); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, var, len + 1); + *size = len; + + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + if (name == NULL || value == NULL) + return -EINVAL; + + if (setenv(name, value, 1) != 0) + return -errno; + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + if (unsetenv(name) != 0) + return -errno; + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + /* + On some platforms, if the input buffer is not large enough, gethostname() + succeeds, but truncates the result. libuv can detect this and return ENOBUFS + instead by creating a large enough buffer and comparing the hostname length + to the size input. + */ + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + if (gethostname(buf, sizeof(buf)) != 0) + return -errno; + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return fd; +} diff --git a/deps/uv/src/unix/cygwin.c b/deps/uv/src/unix/cygwin.c new file mode 100644 index 00000000000000..5a887dd4c2d03e --- /dev/null +++ b/deps/uv/src/unix/cygwin.c @@ -0,0 +1,54 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_uptime(double* uptime) { + struct sysinfo info; + + if (sysinfo(&info) < 0) + return -errno; + + *uptime = info.uptime; + return 0; +} + +int uv_resident_set_memory(size_t* rss) { + /* FIXME: read /proc/meminfo? */ + *rss = 0; + return UV_ENOSYS; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + /* FIXME: read /proc/stat? */ + *cpu_infos = NULL; + *count = 0; + return UV_ENOSYS; +} + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + (void)cpu_infos; + (void)count; +} diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index cf95da21693b9a..df6dd1c61bbc24 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -25,10 +25,6 @@ #include #include -#include -#include -#include - #include #include #include /* _NSGetExecutablePath */ @@ -233,103 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Mac OS X getifaddrs returns information related to Mac Addresses for - * various devices, such as firewire, etc. These are not relevant here. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index cba44a3e0b078e..e52ae99dbe9030 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -25,10 +25,6 @@ #include #include -#include -#include -#include - #include #include #include @@ -41,9 +37,6 @@ #include /* sysconf */ #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - #ifndef CPUSTATES # define CPUSTATES 5U #endif @@ -67,13 +60,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - #ifdef __DragonFly__ int uv_exepath(char* buffer, size_t* size) { char abspath[PATH_MAX * 2 + 1]; @@ -358,103 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On FreeBSD getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index d331a13172675e..643e233cfe9e94 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) { if (state->fsevent_stream == NULL) return; - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - /* Stop emitting events */ pFSEventStreamStop(state->fsevent_stream); diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 1188e8fe70998a..2e3afa6c856827 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -162,7 +162,8 @@ struct uv__stream_queued_fds_s { defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || \ - defined(__linux__) + defined(__linux__) || \ + defined(__OpenBSD__) #define uv__cloexec uv__cloexec_ioctl #define uv__nonblock uv__nonblock_ioctl #else @@ -191,12 +192,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w); int uv__io_active(const uv__io_t* w, unsigned int events); int uv__io_check_fd(uv_loop_t* loop, int fd); void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ +int uv__io_fork(uv_loop_t* loop); /* async */ -void uv__async_send(struct uv__async* wa); -void uv__async_init(struct uv__async* wa); -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb); -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa); +void uv__async_stop(uv_loop_t* loop); +int uv__async_fork(uv_loop_t* loop); + /* loop */ void uv__run_idle(uv_loop_t* loop); @@ -232,6 +233,7 @@ int uv__next_timeout(const uv_loop_t* loop); void uv__signal_close(uv_signal_t* handle); void uv__signal_global_once_init(void); void uv__signal_loop_cleanup(uv_loop_t* loop); +int uv__signal_loop_fork(uv_loop_t* loop); /* platform specific */ uint64_t uv__hrtime(uv_clocktype_t type); @@ -301,15 +303,6 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000; #endif /* defined(__APPLE__) */ -UV_UNUSED(static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type)) { - req->type = type; - uv__req_register(loop, req); -} -#define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) - UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { /* Use a fast time source if available. We only need millisecond precision. */ @@ -326,4 +319,8 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) { return s + 1; } +#if defined(__linux__) +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers); +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index fffd4626f17579..6bc60bbe46885e 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -48,6 +48,37 @@ int uv__kqueue_init(uv_loop_t* loop) { } +static int uv__has_forked_with_cfrunloop; + +int uv__io_fork(uv_loop_t* loop) { + int err; + uv__close(loop->backend_fd); + loop->backend_fd = -1; + err = uv__kqueue_init(loop); + if (err) + return err; + +#if defined(__APPLE__) + if (loop->cf_state != NULL) { + /* We cannot start another CFRunloop and/or thread in the child + process; CF aborts if you try or if you try to touch the thread + at all to kill it. So the best we can do is ignore it from now + on. This means we can't watch directories in the same way + anymore (like other BSDs). It also means we cannot properly + clean up the allocated resources; calling + uv__fsevents_loop_delete from uv_loop_close will crash the + process. So we sidestep the issue by pretending like we never + started it in the first place. + */ + uv__has_forked_with_cfrunloop = 1; + uv__free(loop->cf_state); + loop->cf_state = NULL; + } +#endif + return err; +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct kevent ev; int rc; @@ -404,6 +435,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->cb = cb; #if defined(__APPLE__) + if (uv__has_forked_with_cfrunloop) + goto fallback; + /* Nullify field to perform checks later */ handle->cf_cb = NULL; handle->realpath = NULL; @@ -438,7 +472,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); #if defined(__APPLE__) - if (uv__fsevents_close(handle)) + if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle)) #endif /* defined(__APPLE__) */ { uv__io_close(handle->loop, &handle->event_watcher); diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 58dd813ddf132c..2866e938545cb3 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -107,6 +107,24 @@ int uv__platform_loop_init(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + int err; + void* old_watchers; + + old_watchers = loop->inotify_watchers; + + uv__close(loop->backend_fd); + loop->backend_fd = -1; + uv__platform_loop_delete(loop); + + err = uv__platform_loop_init(loop); + if (err) + return err; + + return uv__inotify_fork(loop, old_watchers); +} + + void uv__platform_loop_delete(uv_loop_t* loop) { if (loop->inotify_fd == -1) return; uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN); @@ -454,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) { } -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - n = *size - 1; - if (n > 0) - n = readlink("/proc/self/exe", buffer, n); - - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.freeram * info.mem_unit; - return 0; -} - - -uint64_t uv_get_total_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.totalram * info.mem_unit; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { char buf[1024]; const char* s; @@ -868,6 +837,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + /* + * On Linux getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information yet. + */ + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { @@ -887,11 +869,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } (*count)++; } @@ -908,17 +887,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Linux getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == PF_PACKET) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); @@ -942,11 +911,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } address = *addresses; diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c index 4708c051d3b540..5934c5d8cb060e 100644 --- a/deps/uv/src/unix/linux-inotify.c +++ b/deps/uv/src/unix/linux-inotify.c @@ -61,6 +61,8 @@ static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, unsigned int revents); +static void maybe_free_watcher_list(struct watcher_list* w, + uv_loop_t* loop); static int new_inotify_fd(void) { int err; @@ -108,6 +110,71 @@ static int init_inotify(uv_loop_t* loop) { } +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) { + /* Open the inotify_fd, and re-arm all the inotify watchers. */ + int err; + struct watcher_list* tmp_watcher_list_iter; + struct watcher_list* watcher_list; + struct watcher_list tmp_watcher_list; + QUEUE queue; + QUEUE* q; + uv_fs_event_t* handle; + char* tmp_path; + + if (old_watchers != NULL) { + /* We must restore the old watcher list to be able to close items + * out of it. + */ + loop->inotify_watchers = old_watchers; + + QUEUE_INIT(&tmp_watcher_list.watchers); + /* Note that the queue we use is shared with the start and stop() + * functions, making QUEUE_FOREACH unsafe to use. So we use the + * QUEUE_MOVE trick to safely iterate. Also don't free the watcher + * list until we're done iterating. c.f. uv__inotify_read. + */ + RB_FOREACH_SAFE(watcher_list, watcher_root, + CAST(&old_watchers), tmp_watcher_list_iter) { + watcher_list->iterating = 1; + QUEUE_MOVE(&watcher_list->watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + /* It's critical to keep a copy of path here, because it + * will be set to NULL by stop() and then deallocated by + * maybe_free_watcher_list + */ + tmp_path = uv__strdup(handle->path); + assert(tmp_path != NULL); + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&watcher_list->watchers, q); + uv_fs_event_stop(handle); + + QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers); + handle->path = tmp_path; + } + watcher_list->iterating = 0; + maybe_free_watcher_list(watcher_list, loop); + } + + QUEUE_MOVE(&tmp_watcher_list.watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + QUEUE_REMOVE(q); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + tmp_path = handle->path; + handle->path = NULL; + err = uv_fs_event_start(handle, handle->cb, tmp_path, 0); + uv__free(tmp_path); + if (err) + return err; + } + } + + return 0; +} + + static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { struct watcher_list w; w.wd = wd; diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index bd63c2f9d1d24a..bcd49242cea2bc 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -54,7 +54,8 @@ int uv_loop_init(uv_loop_t* loop) { loop->closing_handles = NULL; uv__update_time(loop); - uv__async_init(&loop->async_watcher); + loop->async_io_watcher.fd = -1; + loop->async_wfd = -1; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; @@ -108,10 +109,43 @@ int uv_loop_init(uv_loop_t* loop) { } +int uv_loop_fork(uv_loop_t* loop) { + int err; + unsigned int i; + uv__io_t* w; + + err = uv__io_fork(loop); + if (err) + return err; + + err = uv__async_fork(loop); + if (err) + return err; + + err = uv__signal_loop_fork(loop); + if (err) + return err; + + /* Rearm all the watchers that aren't re-queued by the above. */ + for (i = 0; i < loop->nwatchers; i++) { + w = loop->watchers[i]; + if (w == NULL) + continue; + + if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) { + w->events = 0; /* Force re-registration in uv__io_poll. */ + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + } + } + + return 0; +} + + void uv__loop_close(uv_loop_t* loop) { uv__signal_loop_cleanup(loop); uv__platform_loop_delete(loop); - uv__async_stop(loop, &loop->async_watcher); + uv__async_stop(loop); if (loop->emfile_fd != -1) { uv__close(loop->emfile_fd); diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 4a9e6cbc17c783..9b5546b7e6959b 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -27,14 +27,11 @@ #include #include -#include #include #include #include #include -#include -#include #include #include #include @@ -43,9 +40,6 @@ #include #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -58,13 +52,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -283,98 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/no-fsevents.c b/deps/uv/src/unix/no-fsevents.c new file mode 100644 index 00000000000000..38fb6ab0bb2c16 --- /dev/null +++ b/deps/uv/src/unix/no-fsevents.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return -ENOSYS; +} + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + return -ENOSYS; +} + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return -ENOSYS; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} diff --git a/deps/uv/src/unix/no-proctitle.c b/deps/uv/src/unix/no-proctitle.c new file mode 100644 index 00000000000000..a5c19fbff58d38 --- /dev/null +++ b/deps/uv/src/unix/no-proctitle.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return -EINVAL; + + buffer[0] = '\0'; + return 0; +} diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 909288cc888893..56f0af15c3ef3f 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -28,21 +28,13 @@ #include #include -#include -#include -#include - #include #include -#include #include #include #include #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -56,13 +48,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -163,7 +148,7 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { uv__free(process_title); process_title = uv__strdup(title); - setproctitle(title); + setproctitle("%s", title); return 0; } @@ -297,100 +282,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs) != 0) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 2bf3b73815a5f4..7edf2358d43a49 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -120,7 +120,7 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { } -static void epoll_init() { +static void epoll_init(void) { QUEUE_INIT(&global_epoll_queue); if (uv_mutex_init(&global_epoll_lock)) abort(); diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index be325a923091f2..2ba5abf35490d7 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { return 0; } - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, - const char* filename, unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - void uv__io_poll(uv_loop_t* loop, int timeout) { static const int max_safe_timeout = 1789569; struct epoll_event events[1024]; @@ -863,3 +841,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { void uv__set_process_title(const char* title) { /* do nothing */ } + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index b73994cb8de365..4a812955b0d1de 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -47,7 +47,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { int err; pipe_fname = NULL; - sockfd = -1; /* Already bound? */ if (uv__stream_fd(handle) >= 0) @@ -76,7 +75,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { /* Convert ENOENT to EACCES for compatibility with Windows. */ if (err == -ENOENT) err = -EACCES; - goto err_bind; + + uv__close(sockfd); + goto err_socket; } /* Success. */ @@ -85,9 +86,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { handle->io_watcher.fd = sockfd; return 0; -err_bind: - uv__close(sockfd); - err_socket: uv__free((void*)pipe_fname); return err; @@ -183,6 +181,14 @@ void uv_pipe_connect(uv_connect_t* req, if (r == -1 && errno != EINPROGRESS) { err = -errno; +#if defined(__CYGWIN__) || defined(__MSYS__) + /* EBADF is supposed to mean that the socket fd is bad, but + Cygwin reports EBADF instead of ENOTSOCK when the file is + not a socket. We do not expect to see a bad fd here + (e.g. due to new_sock), so translate the error. */ + if (err == -EBADF) + err = -ENOTSOCK; +#endif goto out; } diff --git a/deps/uv/src/unix/posix-hrtime.c b/deps/uv/src/unix/posix-hrtime.c new file mode 100644 index 00000000000000..323dfc20392423 --- /dev/null +++ b/deps/uv/src/unix/posix-hrtime.c @@ -0,0 +1,35 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +uint64_t uv__hrtime(uv_clocktype_t type) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); +} diff --git a/deps/uv/src/unix/posix-poll.c b/deps/uv/src/unix/posix-poll.c new file mode 100644 index 00000000000000..3fba96e1bf154d --- /dev/null +++ b/deps/uv/src/unix/posix-poll.c @@ -0,0 +1,324 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +/* POSIX defines poll() as a portable way to wait on file descriptors. + * Here we maintain a dynamically sized array of file descriptors and + * events to pass as the first argument to poll(). + */ + +#include +#include +#include +#include +#include + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->poll_fds = NULL; + loop->poll_fds_used = 0; + loop->poll_fds_size = 0; + loop->poll_fds_iterating = 0; + return 0; +} + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__free(loop->poll_fds); + loop->poll_fds = NULL; +} + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + +/* Allocate or dynamically resize our poll fds array. */ +static void uv__pollfds_maybe_resize(uv_loop_t* loop) { + size_t i; + size_t n; + struct pollfd* p; + + if (loop->poll_fds_used < loop->poll_fds_size) + return; + + n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64; + p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds)); + if (p == NULL) + abort(); + + loop->poll_fds = p; + for (i = loop->poll_fds_size; i < n; i++) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + loop->poll_fds_size = n; +} + +/* Primitive swap operation on poll fds array elements. */ +static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) { + struct pollfd pfd; + pfd = loop->poll_fds[l]; + loop->poll_fds[l] = loop->poll_fds[r]; + loop->poll_fds[r] = pfd; +} + +/* Add a watcher's fd to our poll fds array with its pending events. */ +static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { + size_t i; + struct pollfd* pe; + + /* If the fd is already in the set just update its events. */ + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == w->fd) { + loop->poll_fds[i].events = w->pevents; + return; + } + } + + /* Otherwise, allocate a new slot in the set for the fd. */ + uv__pollfds_maybe_resize(loop); + pe = &loop->poll_fds[loop->poll_fds_used++]; + pe->fd = w->fd; + pe->events = w->pevents; +} + +/* Remove a watcher's fd from our poll fds array. */ +static void uv__pollfds_del(uv_loop_t* loop, int fd) { + size_t i; + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == fd) { + /* swap to last position and remove */ + --loop->poll_fds_used; + uv__pollfds_swap(loop, i, loop->poll_fds_used); + loop->poll_fds[loop->poll_fds_used].fd = -1; + loop->poll_fds[loop->poll_fds_used].events = 0; + loop->poll_fds[loop->poll_fds_used].revents = 0; + return; + } + } +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + sigset_t* pset; + sigset_t set; + uint64_t time_base; + uint64_t time_diff; + QUEUE* q; + uv__io_t* w; + size_t i; + unsigned int nevents; + int nfds; + int have_signals; + struct pollfd* pe; + int fd; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + /* Take queued watchers and add their fds to our poll fds array. */ + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + uv__pollfds_add(loop, w); + + w->events = w->pevents; + } + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + time_base = loop->time; + + /* Loop calls to poll() and processing of results. If we get some + * results from poll() but they turn out not to be interesting to + * our caller then we need to loop around and poll() again. + */ + for (;;) { + if (pset != NULL) + if (pthread_sigmask(SIG_BLOCK, pset, NULL)) + abort(); + nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout); + if (pset != NULL) + if (pthread_sigmask(SIG_UNBLOCK, pset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + /* Tell uv__platform_invalidate_fd not to manipulate our array + * while we are iterating over it. + */ + loop->poll_fds_iterating = 1; + + /* Initialize a count of events that we care about. */ + nevents = 0; + have_signals = 0; + + /* Loop over the entire poll fds array looking for returned events. */ + for (i = 0; i < loop->poll_fds_used; i++) { + pe = loop->poll_fds + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd. */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, ignore. */ + uv__platform_invalidate_fd(loop, fd); + continue; + } + + /* Filter out events that user has not requested us to watch + * (e.g. POLLNVAL). + */ + pe->revents &= w->pevents | POLLERR | POLLHUP; + + if (pe->revents != 0) { + /* Run signal watchers last. */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + w->cb(loop, w, pe->revents); + } + + nevents++; + } + } + + if (have_signals != 0) + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + + loop->poll_fds_iterating = 0; + + /* Purge invalidated fds from our poll fds array. */ + uv__pollfds_del(loop, -1); + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) + return; + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + time_diff = loop->time - time_base; + if (time_diff >= (uint64_t) timeout) + return; + + timeout -= time_diff; + } +} + +/* Remove the given fd from our poll fds array because no one + * is interested in its events anymore. + */ +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + size_t i; + + if (loop->poll_fds_iterating) { + /* uv__io_poll is currently iterating. Just invalidate fd. */ + for (i = 0; i < loop->poll_fds_used; i++) + if (loop->poll_fds[i].fd == fd) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + } else { + /* uv__io_poll is not iterating. Delete fd from the set. */ + uv__pollfds_del(loop, fd); + } +} + +/* Check whether the given fd is supported by poll(). */ +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rv == -1) + return -errno; + + if (p[0].revents & POLLNVAL) + return -EINVAL; + + return 0; +} diff --git a/deps/uv/src/unix/procfs-exepath.c b/deps/uv/src/unix/procfs-exepath.c new file mode 100644 index 00000000000000..5fdb6115505661 --- /dev/null +++ b/deps/uv/src/unix/procfs-exepath.c @@ -0,0 +1,45 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_exepath(char* buffer, size_t* size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return -errno; + + buffer[n] = '\0'; + *size = n; + + return 0; +} diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c index dbd8f86448d78c..cb09ead50a4c45 100644 --- a/deps/uv/src/unix/signal.c +++ b/deps/uv/src/unix/signal.c @@ -38,9 +38,14 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s); static int uv__signal_unlock(void); +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); static void uv__signal_stop(uv_signal_t* handle); +static void uv__signal_unregister_handler(int signum); static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; @@ -53,8 +58,19 @@ RB_GENERATE_STATIC(uv__signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare) +static void uv__signal_global_reinit(void); static void uv__signal_global_init(void) { + if (!uv__signal_lock_pipefd[0]) + /* pthread_atfork can register before and after handlers, one + * for each child. This only registers one for the child. That + * state is both persistent and cumulative, so if we keep doing + * it the handler functions will be called multiple times. Thus + * we only want to do it once. + */ + if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) + abort(); + if (uv__make_pipe(uv__signal_lock_pipefd, 0)) abort(); @@ -63,6 +79,22 @@ static void uv__signal_global_init(void) { } +static void uv__signal_global_reinit(void) { + /* We can only use signal-safe functions here. + * That includes read/write and close, fortunately. + * We do all of this directly here instead of resetting + * uv__signal_global_init_guard because + * uv__signal_global_once_init is only called from uv_loop_init + * and this needs to function in existing loops. + */ + uv__close(uv__signal_lock_pipefd[0]); + uv__signal_lock_pipefd[0] = -1; + uv__close(uv__signal_lock_pipefd[1]); + uv__signal_lock_pipefd[1] = -1; + uv__signal_global_init(); +} + + void uv__signal_global_once_init(void) { uv_once(&uv__signal_global_init_guard, uv__signal_global_init); } @@ -122,6 +154,7 @@ static uv_signal_t* uv__signal_first_handle(int signum) { uv_signal_t* handle; lookup.signum = signum; + lookup.flags = 0; lookup.loop = NULL; handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); @@ -174,7 +207,7 @@ static void uv__signal_handler(int signum) { } -static int uv__signal_register_handler(int signum) { +static int uv__signal_register_handler(int signum, int oneshot) { /* When this function is called, the signal lock must be held. */ struct sigaction sa; @@ -183,6 +216,7 @@ static int uv__signal_register_handler(int signum) { if (sigfillset(&sa.sa_mask)) abort(); sa.sa_handler = uv__signal_handler; + sa.sa_flags = oneshot ? SA_RESETHAND : 0; /* XXX save old action so we can restore it later on? */ if (sigaction(signum, &sa, NULL)) @@ -228,6 +262,16 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) { } +int uv__signal_loop_fork(uv_loop_t* loop) { + uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); + uv__close(loop->signal_pipefd[0]); + uv__close(loop->signal_pipefd[1]); + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; + return uv__signal_loop_once_init(loop); +} + + void uv__signal_loop_cleanup(uv_loop_t* loop) { QUEUE* q; @@ -287,8 +331,24 @@ void uv__signal_close(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { sigset_t saved_sigmask; int err; + uv_signal_t* first_handle; assert(!uv__is_closing(handle)); @@ -318,9 +378,12 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { /* If at this point there are no active signal watchers for this signum (in * any of the loops), it's time to try and register a handler for it here. + * Also in case there's only one-shot handlers and a regular handler comes in. */ - if (uv__signal_first_handle(signum) == NULL) { - err = uv__signal_register_handler(signum); + first_handle = uv__signal_first_handle(signum); + if (first_handle == NULL || + (!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) { + err = uv__signal_register_handler(signum, oneshot); if (err) { /* Registering the signal handler failed. Must be an invalid signal. */ uv__signal_unlock_and_unblock(&saved_sigmask); @@ -329,6 +392,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { } handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); uv__signal_unlock_and_unblock(&saved_sigmask); @@ -390,6 +456,9 @@ static void uv__signal_event(uv_loop_t* loop, handle->dispatched_signals++; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv__signal_stop(handle); + /* If uv_close was called while there were caught signals that were not * yet dispatched, the uv__finish_close was deferred. Make close pending * now if this has happened. @@ -414,12 +483,22 @@ static void uv__signal_event(uv_loop_t* loop, static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + int f1; + int f2; /* Compare signums first so all watchers with the same signnum end up * adjacent. */ if (w1->signum < w2->signum) return -1; if (w1->signum > w2->signum) return 1; + /* Handlers without UV__SIGNAL_ONE_SHOT set will come first, so if the first + * handler returned is a one-shot handler, the rest will be too. + */ + f1 = w1->flags & UV__SIGNAL_ONE_SHOT; + f2 = w2->flags & UV__SIGNAL_ONE_SHOT; + if (f1 < f2) return -1; + if (f1 > f2) return 1; + /* Sort by loop pointer, so we can easily look up the first item after * { .signum = x, .loop = NULL }. */ @@ -443,6 +522,10 @@ int uv_signal_stop(uv_signal_t* handle) { static void uv__signal_stop(uv_signal_t* handle) { uv_signal_t* removed_handle; sigset_t saved_sigmask; + uv_signal_t* first_handle; + int rem_oneshot; + int first_oneshot; + int ret; /* If the watcher wasn't started, this is a no-op. */ if (handle->signum == 0) @@ -457,8 +540,17 @@ static void uv__signal_stop(uv_signal_t* handle) { /* Check if there are other active signal watchers observing this signal. If * not, unregister the signal handler. */ - if (uv__signal_first_handle(handle->signum) == NULL) + first_handle = uv__signal_first_handle(handle->signum); + if (first_handle == NULL) { uv__signal_unregister_handler(handle->signum); + } else { + rem_oneshot = handle->flags & UV__SIGNAL_ONE_SHOT; + first_oneshot = first_handle->flags & UV__SIGNAL_ONE_SHOT; + if (first_oneshot && !rem_oneshot) { + ret = uv__signal_register_handler(handle->signum, 1); + assert(ret == 0); + } + } uv__signal_unlock_and_unblock(&saved_sigmask); diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 7059df16a69a03..7b23d16ecf1407 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -390,7 +390,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { int uv__stream_open(uv_stream_t* stream, int fd, int flags) { -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) int enable; #endif @@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { return -errno; } -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) enable = 1; if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && errno != ENOTSOCK && @@ -785,7 +785,12 @@ static void uv__write(uv_stream_t* stream) { struct msghdr msg; struct cmsghdr *cmsg; int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - char scratch[64] = {0}; + union { + char data[64]; + struct cmsghdr alias; + } scratch; + + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -795,7 +800,7 @@ static void uv__write(uv_stream_t* stream) { msg.msg_iovlen = iovcnt; msg.msg_flags = 0; - msg.msg_control = (void*) scratch; + msg.msg_control = &scratch.alias; msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); cmsg = CMSG_FIRSTHDR(&msg); @@ -1168,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) { uv__stream_osx_interrupt_select(stream); } stream->read_cb(stream, 0, &buf); +#if defined(__CYGWIN__) || defined(__MSYS__) + } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { + uv__stream_eof(stream, &buf); + return; +#endif } else { /* Error. User should call uv_close(). */ stream->read_cb(stream, -errno, &buf); @@ -1400,6 +1410,12 @@ int uv_write2(uv_write_t* req, */ if (uv__handle_fd((uv_handle_t*) send_handle) < 0) return -EBADF; + +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it. + See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */ + return -ENOSYS; +#endif } /* It's legal for write_queue_size > 0 even when the write_queue is empty; diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index a43f7f1b1c021c..2dc02ae457cd06 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -99,6 +99,18 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { +#if defined(PORT_SOURCE_FILE) + if (loop->fs_fd != -1) { + /* stop the watcher before we blow away its fileno */ + uv__io_stop(loop, &loop->fs_event_watcher, POLLIN); + } +#endif + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + + void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { struct port_event* events; uintptr_t i; @@ -469,8 +481,10 @@ int uv_fs_event_start(uv_fs_event_t* handle, memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->path; err = uv__fs_event_rearm(handle); - if (err != 0) + if (err != 0) { + uv_fs_event_stop(handle); return err; + } if (first_run) { uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); @@ -531,25 +545,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) { #endif /* defined(PORT_SOURCE_FILE) */ -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (buffer == NULL || size == 0) - return -EINVAL; - - buffer[0] = '\0'; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { psinfo_t psinfo; int err; @@ -746,6 +741,17 @@ static int uv__set_phys_addr(uv_interface_address_t* address, return 0; } + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} + int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; struct ifaddrs* addrs; @@ -759,12 +765,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } - (*count)++; } @@ -777,10 +779,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); diff --git a/deps/uv/src/unix/sysinfo-loadavg.c b/deps/uv/src/unix/sysinfo-loadavg.c new file mode 100644 index 00000000000000..ebad0e89db597f --- /dev/null +++ b/deps/uv/src/unix/sysinfo-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/deps/uv/src/unix/sysinfo-memory.c b/deps/uv/src/unix/sysinfo-memory.c new file mode 100644 index 00000000000000..23b4fc6e914ae9 --- /dev/null +++ b/deps/uv/src/unix/sysinfo-memory.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.freeram * info.mem_unit; + return 0; +} + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.totalram * info.mem_unit; + return 0; +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 1cd49257865d0f..c556325de018b3 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle, if (flags & UV_UDP_REUSEADDR) { err = uv__set_reuse(fd); if (err) - goto out; + return err; } if (flags & UV_UDP_IPV6ONLY) { @@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle, yes = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { err = -errno; - goto out; + return err; } #else err = -ENOTSUP; - goto out; + return err; #endif } @@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle, /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a * socket created with AF_INET to an AF_INET6 address or vice versa. */ err = -EINVAL; - goto out; + return err; } if (addr->sa_family == AF_INET6) handle->flags |= UV_HANDLE_IPV6; handle->flags |= UV_HANDLE_BOUND; - return 0; - -out: - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - return err; } static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain, unsigned int flags) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; + union { + struct sockaddr_in6 in6; + struct sockaddr_in in; + struct sockaddr addr; + } taddr; socklen_t addrlen; if (handle->io_watcher.fd != -1) @@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, switch (domain) { case AF_INET: { - struct sockaddr_in* addr = (void*)&taddr; + struct sockaddr_in* addr = &taddr.in; memset(addr, 0, sizeof *addr); addr->sin_family = AF_INET; addr->sin_addr.s_addr = INADDR_ANY; @@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, } case AF_INET6: { - struct sockaddr_in6* addr = (void*)&taddr; + struct sockaddr_in6* addr = &taddr.in6; memset(addr, 0, sizeof *addr); addr->sin6_family = AF_INET6; addr->sin6_addr = in6addr_any; @@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, abort(); } - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags); + return uv__udp_bind(handle, &taddr.addr, addrlen, flags); } @@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req, if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); + + /* `uv__udp_sendmsg` may not be able to do non-blocking write straight + * away. In such cases the `io_watcher` has to be queued for asynchronous + * write. + */ + if (!QUEUE_EMPTY(&handle->write_queue)) + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } else { uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 27902fdf8645f7..781a8559dc8428 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -55,16 +55,19 @@ extern int snprintf(char*, size_t, const char*, ...); #ifndef _WIN32 enum { + UV__SIGNAL_ONE_SHOT = 0x80000, /* On signal reception remove sighandler */ UV__HANDLE_INTERNAL = 0x8000, UV__HANDLE_ACTIVE = 0x4000, UV__HANDLE_REF = 0x2000, UV__HANDLE_CLOSING = 0 /* no-op on unix */ }; #else -# define UV__HANDLE_INTERNAL 0x80 -# define UV__HANDLE_ACTIVE 0x40 -# define UV__HANDLE_REF 0x20 -# define UV__HANDLE_CLOSING 0x01 +# define UV__SIGNAL_ONE_SHOT_DISPATCHED 0x200 +# define UV__SIGNAL_ONE_SHOT 0x100 +# define UV__HANDLE_INTERNAL 0x80 +# define UV__HANDLE_ACTIVE 0x40 +# define UV__HANDLE_REF 0x20 +# define UV__HANDLE_CLOSING 0x01 #endif int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap); @@ -215,6 +218,30 @@ void uv__fs_scandir_cleanup(uv_fs_t* req); } \ while (0) +/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of + * a circular dependency between src/uv-common.h and src/win/internal.h. + */ +#if defined(_WIN32) +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + (req)->u.io.overlapped.Internal = 0; /* SET_REQ_SUCCESS() */ \ + } \ + while (0) +#else +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + } \ + while (0) +#endif + +#define uv__req_init(loop, req, typ) \ + do { \ + UV_REQ_INIT(req, typ); \ + uv__req_register(loop, req); \ + } \ + while (0) /* Allocator prototypes */ void *uv__calloc(size_t count, size_t size); diff --git a/deps/uv/src/win/async.c b/deps/uv/src/win/async.c index ad240ab897241e..0b636ed1e9137a 100644 --- a/deps/uv/src/win/async.c +++ b/deps/uv/src/win/async.c @@ -45,8 +45,7 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { handle->async_cb = async_cb; req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; + UV_REQ_INIT(req, UV_WAKEUP); req->data = handle; uv__handle_start(handle); diff --git a/deps/uv/src/win/atomicops-inl.h b/deps/uv/src/win/atomicops-inl.h index 61e006026c1867..6d8126f6921bbb 100644 --- a/deps/uv/src/win/atomicops-inl.h +++ b/deps/uv/src/win/atomicops-inl.h @@ -23,6 +23,7 @@ #define UV_WIN_ATOMICOPS_INL_H_ #include "uv.h" +#include "internal.h" /* Atomic set operation on char */ @@ -34,7 +35,7 @@ /* target to be aligned. */ #pragma intrinsic(_InterlockedOr8) -static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) { +static char INLINE uv__atomic_exchange_set(char volatile* target) { return _InterlockedOr8(target, 1); } diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index e84186d4ecc840..9ed4e824c6e96b 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -83,13 +83,8 @@ static int uv__loops_capacity; #define UV__LOOPS_CHUNK_SIZE 8 static uv_mutex_t uv__loops_lock; -static void uv__loops_init() { +static void uv__loops_init(void) { uv_mutex_init(&uv__loops_lock); - uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*)); - if (!uv__loops) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - uv__loops_size = 0; - uv__loops_capacity = UV__LOOPS_CHUNK_SIZE; } static int uv__loops_add(uv_loop_t* loop) { @@ -138,6 +133,13 @@ static void uv__loops_remove(uv_loop_t* loop) { uv__loops[uv__loops_size - 1] = NULL; --uv__loops_size; + if (uv__loops_size == 0) { + uv__loops_capacity = 0; + uv__free(uv__loops); + uv__loops = NULL; + goto loop_removed; + } + /* If we didn't grow to big skip downsizing */ if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE) goto loop_removed; @@ -156,7 +158,7 @@ static void uv__loops_remove(uv_loop_t* loop) { uv_mutex_unlock(&uv__loops_lock); } -void uv__wake_all_loops() { +void uv__wake_all_loops(void) { int i; uv_loop_t* loop; @@ -332,6 +334,11 @@ int uv_backend_fd(const uv_loop_t* loop) { } +int uv_loop_fork(uv_loop_t* loop) { + return UV_ENOSYS; +} + + int uv_backend_timeout(const uv_loop_t* loop) { if (loop->stop_flag != 0) return 0; diff --git a/deps/uv/src/win/detect-wakeup.c b/deps/uv/src/win/detect-wakeup.c index a12179f7981d13..72dfb7a1771765 100644 --- a/deps/uv/src/win/detect-wakeup.c +++ b/deps/uv/src/win/detect-wakeup.c @@ -2,9 +2,9 @@ #include "internal.h" #include "winapi.h" -static void uv__register_system_resume_callback(); +static void uv__register_system_resume_callback(void); -void uv__init_detect_system_wakeup() { +void uv__init_detect_system_wakeup(void) { /* Try registering system power event callback. This is the cleanest * method, but it will only work on Win8 and above. */ @@ -20,7 +20,7 @@ static ULONG CALLBACK uv__system_resume_callback(PVOID Context, return 0; } -static void uv__register_system_resume_callback() { +static void uv__register_system_resume_callback(void) { _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient; _HPOWERNOTIFY registration_handle; diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 03e4adc058f9f3..95f843ad08edee 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -81,8 +81,17 @@ static void uv_relative_path(const WCHAR* filename, static int uv_split_path(const WCHAR* filename, WCHAR** dir, WCHAR** file) { - int len = wcslen(filename); - int i = len; + size_t len, i; + + if (filename == NULL) { + if (dir != NULL) + *dir = NULL; + *file = NULL; + return 0; + } + + len = wcslen(filename); + i = len; while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); if (i == 0) { @@ -131,8 +140,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { handle->short_filew = NULL; handle->dirw = NULL; - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; + UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ); handle->req.data = handle; return 0; @@ -146,7 +154,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, int name_size, is_path_dir; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; - WCHAR short_path[MAX_PATH]; + WCHAR short_path_buffer[MAX_PATH]; + WCHAR* short_path; if (uv__is_active(handle)) return UV_EINVAL; @@ -188,7 +197,6 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (is_path_dir) { /* path is a directory, so that's the directory that we will watch. */ - handle->dirw = pathw; dir_to_watch = pathw; } else { /* @@ -197,9 +205,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, */ /* Convert to short path. */ + short_path = short_path_buffer; if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; + short_path = NULL; } if (uv_split_path(pathw, &dir, &handle->filew) != 0) { @@ -274,6 +282,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, goto error; } + assert(is_path_dir ? pathw != NULL : pathw == NULL); + handle->dirw = pathw; handle->req_pending = 1; return 0; @@ -305,6 +315,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->buffer = NULL; } + if (uv__is_active(handle)) + uv__handle_stop(handle); + return uv_translate_sys_error(last_error); } @@ -344,8 +357,11 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { } -static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) { - int str_len; +static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) { + size_t str_len; + + if (str == NULL) + return -1; str_len = wcslen(str); diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 6902d4f1a69485..2d72cdc70fe7d8 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -114,7 +114,7 @@ const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; const WCHAR UNC_PATH_PREFIX_LEN = 8; -void uv_fs_init() { +void uv_fs_init(void) { _fmode = _O_BINARY; } @@ -220,9 +220,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type, const uv_fs_cb cb) { - uv_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; + UV_REQ_INIT(req, UV_FS); req->loop = loop; req->flags = 0; req->fs_type = fs_type; @@ -1373,7 +1371,7 @@ static void fs__access(uv_fs_t* req) { * - or it's a directory. * (Directories cannot be read-only on Windows.) */ - if (!(req->flags & W_OK) || + if (!(req->fs.info.mode & W_OK) || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { SET_REQ_RESULT(req, 0); @@ -2400,7 +2398,7 @@ int uv_fs_access(uv_loop_t* loop, if (err) return uv_translate_sys_error(err); - req->flags = flags; + req->fs.info.mode = flags; if (cb) { QUEUE_FS_TP_JOB(loop, req); diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c index c13bfec350f27e..baab838898a62e 100644 --- a/deps/uv/src/win/getaddrinfo.c +++ b/deps/uv/src/win/getaddrinfo.c @@ -265,11 +265,9 @@ int uv_getaddrinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); - + UV_REQ_INIT(req, UV_GETADDRINFO); req->getaddrinfo_cb = getaddrinfo_cb; req->addrinfo = NULL; - req->type = UV_GETADDRINFO; req->loop = loop; req->retcode = 0; diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c index 66b64b883248e3..9f10cd2a5a1432 100644 --- a/deps/uv/src/win/getnameinfo.c +++ b/deps/uv/src/win/getnameinfo.c @@ -127,12 +127,11 @@ int uv_getnameinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); + UV_REQ_INIT(req, UV_GETNAMEINFO); uv__req_register(loop, req); req->getnameinfo_cb = getnameinfo_cb; req->flags = flags; - req->type = UV_GETNAMEINFO; req->loop = loop; req->retcode = 0; diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index 72b49d979045ba..39150702ddcd07 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -152,3 +152,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { int uv_is_closing(const uv_handle_t* handle) { return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); } + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return uv__get_osfhandle(fd); +} diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index b8cfde90e81f8b..444327d647f284 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -206,7 +206,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); /* * TTY */ -void uv_console_init(); +void uv_console_init(void); int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb); @@ -259,7 +259,7 @@ void uv_prepare_invoke(uv_loop_t* loop); void uv_check_invoke(uv_loop_t* loop); void uv_idle_invoke(uv_loop_t* loop); -void uv__once_init(); +void uv__once_init(void); /* @@ -275,7 +275,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, /* * Signal watcher */ -void uv_signals_init(); +void uv_signals_init(void); int uv__signal_dispatch(int signum); void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); @@ -302,7 +302,7 @@ int uv_translate_sys_error(int sys_errno); /* * FS */ -void uv_fs_init(); +void uv_fs_init(void); /* @@ -323,14 +323,15 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); /* * Utilities. */ -void uv__util_init(); +void uv__util_init(void); uint64_t uv__hrtime(double scale); -int uv_parent_pid(); -int uv_current_pid(); +int uv_parent_pid(void); +int uv_current_pid(void); __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); int uv__getpwuid_r(uv_passwd_t* pwd); int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16); /* @@ -349,13 +350,13 @@ HANDLE uv__stdio_handle(BYTE* buffer, int fd); /* * Winapi and ntapi utility functions */ -void uv_winapi_init(); +void uv_winapi_init(void); /* * Winsock utility functions */ -void uv_winsock_init(); +void uv_winsock_init(void); int uv_ntstatus_to_winsock_error(NTSTATUS status); @@ -384,11 +385,11 @@ extern struct sockaddr_in6 uv_addr_ip6_any_; /* * Wake all loops with fake message */ -void uv__wake_all_loops(); +void uv__wake_all_loops(void); /* * Init system wake-up detection */ -void uv__init_detect_system_wakeup(); +void uv__init_detect_system_wakeup(void); #endif /* UV_WIN_INTERNAL_H_ */ diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 2442be7301ebf8..edf30021217980 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -103,7 +103,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { handle->pipe.conn.non_overlapped_writes_tail = NULL; handle->pipe.conn.readfile_thread = NULL; - uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req); + UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ); return 0; } @@ -505,8 +505,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) { req = &handle->pipe.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->data = handle; req->pipeHandle = INVALID_HANDLE_VALUE; req->next_pending = NULL; @@ -626,8 +625,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, HANDLE pipeHandle = INVALID_HANDLE_VALUE; DWORD duplex_flags; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; @@ -962,7 +960,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */ if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hThread, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { + 0, FALSE, DUPLICATE_SAME_ACCESS)) { handle->pipe.conn.readfile_thread = hThread; } else { hThread = NULL; @@ -1239,8 +1237,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, assert(handle->handle != INVALID_HANDLE_VALUE); - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; req->ipc_header = 0; @@ -1301,8 +1298,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, } } - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; + UV_REQ_INIT(ipc_header_req, UV_WRITE); ipc_header_req->handle = (uv_stream_t*) handle; ipc_header_req->cb = NULL; ipc_header_req->ipc_header = 1; @@ -2076,7 +2072,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) buffer[addrlen] = '\0'; err = 0; - goto cleanup; error: uv__free(name_info); diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c index d479e521efe24f..a648ba711d569a 100644 --- a/deps/uv/src/win/poll.c +++ b/deps/uv/src/win/poll.c @@ -61,13 +61,13 @@ static void uv__init_overlapped_dummy(void) { } -static OVERLAPPED* uv__get_overlapped_dummy() { +static OVERLAPPED* uv__get_overlapped_dummy(void) { uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); return &overlapped_dummy_; } -static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() { +static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) { return &afd_poll_info_dummy_; } @@ -572,13 +572,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, /* Initialize 2 poll reqs. */ handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ); handle->poll_req_1.data = handle; handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ); handle->poll_req_2.data = handle; return 0; diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index bdf88d2cdd944c..d141601607851b 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -148,8 +148,7 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { handle->child_stdio_buffer = NULL; handle->exit_cb_pending = 0; - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; + UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT); handle->exit_req.data = handle; } diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h index b5e502eef5521a..f2513b7d3e7b5b 100644 --- a/deps/uv/src/win/req-inl.h +++ b/deps/uv/src/win/req-inl.h @@ -34,6 +34,9 @@ #define SET_REQ_ERROR(req, error) \ SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) +/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency + * between src/uv-common.h and src/win/internal.h. + */ #define SET_REQ_SUCCESS(req) \ SET_REQ_STATUS((req), STATUS_SUCCESS) @@ -79,12 +82,6 @@ } -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); } diff --git a/deps/uv/src/win/signal.c b/deps/uv/src/win/signal.c index af7974c364465f..7b42dd99280a00 100644 --- a/deps/uv/src/win/signal.c +++ b/deps/uv/src/win/signal.c @@ -34,7 +34,12 @@ static CRITICAL_SECTION uv__signal_lock; static BOOL WINAPI uv__signal_control_handler(DWORD type); -void uv_signals_init() { +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); + +void uv_signals_init(void) { InitializeCriticalSection(&uv__signal_lock); if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) abort(); @@ -70,7 +75,9 @@ RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare int uv__signal_dispatch(int signum) { uv_signal_t lookup; uv_signal_t* handle; - int dispatched = 0; + int dispatched; + + dispatched = 0; EnterCriticalSection(&uv__signal_lock); @@ -83,11 +90,16 @@ int uv__signal_dispatch(int signum) { unsigned long previous = InterlockedExchange( (volatile LONG*) &handle->pending_signum, signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED) + continue; + if (!previous) { POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); } dispatched = 1; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED; } LeaveCriticalSection(&uv__signal_lock); @@ -128,17 +140,13 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) { int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); handle->pending_signum = 0; handle->signum = 0; handle->signal_cb = NULL; - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; + UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ); + handle->signal_req.data = handle; return 0; } @@ -166,6 +174,21 @@ int uv_signal_stop(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { /* Test for invalid signal values. */ if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG)) return UV_EINVAL; @@ -189,6 +212,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { EnterCriticalSection(&uv__signal_lock); handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); LeaveCriticalSection(&uv__signal_lock); @@ -217,6 +243,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, if (dispatched_signum == handle->signum) handle->signal_cb(handle, dispatched_signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv_signal_stop(handle); + if (handle->flags & UV__HANDLE_CLOSING) { /* When it is closing, it must be stopped at this point. */ assert(handle->signum == 0); diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h index b7a3c11958c274..bf12148afe1605 100644 --- a/deps/uv/src/win/stream-inl.h +++ b/deps/uv/src/win/stream-inl.h @@ -43,10 +43,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) { handle->flags |= UV_HANDLE_CONNECTION; handle->stream.conn.write_reqs_pending = 0; - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); + UV_REQ_INIT(&handle->read_req, UV_READ); handle->read_req.event_handle = NULL; handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; handle->read_req.data = handle; handle->stream.conn.shutdown_req = NULL; diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c index a2466e5e9db8ba..13cbfdcb9e6e5f 100644 --- a/deps/uv/src/win/stream.c +++ b/deps/uv/src/win/stream.c @@ -210,8 +210,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { return UV_EPIPE; } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; + UV_REQ_INIT(req, UV_SHUTDOWN); req->handle = handle; req->cb = cb; diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 0709696ff9afed..972539f4df49d0 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -555,7 +555,6 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; unsigned int i, simultaneous_accepts; uv_tcp_accept_t* req; int err; @@ -612,8 +611,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { for (i = 0; i < simultaneous_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; @@ -635,8 +633,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { /* try to clean up {uv_simultaneous_server_accepts} requests. */ for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; req->wait_handle = INVALID_HANDLE_VALUE; @@ -779,8 +776,7 @@ static int uv_tcp_try_connect(uv_connect_t* req, } } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); @@ -863,8 +859,7 @@ int uv_tcp_write(uv_loop_t* loop, int result; DWORD bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 1b7adf64ffcbdb..a6f583956fe6b3 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -138,7 +138,7 @@ typedef enum { static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED; static void uv__determine_vterm_state(HANDLE handle); -void uv_console_init() { +void uv_console_init(void) { if (uv_sem_init(&uv_tty_output_lock, 1)) abort(); } @@ -2126,8 +2126,7 @@ int uv_tty_write(uv_loop_t* loop, uv_write_cb cb) { DWORD error; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 9bf1453e536d9a..2fd15cfa9a64fa 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -142,8 +142,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { handle->func_wsarecvfrom = WSARecvFrom; handle->send_queue_size = 0; handle->send_queue_count = 0; - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; + UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV); handle->recv_req.data = handle; /* If anything fails beyond this point we need to remove the handle from @@ -417,8 +416,7 @@ static int uv__send(uv_udp_send_t* req, uv_loop_t* loop = handle->loop; DWORD result, bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; + UV_REQ_INIT(req, UV_UDP_SEND); req->handle = handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 050058afaa9a90..d2e7f772ce2977 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -59,6 +59,17 @@ # define UNLEN 256 #endif +/* + Max hostname length. The Windows gethostname() documentation states that 256 + bytes will always be large enough to hold the null-terminated hostname. +*/ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +/* Maximum environment variable size, including the terminating null */ +#define MAX_ENV_VAR_LENGTH 32767 + /* Cached copy of the process title, plus a mutex guarding it. */ static char *process_title; static CRITICAL_SECTION process_title_lock; @@ -74,7 +85,7 @@ static double hrtime_interval_ = 0; /* * One-time initialization code for functionality defined in util.c. */ -void uv__util_init() { +void uv__util_init(void) { LARGE_INTEGER perf_frequency; /* Initialize process title access mutex. */ @@ -320,7 +331,7 @@ uint64_t uv_get_total_memory(void) { } -int uv_parent_pid() { +int uv_parent_pid(void) { int parent_pid = -1; HANDLE handle; PROCESSENTRY32 pe; @@ -343,7 +354,7 @@ int uv_parent_pid() { } -int uv_current_pid() { +int uv_current_pid(void) { if (current_pid == 0) { current_pid = GetCurrentProcessId(); } @@ -405,7 +416,7 @@ int uv_set_process_title(const char* title) { } -static int uv__get_process_title() { +static int uv__get_process_title(void) { WCHAR title_w[MAX_TITLE_LENGTH]; if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { @@ -1322,6 +1333,47 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) { } +/* + * Converts a UTF-8 string into a UTF-16 one. The resulting string is + * null-terminated. + * + * If utf8 is null terminated, utf8len can be set to -1, otherwise it must + * be specified. + */ +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) { + int bufsize; + + if (utf8 == NULL) + return UV_EINVAL; + + /* Check how much space we need */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + /* Allocate the destination buffer adding an extra byte for the terminating + * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so + * we do it ourselves always, just in case. */ + *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1)); + + if (*utf16 == NULL) + return UV_ENOMEM; + + /* Convert to UTF-16 */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); + + if (bufsize == 0) { + uv__free(*utf16); + *utf16 = NULL; + return uv_translate_sys_error(GetLastError()); + } + + (*utf16)[bufsize] = '\0'; + return 0; +} + + int uv__getpwuid_r(uv_passwd_t* pwd) { HANDLE token; wchar_t username[UNLEN + 1]; @@ -1387,3 +1439,138 @@ int uv__getpwuid_r(uv_passwd_t* pwd) { int uv_os_get_passwd(uv_passwd_t* pwd) { return uv__getpwuid_r(pwd); } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + wchar_t var[MAX_ENV_VAR_LENGTH]; + wchar_t* name_w; + DWORD bufsize; + size_t len; + int r; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH); + uv__free(name_w); + assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */ + + if (len == 0) { + r = GetLastError(); + + if (r == ERROR_ENVVAR_NOT_FOUND) + return UV_ENOENT; + + return uv_translate_sys_error(r); + } + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + *size = bufsize; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + var, + -1, + buffer, + *size, + NULL, + NULL); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + wchar_t* name_w; + wchar_t* value_w; + int r; + + if (name == NULL || value == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = uv__convert_utf8_to_utf16(value, -1, &value_w); + + if (r != 0) { + uv__free(name_w); + return r; + } + + r = SetEnvironmentVariableW(name_w, value_w); + uv__free(name_w); + uv__free(value_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + wchar_t* name_w; + int r; + + if (name == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = SetEnvironmentVariableW(name_w, NULL); + uv__free(name_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv__once_init(); /* Initialize winsock */ + + if (gethostname(buf, sizeof(buf)) != 0) + return uv_translate_sys_error(WSAGetLastError()); + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index 1fa179b5724ed0..aa5d719fbea199 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -53,7 +53,7 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW; sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; -void uv_winapi_init() { +void uv_winapi_init(void) { HMODULE ntdll_module; HMODULE kernel32_module; HMODULE powrprof_module; diff --git a/deps/uv/src/win/winsock.c b/deps/uv/src/win/winsock.c index d2e667e9f7546a..e86d76b131caa4 100644 --- a/deps/uv/src/win/winsock.c +++ b/deps/uv/src/win/winsock.c @@ -80,7 +80,7 @@ static int error_means_no_support(DWORD error) { } -void uv_winsock_init() { +void uv_winsock_init(void) { WSADATA wsa_data; int errorno; SOCKET dummy; diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 1b4a569aef54dd..0f1b56e777c6cb 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -209,22 +209,30 @@ long int process_output_size(process_info_t *p) { int process_copy_output(process_info_t* p, FILE* stream) { - DWORD read; char buf[1024]; + int fd, r; + FILE* f; - if (SetFilePointer(p->stdio_out, - 0, - 0, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) { + fd = _open_osfhandle((intptr_t)p->stdio_out, _O_RDONLY | _O_TEXT); + if (fd == -1) + return -1; + f = _fdopen(fd, "rt"); + if (f == NULL) { + _close(fd); return -1; } - while (ReadFile(p->stdio_out, &buf, sizeof(buf), &read, NULL) && read > 0) - print_lines(buf, read, stream); + r = fseek(f, 0, SEEK_SET); + if (r < 0) + return -1; - if (GetLastError() != ERROR_HANDLE_EOF) + while (fgets(buf, sizeof(buf), f) != NULL) + print_lines(buf, strlen(buf), stream); + + if (ferror(f)) return -1; + fclose(f); return 0; } diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 65a1132e49865d..67eb9804926824 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -209,4 +209,24 @@ UNUSED static int can_ipv6(void) { return supported; } +#if defined(__MVS__) || defined(__CYGWIN__) || defined(__MSYS__) +# define NO_FS_EVENTS "Filesystem watching not supported on this platform." +#endif + +#if defined(__MSYS__) +# define NO_SEND_HANDLE_ON_PIPE \ + "MSYS2 runtime does not support sending handles on pipes." +#elif defined(__CYGWIN__) +# define NO_SEND_HANDLE_ON_PIPE \ + "Cygwin runtime does not support sending handles on pipes." +#endif + +#if defined(__MSYS__) +# define NO_SELF_CONNECT \ + "MSYS2 runtime hangs on listen+connect in same process." +#elif defined(__CYGWIN__) +# define NO_SELF_CONNECT \ + "Cygwin runtime hangs on listen+connect in same process." +#endif + #endif /* TASK_H_ */ diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c new file mode 100644 index 00000000000000..641050e675ffce --- /dev/null +++ b/deps/uv/test/test-env-vars.c @@ -0,0 +1,90 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define BUF_SIZE 10 + +TEST_IMPL(env_vars) { + const char* name = "UV_TEST_FOO"; + char buf[BUF_SIZE]; + size_t size; + int r; + + /* Reject invalid inputs when setting an environment variable */ + r = uv_os_setenv(NULL, "foo"); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(name, NULL); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(NULL, NULL); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when retrieving an environment variable */ + size = BUF_SIZE; + r = uv_os_getenv(NULL, buf, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when deleting an environment variable */ + r = uv_os_unsetenv(NULL); + ASSERT(r == UV_EINVAL); + + /* Successfully set an environment variable */ + r = uv_os_setenv(name, "123456789"); + ASSERT(r == 0); + + /* Successfully read an environment variable */ + size = BUF_SIZE; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == 0); + ASSERT(strcmp(buf, "123456789") == 0); + ASSERT(size == BUF_SIZE - 1); + + /* Return UV_ENOBUFS if the buffer cannot hold the environment variable */ + size = BUF_SIZE - 1; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOBUFS); + ASSERT(size == BUF_SIZE); + + /* Successfully delete an environment variable */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + /* Return UV_ENOENT retrieving an environment variable that does not exist */ + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOENT); + + /* Successfully delete an environment variable that does not exist */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + return 0; +} diff --git a/deps/uv/test/test-fork.c b/deps/uv/test/test-fork.c new file mode 100644 index 00000000000000..3716a3ad975c17 --- /dev/null +++ b/deps/uv/test/test-fork.c @@ -0,0 +1,677 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* These tests are Unix only. */ +#ifndef _WIN32 + +#include +#include +#include +#include + +#include "uv.h" +#include "task.h" + +static int timer_cb_called; +static int socket_cb_called; + +static void timer_cb(uv_timer_t* timer) { + timer_cb_called++; + uv_close((uv_handle_t*) timer, NULL); +} + + +static int socket_cb_read_fd; +static int socket_cb_read_size; +static char socket_cb_read_buf[1024]; + + +static void socket_cb(uv_poll_t* poll, int status, int events) { + ssize_t cnt; + socket_cb_called++; + ASSERT(0 == status); + printf("Socket cb got events %d\n", events); + ASSERT(UV_READABLE == (events & UV_READABLE)); + if (socket_cb_read_fd) { + cnt = read(socket_cb_read_fd, socket_cb_read_buf, socket_cb_read_size); + ASSERT(cnt == socket_cb_read_size); + } + uv_close((uv_handle_t*) poll, NULL); +} + + +static void run_timer_loop_once(void) { + uv_loop_t* loop; + uv_timer_t timer_handle; + + loop = uv_default_loop(); + + timer_cb_called = 0; /* Reset for the child. */ + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); +} + + +static void assert_wait_child(pid_t child_pid) { + pid_t waited_pid; + int child_stat; + + waited_pid = waitpid(child_pid, &child_stat, 0); + printf("Waited pid is %d with status %d\n", waited_pid, child_stat); + if (waited_pid == -1) { + perror("Failed to wait"); + } + ASSERT(child_pid == waited_pid); + ASSERT(WIFEXITED(child_stat)); /* Clean exit, not a signal. */ + ASSERT(!WIFSIGNALED(child_stat)); + ASSERT(0 == WEXITSTATUS(child_stat)); +} + + +TEST_IMPL(fork_timer) { + /* Timers continue to work after we fork. */ + + /* + * Establish the loop before we fork to make sure that it + * has state to get reset after the fork. + */ + pid_t child_pid; + + run_timer_loop_once(); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + run_timer_loop_once(); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair) { + /* A socket opened in the parent and accept'd in the + child works after a fork. */ + pid_t child_pid; + int socket_fds[2]; + uv_poll_t poll_handle; + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + printf("Going to run the loop in the child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair_started) { + /* A socket opened in the parent and accept'd in the + child works after a fork, even if the watcher was already + started, and then stopped in the parent. */ + pid_t child_pid; + int socket_fds[2]; + int sync_pipe[2]; + char sync_buf[1]; + uv_poll_t poll_handle; + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create and start the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + + /* Run the loop AFTER the poll watcher is registered to make sure it + gets passed to the kernel. Use NOWAIT and expect a non-zero + return to prove the poll watcher is active. + */ + ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(0 == uv_poll_stop(&poll_handle)); + uv_close((uv_handle_t*)&poll_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert child */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + + assert_wait_child(child_pid); + } else { + /* child */ + printf("Child is %d\n", getpid()); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for parent */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + + printf("Going to run the loop in the child\n"); + socket_cb_read_fd = socket_fds[0]; + socket_cb_read_size = 3; + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + printf("Buf %s\n", socket_cb_read_buf); + ASSERT(0 == strcmp("hi\n", socket_cb_read_buf)); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static int fork_signal_cb_called; + +void fork_signal_to_child_cb(uv_signal_t* handle, int signum) +{ + fork_signal_cb_called = signum; + uv_close((uv_handle_t*)handle, NULL); +} + + +TEST_IMPL(fork_signal_to_child) { + /* A signal handler installed before forking + is run only in the child when the child is signalled. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + char sync_buf[1]; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + ASSERT(0 == fork_signal_cb_called); + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Get the signal. */ + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Running loop in child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(SIGUSR1 == fork_signal_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_signal_to_child_closed) { + /* A signal handler installed before forking + doesn't get received anywhere when the child is signalled, + but isnt running the loop. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + int sync_pipe2[2]; + char sync_buf[1]; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + ASSERT(0 == pipe(sync_pipe2)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + printf("Wating on child in parent\n"); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + printf("Parent killing child\n"); + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); /* so the loop can exit; + we *shouldn't* get any signals */ + run_timer_loop_once(); /* but while we share a pipe, we do, so + have something active. */ + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + printf("Signal in parent %d\n", fork_signal_cb_called); + ASSERT(0 == fork_signal_cb_called); + ASSERT(1 == write(sync_pipe2[1], "1", 1)); /* alert child */ + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* child */ + /* Our signal handler should still be installed. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + printf("Checking loop in child\n"); + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Alerting parent in child\n"); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Don't run the loop. Wait for the parent to call us */ + printf("Waiting on parent in child\n"); + /* Wait for parent. read may fail if the parent tripped an ASSERT + and exited, so this isn't in an ASSERT. + */ + read(sync_pipe2[0], sync_buf, 1); + ASSERT(0 == fork_signal_cb_called); + printf("Exiting child \n"); + /* Note that we're deliberately not running the loop + * in the child, and also not closing the loop's handles, + * so the child default loop can't be cleanly closed. + * We need te explicitly exit to avoid an automatic failure + * in that case. + */ + exit(0); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void create_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static void touch_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + uv_buf_t buf; + + r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + + buf = uv_buf_init("foo", 4); + r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static int timer_cb_touch_called; + +static void timer_cb_touch(uv_timer_t* timer) { + uv_close((uv_handle_t*)timer, NULL); + touch_file("watch_file"); + timer_cb_touch_called++; +} + + +static int fs_event_cb_called; + +static void fs_event_cb_file_current_dir(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(fs_event_cb_called == 0); + ++fs_event_cb_called; + ASSERT(status == 0); +#if defined(__APPLE__) || defined(__linux__) + ASSERT(strcmp(filename, "watch_file") == 0); +#else + ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0); +#endif + uv_close((uv_handle_t*)handle, NULL); +} + + +static void assert_watch_file_current_dir(uv_loop_t* const loop, int file_or_dir) { + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + /* watching a dir is the only way to get fsevents involved on apple + platforms */ + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + file_or_dir == 1 ? "." : "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* flush pending closes */ +} + + +#define FS_TEST_FILE 0 +#define FS_TEST_DIR 1 + +static int _do_fork_fs_events_child(int file_or_dir) { + /* basic fsevents work in the child after a fork */ + pid_t child_pid; + uv_loop_t loop; + + /* Watch in the parent, prime the loop and/or threads. */ + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + /* Ee can watch in a new loop, but dirs only work + if we're on linux. */ +#if defined(__APPLE__) + file_or_dir = FS_TEST_FILE; +#endif + printf("Running child\n"); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_watch_file_current_dir(&loop, file_or_dir); + ASSERT(0 == uv_loop_close(&loop)); + printf("Child second watch default loop\n"); + /* Ee can watch in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + /* On some platforms (OS X), if we don't update the time now, + * the timer cb fires before the event loop enters uv__io_poll, + * instead of after, meaning we don't see the change! This may be + * a general race. + */ + uv_update_time(uv_default_loop()); + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + + /* We can close the parent loop successfully too. This is + especially important on Apple platforms where if we're not + careful trying to touch the CFRunLoop, even just to shut it + down, that we allocated in the FS_TEST_DIR case would crash. */ + ASSERT(0 == uv_loop_close(uv_default_loop())); + + printf("Exiting child \n"); + } + + MAKE_VALGRIND_HAPPY(); + return 0; + +} + + +TEST_IMPL(fork_fs_events_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + return _do_fork_fs_events_child(FS_TEST_FILE); +} + + +TEST_IMPL(fork_fs_events_child_dir) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__APPLE__) || defined (__linux__) + return _do_fork_fs_events_child(FS_TEST_DIR); +#else + /* You can't spin up a cfrunloop thread on an apple platform + and then fork. See + http://objectivistc.tumblr.com/post/16187948939/you-must-exec-a-core-foundation-fork-safety-tale + */ + return 0; +#endif +} + + +TEST_IMPL(fork_fs_events_file_parent_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__sun) || defined(_AIX) + /* It's not possible to implement this without additional + * bookkeeping on SunOS. For AIX it is possible, but has to be + * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420 + */ + return 0; +#else + /* Establishing a started fs events watcher in the parent should + still work in the child. */ + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + pid_t child_pid; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + child_pid = fork(); + ASSERT(child_pid != -1); + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + printf("Running child\n"); + ASSERT(0 == uv_loop_fork(loop)); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + printf("Running loop in child \n"); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* Flush pending closes. */ + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + + +static int work_cb_count; +static int after_work_cb_count; + + +static void work_cb(uv_work_t* req) { + work_cb_count++; +} + + +static void after_work_cb(uv_work_t* req, int status) { + ASSERT(status == 0); + after_work_cb_count++; +} + + +static void assert_run_work(uv_loop_t* const loop) { + uv_work_t work_req; + int r; + + ASSERT(work_cb_count == 0); + ASSERT(after_work_cb_count == 0); + printf("Queue in %d\n", getpid()); + r = uv_queue_work(loop, &work_req, work_cb, after_work_cb); + ASSERT(r == 0); + printf("Running in %d\n", getpid()); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(work_cb_count == 1); + ASSERT(after_work_cb_count == 1); + + /* cleanup */ + work_cb_count = 0; + after_work_cb_count = 0; +} + + +TEST_IMPL(fork_threadpool_queue_work_simple) { + /* The threadpool works in a child process. */ + + pid_t child_pid; + uv_loop_t loop; + + /* Prime the pool and default loop. */ + assert_run_work(uv_default_loop()); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + /* We can still run work. */ + assert_run_work(uv_default_loop()); + assert_wait_child(child_pid); + } else { + /* child */ + /* We can work in a new loop. */ + printf("Running child in %d\n", getpid()); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_run_work(&loop); + uv_loop_close(&loop); + printf("Child second watch default loop\n"); + /* We can work in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + assert_run_work(uv_default_loop()); + printf("Exiting child \n"); + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index df8dc4c2f700fd..fba6b5440b0fc3 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -394,8 +394,8 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { } TEST_IMPL(fs_event_watch_dir) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -477,8 +477,8 @@ TEST_IMPL(fs_event_watch_dir_recursive) { TEST_IMPL(fs_event_watch_file) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -522,8 +522,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) { "file.js". The test verifies that no events occur for file.jsx. */ -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; @@ -561,8 +561,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) { } TEST_IMPL(fs_event_watch_file_twice) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif const char path[] = "test/fixtures/empty_file"; uv_fs_event_t watchers[2]; @@ -585,8 +585,8 @@ TEST_IMPL(fs_event_watch_file_twice) { } TEST_IMPL(fs_event_watch_file_current_dir) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_timer_t timer; uv_loop_t* loop; @@ -658,8 +658,8 @@ TEST_IMPL(fs_event_watch_file_root_dir) { #endif TEST_IMPL(fs_event_no_callback_after_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -696,8 +696,8 @@ TEST_IMPL(fs_event_no_callback_after_close) { } TEST_IMPL(fs_event_no_callback_on_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -747,8 +747,8 @@ static void timer_cb(uv_timer_t* handle) { TEST_IMPL(fs_event_immediate_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_timer_t timer; uv_loop_t* loop; @@ -772,8 +772,8 @@ TEST_IMPL(fs_event_immediate_close) { TEST_IMPL(fs_event_close_with_pending_event) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; int r; @@ -818,8 +818,8 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, } TEST_IMPL(fs_event_close_in_callback) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; int r; @@ -857,8 +857,8 @@ TEST_IMPL(fs_event_close_in_callback) { } TEST_IMPL(fs_event_start_and_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; uv_fs_event_t fs_event1; @@ -892,8 +892,8 @@ TEST_IMPL(fs_event_start_and_close) { } TEST_IMPL(fs_event_getpath) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); int r; @@ -1027,3 +1027,21 @@ TEST_IMPL(fs_event_error_reporting) { } #endif /* defined(__APPLE__) */ + +TEST_IMPL(fs_event_watch_invalid_path) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0); + ASSERT(r != 0); + ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 030245eadc5389..c482ab5c71c06a 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -125,7 +125,7 @@ static void check_permission(const char* filename, unsigned int mode) { ASSERT(req.result == 0); s = &req.statbuf; -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__) /* * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit, * so only testing for the specified flags. @@ -240,7 +240,7 @@ static void chown_cb(uv_fs_t* req) { static void chown_root_cb(uv_fs_t* req) { ASSERT(req->fs_type == UV_FS_CHOWN); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__MSYS__) /* On windows, chown is a no-op and always succeeds. */ ASSERT(req->result == 0); #else @@ -250,7 +250,12 @@ static void chown_root_cb(uv_fs_t* req) { if (geteuid() == 0) ASSERT(req->result == 0); else +# if defined(__CYGWIN__) + /* On Cygwin, uid 0 is invalid (no root). */ + ASSERT(req->result == UV_EINVAL); +# else ASSERT(req->result == UV_EPERM); +# endif #endif chown_cb_count++; uv_fs_req_cleanup(req); @@ -641,6 +646,11 @@ TEST_IMPL(fs_file_loop) { */ if (r == UV_ENOTSUP || r == UV_EPERM) return 0; +#elif defined(__MSYS__) + /* MSYS2's approximation of symlinks with copies does not work for broken + links. */ + if (r == UV_ENOENT) + return 0; #endif ASSERT(r == 0); uv_fs_req_cleanup(&req); @@ -1485,6 +1495,7 @@ TEST_IMPL(fs_chown) { /* chown to root (fail) */ chown_cb_count = 0; r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); + ASSERT(r == 0); uv_run(loop, UV_RUN_DEFAULT); ASSERT(chown_cb_count == 1); @@ -1734,6 +1745,10 @@ TEST_IMPL(fs_symlink) { ASSERT(r == 0); uv_fs_req_cleanup(&req); +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif + r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL); ASSERT(r == 0); ASSERT(strcmp(req.ptr, "test_file_symlink") == 0); @@ -1877,6 +1892,9 @@ TEST_IMPL(fs_symlink_dir) { r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL); ASSERT(r == 0); +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK); #ifdef _WIN32 ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4)); @@ -2102,8 +2120,13 @@ TEST_IMPL(fs_futime) { uv_fs_req_cleanup(&req); r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(r == UV_ENOSYS); + RETURN_SKIP("futime not supported on Cygwin"); +#else ASSERT(r == 0); ASSERT(req.result == 0); +#endif uv_fs_req_cleanup(&req); r = uv_fs_stat(NULL, &req, path, NULL); @@ -2412,6 +2435,9 @@ TEST_IMPL(fs_rename_to_existing_file) { TEST_IMPL(fs_read_file_eof) { +#if defined(__CYGWIN__) || defined(__MSYS__) + RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!"); +#endif int r; /* Setup. */ @@ -2739,3 +2765,42 @@ TEST_IMPL(fs_read_write_null_arguments) { return 0; } + + +TEST_IMPL(get_osfhandle_valid_handle) { + int r; + uv_os_fd_t fd; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + fd = uv_get_osfhandle(open_req1.result); +#ifdef _WIN32 + ASSERT(fd != INVALID_HANDLE_VALUE); +#else + ASSERT(fd >= 0); +#endif + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-gethostname.c b/deps/uv/test/test-gethostname.c new file mode 100644 index 00000000000000..5229804b569421 --- /dev/null +++ b/deps/uv/test/test-gethostname.c @@ -0,0 +1,62 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +TEST_IMPL(gethostname) { + char buf[MAXHOSTNAMELEN + 1]; + size_t size; + size_t enobufs_size; + int r; + + /* Reject invalid inputs */ + size = 1; + r = uv_os_gethostname(NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_gethostname(buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_gethostname(buf, &size); + ASSERT(r == UV_EINVAL); + + /* Return UV_ENOBUFS if the buffer cannot hold the hostname */ + enobufs_size = 1; + buf[0] = '\0'; + r = uv_os_gethostname(buf, &enobufs_size); + ASSERT(r == UV_ENOBUFS); + ASSERT(buf[0] == '\0'); + ASSERT(enobufs_size > 1); + + /* Successfully get the hostname */ + size = MAXHOSTNAMELEN + 1; + r = uv_os_gethostname(buf, &size); + ASSERT(r == 0); + ASSERT(size > 1 && size == strlen(buf)); + ASSERT(size + 1 == enobufs_size); + + return 0; +} diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index 869b099e0fccaf..156fccde39deb6 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -32,6 +32,10 @@ TEST_IMPL(ip6_addr_link_local) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif char string_address[INET6_ADDRSTRLEN]; uv_interface_address_t* addresses; uv_interface_address_t* address; diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c index 133ae901493728..160c235078b939 100644 --- a/deps/uv/test/test-ipc-send-recv.c +++ b/deps/uv/test/test-ipc-send-recv.c @@ -224,10 +224,16 @@ static int run_ipc_send_recv_pipe(int inprocess) { } TEST_IMPL(ipc_send_recv_pipe) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_pipe(0); } TEST_IMPL(ipc_send_recv_pipe_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_pipe(1); } @@ -259,10 +265,16 @@ static int run_ipc_send_recv_tcp(int inprocess) { } TEST_IMPL(ipc_send_recv_tcp) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_tcp(0); } TEST_IMPL(ipc_send_recv_tcp_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_tcp(1); } @@ -335,7 +347,7 @@ static void read_cb(uv_stream_t* handle, } while (uv_pipe_pending_count(pipe) > 0); } -static void send_recv_start() { +static void send_recv_start(void) { int r; ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx2.channel)); ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx2.channel)); diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index f018c2d4d49b7f..a2fda2458546ba 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -411,6 +411,9 @@ static int run_ipc_test(const char* helper, uv_read_cb read_cb) { TEST_IMPL(ipc_listen_before_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_listen_before_write", on_read); ASSERT(local_conn_accepted == 1); ASSERT(remote_conn_accepted == 1); @@ -421,6 +424,9 @@ TEST_IMPL(ipc_listen_before_write) { TEST_IMPL(ipc_listen_after_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_listen_after_write", on_read); ASSERT(local_conn_accepted == 1); ASSERT(remote_conn_accepted == 1); @@ -431,6 +437,9 @@ TEST_IMPL(ipc_listen_after_write) { TEST_IMPL(ipc_tcp_connection) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection); ASSERT(read_cb_called == 1); ASSERT(tcp_write_cb_called == 1); @@ -491,6 +500,9 @@ TEST_IMPL(listen_no_simultaneous_accepts) { } TEST_IMPL(ipc_listen_after_bind_twice) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice); ASSERT(read_cb_called == 2); ASSERT(exit_cb_called == 1); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 3a1e82a919186b..3571aa2308397f 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -116,6 +116,7 @@ TEST_DECLARE (udp_create_early) TEST_DECLARE (udp_create_early_bad_bind) TEST_DECLARE (udp_create_early_bad_domain) TEST_DECLARE (udp_send_and_recv) +TEST_DECLARE (udp_send_hang_loop) TEST_DECLARE (udp_send_immediate) TEST_DECLARE (udp_send_unreachable) TEST_DECLARE (udp_multicast_join) @@ -153,6 +154,7 @@ TEST_DECLARE (shutdown_close_pipe) TEST_DECLARE (shutdown_eof) TEST_DECLARE (shutdown_twice) TEST_DECLARE (callback_stack) +TEST_DECLARE (env_vars) TEST_DECLARE (error_message) TEST_DECLARE (sys_error) TEST_DECLARE (timer) @@ -218,6 +220,7 @@ TEST_DECLARE (getaddrinfo_fail_sync) TEST_DECLARE (getaddrinfo_basic) TEST_DECLARE (getaddrinfo_basic_sync) TEST_DECLARE (getaddrinfo_concurrent) +TEST_DECLARE (gethostname) TEST_DECLARE (getnameinfo_basic_ip4) TEST_DECLARE (getnameinfo_basic_ip4_sync) TEST_DECLARE (getnameinfo_basic_ip6) @@ -286,6 +289,7 @@ TEST_DECLARE (fs_event_watch_file_current_dir) #ifdef _WIN32 TEST_DECLARE (fs_event_watch_file_root_dir) #endif +TEST_DECLARE (fs_event_watch_invalid_path) TEST_DECLARE (fs_event_no_callback_after_close) TEST_DECLARE (fs_event_no_callback_on_close) TEST_DECLARE (fs_event_immediate_close) @@ -301,6 +305,7 @@ TEST_DECLARE (fs_open_dir) TEST_DECLARE (fs_rename_to_existing_file) TEST_DECLARE (fs_write_multiple_bufs) TEST_DECLARE (fs_read_write_null_arguments) +TEST_DECLARE (get_osfhandle_valid_handle) TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) TEST_DECLARE (threadpool_queue_work_simple) @@ -354,6 +359,8 @@ TEST_DECLARE (spawn_fs_open) TEST_DECLARE (spawn_setuid_setgid) TEST_DECLARE (we_get_signal) TEST_DECLARE (we_get_signals) +TEST_DECLARE (we_get_signal_one_shot) +TEST_DECLARE (we_get_signals_mixed) TEST_DECLARE (signal_multiple_loops) TEST_DECLARE (closed_fd_events) #endif @@ -368,6 +375,18 @@ HELPER_DECLARE (pipe_echo_server) TEST_DECLARE (queue_foreach_delete) +#ifndef _WIN32 +TEST_DECLARE (fork_timer) +TEST_DECLARE (fork_socketpair) +TEST_DECLARE (fork_socketpair_started) +TEST_DECLARE (fork_signal_to_child) +TEST_DECLARE (fork_signal_to_child_closed) +TEST_DECLARE (fork_fs_events_child) +TEST_DECLARE (fork_fs_events_child_dir) +TEST_DECLARE (fork_fs_events_file_parent_child) +TEST_DECLARE (fork_threadpool_queue_work_simple) +#endif + TASK_LIST_START TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000) @@ -443,7 +462,11 @@ TASK_LIST_START TEST_ENTRY (tcp_write_after_connect) #endif +#ifdef __MVS__ + TEST_ENTRY_CUSTOM (tcp_writealot, 0, 0, 20000) +#else TEST_ENTRY (tcp_writealot) +#endif TEST_HELPER (tcp_writealot, tcp4_echo_server) TEST_ENTRY (tcp_write_fail) @@ -501,6 +524,7 @@ TASK_LIST_START TEST_ENTRY (udp_create_early_bad_bind) TEST_ENTRY (udp_create_early_bad_domain) TEST_ENTRY (udp_send_and_recv) + TEST_ENTRY (udp_send_hang_loop) TEST_ENTRY (udp_send_immediate) TEST_ENTRY (udp_send_unreachable) TEST_ENTRY (udp_dgram_too_big) @@ -548,6 +572,8 @@ TASK_LIST_START TEST_ENTRY (callback_stack) TEST_HELPER (callback_stack, tcp4_echo_server) + TEST_ENTRY (env_vars) + TEST_ENTRY (error_message) TEST_ENTRY (sys_error) @@ -635,6 +661,8 @@ TASK_LIST_START TEST_ENTRY (getaddrinfo_basic_sync) TEST_ENTRY (getaddrinfo_concurrent) + TEST_ENTRY (gethostname) + TEST_ENTRY (getnameinfo_basic_ip4) TEST_ENTRY (getnameinfo_basic_ip4_sync) TEST_ENTRY (getnameinfo_basic_ip6) @@ -704,6 +732,8 @@ TASK_LIST_START TEST_ENTRY (spawn_setuid_setgid) TEST_ENTRY (we_get_signal) TEST_ENTRY (we_get_signals) + TEST_ENTRY (we_get_signal_one_shot) + TEST_ENTRY (we_get_signals_mixed) TEST_ENTRY (signal_multiple_loops) TEST_ENTRY (closed_fd_events) #endif @@ -745,6 +775,7 @@ TASK_LIST_START #ifdef _WIN32 TEST_ENTRY (fs_event_watch_file_root_dir) #endif + TEST_ENTRY (fs_event_watch_invalid_path) TEST_ENTRY (fs_event_no_callback_after_close) TEST_ENTRY (fs_event_no_callback_on_close) TEST_ENTRY (fs_event_immediate_close) @@ -762,6 +793,7 @@ TASK_LIST_START TEST_ENTRY (fs_write_alotof_bufs) TEST_ENTRY (fs_write_alotof_bufs_with_offset) TEST_ENTRY (fs_read_write_null_arguments) + TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) #if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */ @@ -790,6 +822,18 @@ TASK_LIST_START TEST_ENTRY (queue_foreach_delete) +#ifndef _WIN32 + TEST_ENTRY (fork_timer) + TEST_ENTRY (fork_socketpair) + TEST_ENTRY (fork_socketpair_started) + TEST_ENTRY (fork_signal_to_child) + TEST_ENTRY (fork_signal_to_child_closed) + TEST_ENTRY (fork_fs_events_child) + TEST_ENTRY (fork_fs_events_child_dir) + TEST_ENTRY (fork_fs_events_file_parent_child) + TEST_ENTRY (fork_threadpool_queue_work_simple) +#endif + #if 0 /* These are for testing the test runner. */ TEST_ENTRY (fail_always) diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index c074178541b0a3..bdc967151ed8f2 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -27,7 +27,11 @@ static int completed_pingers = 0; +#if defined(__CYGWIN__) || defined(__MSYS__) +#define NUM_PINGS 100 /* fewer pings to avoid timeout */ +#else #define NUM_PINGS 1000 +#endif /* 64 bytes is enough for a pinger */ #define BUFSIZE 10240 diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c index 38b57db6991fbc..9cf93165e41301 100644 --- a/deps/uv/test/test-pipe-bind-error.c +++ b/deps/uv/test/test-pipe-bind-error.c @@ -116,6 +116,9 @@ TEST_IMPL(pipe_bind_error_inval) { TEST_IMPL(pipe_listen_without_bind) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_pipe_t server; int r; diff --git a/deps/uv/test/test-pipe-connect-multiple.c b/deps/uv/test/test-pipe-connect-multiple.c index 3de5a9a0bf4e83..0a60d4a9642433 100644 --- a/deps/uv/test/test-pipe-connect-multiple.c +++ b/deps/uv/test/test-pipe-connect-multiple.c @@ -70,6 +70,9 @@ static void connect_cb(uv_connect_t* connect_req, int status) { TEST_IMPL(pipe_connect_multiple) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif int i; int r; uv_loop_t* loop; diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c index 4b4ceccc45ced5..d1628a67d5d032 100644 --- a/deps/uv/test/test-pipe-getsockname.c +++ b/deps/uv/test/test-pipe-getsockname.c @@ -87,6 +87,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) { TEST_IMPL(pipe_getsockname) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_loop_t* loop; char buf[1024]; size_t len; diff --git a/deps/uv/test/test-pipe-sendmsg.c b/deps/uv/test/test-pipe-sendmsg.c index f6d893b449433a..3bf427f8aa0634 100644 --- a/deps/uv/test/test-pipe-sendmsg.c +++ b/deps/uv/test/test-pipe-sendmsg.c @@ -102,6 +102,9 @@ static void read_cb(uv_stream_t* handle, TEST_IMPL(pipe_sendmsg) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif uv_pipe_t p; int r; int fds[2]; diff --git a/deps/uv/test/test-pipe-server-close.c b/deps/uv/test/test-pipe-server-close.c index 1dcdfffaf7cb2d..ea9977dd843e2a 100644 --- a/deps/uv/test/test-pipe-server-close.c +++ b/deps/uv/test/test-pipe-server-close.c @@ -61,6 +61,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) { TEST_IMPL(pipe_server_close) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_loop_t* loop; int r; diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index b8955080104756..72c176edc459fb 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -47,8 +47,12 @@ TEST_IMPL(platform_output) { printf("uv_cwd: %s\n", buffer); err = uv_resident_set_memory(&rss); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else ASSERT(err == 0); printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss); +#endif err = uv_uptime(&uptime); ASSERT(err == 0); @@ -73,6 +77,9 @@ TEST_IMPL(platform_output) { (unsigned long long) rusage.ru_maxrss); err = uv_cpu_info(&cpus, &count); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else ASSERT(err == 0); printf("uv_cpu_info:\n"); @@ -88,6 +95,7 @@ TEST_IMPL(platform_output) { printf(" times.nice: %llu\n", (unsigned long long) cpus[i].cpu_times.nice); } +#endif uv_free_cpu_info(cpus, count); err = uv_interface_addresses(&interfaces, &count); diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c index 6c1f98b7eff552..7cfc159a2b3d03 100644 --- a/deps/uv/test/test-poll.c +++ b/deps/uv/test/test-poll.c @@ -574,6 +574,9 @@ static void start_poll_test(void) { TEST_IMPL(poll_duplex) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif test_mode = DUPLEX; start_poll_test(); return 0; @@ -581,6 +584,9 @@ TEST_IMPL(poll_duplex) { TEST_IMPL(poll_unidirectional) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif test_mode = UNIDIRECTIONAL; start_poll_test(); return 0; @@ -594,7 +600,8 @@ TEST_IMPL(poll_unidirectional) { */ TEST_IMPL(poll_bad_fdtype) { #if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \ - !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) + !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) && \ + !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__MSYS__) uv_poll_t poll_handle; int fd; diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c index 5d5ede9d60291c..886f83a7d30fe1 100644 --- a/deps/uv/test/test-process-title.c +++ b/deps/uv/test/test-process-title.c @@ -41,7 +41,7 @@ static void set_title(const char* title) { } -static void uv_get_process_title_edge_cases() { +static void uv_get_process_title_edge_cases(void) { char buffer[512]; int r; @@ -60,7 +60,7 @@ static void uv_get_process_title_edge_cases() { TEST_IMPL(process_title) { -#if defined(__sun) +#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) RETURN_SKIP("uv_(get|set)_process_title is not implemented."); #else /* Check for format string vulnerabilities. */ diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c index 39f4b0fc739174..05728c83365bfe 100644 --- a/deps/uv/test/test-ref.c +++ b/deps/uv/test/test-ref.c @@ -194,8 +194,8 @@ TEST_IMPL(timer_ref2) { TEST_IMPL(fs_event_ref) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_fs_event_t h; uv_fs_event_init(uv_default_loop(), &h); diff --git a/deps/uv/test/test-shutdown-twice.c b/deps/uv/test/test-shutdown-twice.c index 75c054354995b3..d7aae89914dad6 100644 --- a/deps/uv/test/test-shutdown-twice.c +++ b/deps/uv/test/test-shutdown-twice.c @@ -67,6 +67,7 @@ TEST_IMPL(shutdown_twice) { loop = uv_default_loop(); r = uv_tcp_init(loop, &h); + ASSERT(r == 0); r = uv_tcp_connect(&connect_req, &h, diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c index 158129919bd772..11193dcf50b227 100644 --- a/deps/uv/test/test-signal-multiple-loops.c +++ b/deps/uv/test/test-signal-multiple-loops.c @@ -193,6 +193,13 @@ static void loop_creating_worker(void* context) { TEST_IMPL(signal_multiple_loops) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: This test needs more investigation. Somehow the `read` in + uv__signal_lock fails spuriously with EACCES or even EAGAIN even + though it is supposed to be blocking. Also the test hangs during + thread setup occasionally. */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS]; uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS]; enum signal_action action; diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c index c0424c60a0995e..9a881510c72151 100644 --- a/deps/uv/test/test-signal.c +++ b/deps/uv/test/test-signal.c @@ -70,17 +70,17 @@ struct timer_ctx { }; struct signal_ctx { - enum { CLOSE, STOP } stop_or_close; + enum { CLOSE, STOP, NOOP } stop_or_close; unsigned int ncalls; uv_signal_t handle; int signum; + int one_shot; }; static void signal_cb(uv_signal_t* handle, int signum) { struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); ASSERT(signum == ctx->signum); - if (++ctx->ncalls == NSIGNALS) { if (ctx->stop_or_close == STOP) uv_signal_stop(handle); @@ -91,6 +91,14 @@ static void signal_cb(uv_signal_t* handle, int signum) { } } +static void signal_cb_one_shot(uv_signal_t* handle, int signum) { + struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); + ASSERT(signum == ctx->signum); + ASSERT(++ctx->ncalls == 1); + if (ctx->stop_or_close == CLOSE) + uv_close((uv_handle_t*)handle, NULL); +} + static void timer_cb(uv_timer_t* handle) { struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle); @@ -102,15 +110,21 @@ static void timer_cb(uv_timer_t* handle) { } -static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) { +static void start_watcher(uv_loop_t* loop, + int signum, + struct signal_ctx* ctx, + int one_shot) { ctx->ncalls = 0; ctx->signum = signum; ctx->stop_or_close = CLOSE; + ctx->one_shot = one_shot; ASSERT(0 == uv_signal_init(loop, &ctx->handle)); - ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); + if (one_shot) + ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum)); + else + ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); } - static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) { ctx->ncalls = 0; ctx->signum = signum; @@ -126,7 +140,7 @@ TEST_IMPL(we_get_signal) { loop = uv_default_loop(); start_timer(loop, SIGCHLD, &tc); - start_watcher(loop, SIGCHLD, &sc); + start_watcher(loop, SIGCHLD, &sc, 0); sc.stop_or_close = STOP; /* stop, don't close the signal handle */ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); ASSERT(tc.ncalls == NSIGNALS); @@ -158,10 +172,10 @@ TEST_IMPL(we_get_signals) { unsigned int i; loop = uv_default_loop(); - start_watcher(loop, SIGUSR1, sc + 0); - start_watcher(loop, SIGUSR1, sc + 1); - start_watcher(loop, SIGUSR2, sc + 2); - start_watcher(loop, SIGUSR2, sc + 3); + start_watcher(loop, SIGUSR1, sc + 0, 0); + start_watcher(loop, SIGUSR1, sc + 1, 0); + start_watcher(loop, SIGUSR2, sc + 2, 0); + start_watcher(loop, SIGUSR2, sc + 3, 0); start_timer(loop, SIGUSR1, tc + 0); start_timer(loop, SIGUSR2, tc + 1); ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); @@ -176,4 +190,116 @@ TEST_IMPL(we_get_signals) { return 0; } +TEST_IMPL(we_get_signal_one_shot) { + struct signal_ctx sc; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, &sc, 1); + sc.stop_or_close = NOOP; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(sc.ncalls == 1); + + sc.ncalls = 0; + sc.stop_or_close = CLOSE; /* now close it when it's done */ + uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD); + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(we_get_signals_mixed) { + struct signal_ctx sc[4]; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* 2 one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + + /* 2 one-shot, 1 normal then remove normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 0); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 1 one-shot then remove one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 1); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == NSIGNALS); + ASSERT(sc[1].ncalls == NSIGNALS); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 2 one-shot then remove 2 normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + start_watcher(loop, SIGCHLD, sc + 2, 1); + start_watcher(loop, SIGCHLD, sc + 3, 1); + sc[2].stop_or_close = CLOSE; + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[1]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 0); + ASSERT(sc[2].ncalls == 1); + ASSERT(sc[2].ncalls == 1); + + /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 1); + start_watcher(loop, SIGCHLD, sc + 2, 0); + start_watcher(loop, SIGCHLD, sc + 3, 0); + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + ASSERT(sc[3].ncalls == NSIGNALS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + #endif /* _WIN32 */ diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 53a036969b6252..52fc7f6cc5e95d 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -90,7 +90,16 @@ static void kill_cb(uv_process_t* process, #else ASSERT(exit_status == 0); #endif - ASSERT(no_term_signal || term_signal == 15); +#if defined(__APPLE__) + /* + * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a + * process that is still starting up kills it with SIGKILL instead of SIGTERM. + * See: https://github.com/libuv/libuv/issues/1226 + */ + ASSERT(no_term_signal || term_signal == SIGTERM || term_signal == SIGKILL); +#else + ASSERT(no_term_signal || term_signal == SIGTERM); +#endif uv_close((uv_handle_t*)process, close_cb); /* @@ -1288,7 +1297,11 @@ TEST_IMPL(spawn_setuid_fails) { options.uid = 0; r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) + ASSERT(r == UV_EINVAL); +#else ASSERT(r == UV_EPERM); +#endif r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(r == 0); @@ -1319,7 +1332,11 @@ TEST_IMPL(spawn_setgid_fails) { options.gid = 0; r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) + ASSERT(r == UV_EINVAL); +#else ASSERT(r == UV_EPERM); +#endif r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(r == 0); @@ -1528,6 +1545,17 @@ TEST_IMPL(spawn_reads_child_path) { exepath[len] = 0; strcpy(path, "PATH="); strcpy(path + 5, exepath); +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Carry over the dynamic linker path in case the test runner + is linked against cyguv-1.dll or msys-uv-1.dll, see above. */ + { + char* syspath = getenv("PATH"); + if (syspath != NULL) { + strcat(path, ":"); + strcat(path, syspath); + } + } +#endif env[0] = path; env[1] = getenv(dyld_path_var); diff --git a/deps/uv/test/test-tcp-create-socket-early.c b/deps/uv/test/test-tcp-create-socket-early.c index 1a508e474aa700..b87e7324184be1 100644 --- a/deps/uv/test/test-tcp-create-socket-early.c +++ b/deps/uv/test/test-tcp-create-socket-early.c @@ -164,7 +164,7 @@ TEST_IMPL(tcp_create_early_bad_bind) { #endif r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) ASSERT(r == UV_EINVAL); #else ASSERT(r == UV_EFAULT); diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c index d50289c3c26fe1..5119be6d330932 100644 --- a/deps/uv/test/test-tcp-write-queue-order.c +++ b/deps/uv/test/test-tcp-write-queue-order.c @@ -89,6 +89,9 @@ static void connection_cb(uv_stream_t* tcp, int status) { ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_cb, 1, 0)); + connection_cb_called++; } @@ -120,9 +123,6 @@ TEST_IMPL(tcp_write_queue_order) { connect_cb)); ASSERT(0 == uv_send_buffer_size((uv_handle_t*) &client, &buffer_size)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb, 100, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); ASSERT(connect_cb_called == 1); diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c index 917f5f475160aa..dd13d8ae4bf1fa 100644 --- a/deps/uv/test/test-threadpool-cancel.c +++ b/deps/uv/test/test-threadpool-cancel.c @@ -60,7 +60,10 @@ static void saturate_threadpool(void) { char buf[64]; size_t i; - snprintf(buf, sizeof(buf), "UV_THREADPOOL_SIZE=%zu", ARRAY_SIZE(pause_reqs)); + snprintf(buf, + sizeof(buf), + "UV_THREADPOOL_SIZE=%lu", + (unsigned long)ARRAY_SIZE(pause_reqs)); putenv(buf); loop = uv_default_loop(); diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c index 6fc2c95c98590c..e761822fa349fc 100644 --- a/deps/uv/test/test-tty.c +++ b/deps/uv/test/test-tty.c @@ -244,7 +244,7 @@ TEST_IMPL(tty_empty_write) { ASSERT(r == 0); bufs[0].len = 0; - bufs[0].base = &dummy; + bufs[0].base = &dummy[0]; r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1); ASSERT(r == 0); diff --git a/deps/uv/test/test-udp-create-socket-early.c b/deps/uv/test/test-udp-create-socket-early.c index 3f3027404700f4..f7e46abc98da54 100644 --- a/deps/uv/test/test-udp-create-socket-early.c +++ b/deps/uv/test/test-udp-create-socket-early.c @@ -104,7 +104,7 @@ TEST_IMPL(udp_create_early_bad_bind) { #endif r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) ASSERT(r == UV_EINVAL); #else ASSERT(r == UV_EFAULT); diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c index a65f09e0c6d765..54b364da9ebc75 100644 --- a/deps/uv/test/test-udp-ipv6.c +++ b/deps/uv/test/test-udp-ipv6.c @@ -163,6 +163,11 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) { TEST_IMPL(udp_dual_stack) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif + if (!can_ipv6()) RETURN_SKIP("IPv6 not supported"); diff --git a/deps/uv/test/test-udp-send-hang-loop.c b/deps/uv/test/test-udp-send-hang-loop.c new file mode 100644 index 00000000000000..6253ff7a4134c0 --- /dev/null +++ b/deps/uv/test/test-udp-send-hang-loop.c @@ -0,0 +1,99 @@ +/* Copyright The libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_OBJECT(handle, type, parent) \ + ASSERT((type*)(handle) == &(parent)) + +static uv_udp_t client; +static uv_idle_t idle_handle; +static uv_udp_send_t send_req; +static uv_buf_t buf; +static struct sockaddr_in addr; +static char send_data[1024]; + +static int loop_hang_called; + +static void send_cb(uv_udp_send_t* req, int status); + + +static void idle_cb(uv_idle_t* handle) { + int r; + + ASSERT(send_req.handle == NULL); + CHECK_OBJECT(handle, uv_idle_t, idle_handle); + ASSERT(0 == uv_idle_stop(handle)); + + /* It probably would have stalled by now if it's going to stall at all. */ + if (++loop_hang_called > 1000) { + uv_close((uv_handle_t*) &client, NULL); + uv_close((uv_handle_t*) &idle_handle, NULL); + return; + } + + r = uv_udp_send(&send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); +} + + +static void send_cb(uv_udp_send_t* req, int status) { + ASSERT(req != NULL); + ASSERT(status == 0); + CHECK_OBJECT(req->handle, uv_udp_t, client); + CHECK_OBJECT(req, uv_udp_send_t, send_req); + req->handle = NULL; + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); +} + + +TEST_IMPL(udp_send_hang_loop) { + ASSERT(0 == uv_idle_init(uv_default_loop(), &idle_handle)); + + /* 192.0.2.0/8 is "TEST-NET" and reserved for documentation. + * Good for us, though. Since we want to have something unreachable. + */ + ASSERT(0 == uv_ip4_addr("192.0.2.3", TEST_PORT, &addr)); + + ASSERT(0 == uv_udp_init(uv_default_loop(), &client)); + + buf = uv_buf_init(send_data, sizeof(send_data)); + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(loop_hang_called > 1000); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-udp-send-immediate.c b/deps/uv/test/test-udp-send-immediate.c index 0999f6b3425286..215f72257233a1 100644 --- a/deps/uv/test/test-udp-send-immediate.c +++ b/deps/uv/test/test-udp-send-immediate.c @@ -136,6 +136,7 @@ TEST_IMPL(udp_send_immediate) { 1, (const struct sockaddr*) &addr, cl_send_cb); + ASSERT(r == 0); uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c index 6ff48d44c88178..29a82a5c374029 100644 --- a/deps/uv/test/test-watcher-cross-stop.c +++ b/deps/uv/test/test-watcher-cross-stop.c @@ -26,7 +26,12 @@ #include /* NOTE: Number should be big enough to trigger this problem */ +#if defined(__CYGWIN__) || defined(__MSYS__) +/* Cygwin crashes or hangs in socket() with too many AF_INET sockets. */ +static uv_udp_t sockets[1250]; +#else static uv_udp_t sockets[2500]; +#endif static uv_udp_send_t reqs[ARRAY_SIZE(sockets)]; static char slab[1]; static unsigned int recv_cb_called; diff --git a/deps/uv/tools/make_dist_html.py b/deps/uv/tools/make_dist_html.py new file mode 100644 index 00000000000000..7a19d3e1151fb8 --- /dev/null +++ b/deps/uv/tools/make_dist_html.py @@ -0,0 +1,124 @@ +#!/usr/bin/python + +from __future__ import print_function + +import itertools +import os +import re +import subprocess + +HTML = r''' + + + + + + + + + {groups}
+ + +''' + +GROUPS = r''' + + {groups[0]} + {groups[1]} + {groups[2]} + {groups[3]} + +''' + +GROUP = r''' + + + + + + + + {rows} +
versiontarballgpgwindows
+''' + +ROW = r''' + + + {tag} + + + tarball + + {maybe_gpg} + {maybe_exe} + +''' + +GPG = r''' +gpg +''' + +# The binaries don't have a predictable name, link to the directory instead. +EXE = r''' +exe +''' + +def version(tag): + return map(int, re.match('^v(\d+)\.(\d+)\.(\d+)', tag).groups()) + +def major_minor(tag): + return version(tag)[:2] + +def row_for(tag): + maybe_gpg = '' + maybe_exe = '' + # We didn't start signing releases and producing Windows installers + # until v1.7.0. + if version(tag) >= version('v1.7.0'): + maybe_gpg = GPG.format(**locals()) + maybe_exe = EXE.format(**locals()) + return ROW.format(**locals()) + +def group_for(tags): + rows = ''.join(row_for(tag) for tag in tags) + return GROUP.format(rows=rows) + +# Partition in groups of |n|. +def groups_for(groups, n=4): + html = '' + groups = groups[:] + [''] * (n - 1) + while len(groups) >= n: + html += GROUPS.format(groups=groups) + groups = groups[n:] + return html + +if __name__ == '__main__': + os.chdir(os.path.dirname(__file__)) + tags = subprocess.check_output(['git', 'tag']) + tags = [tag for tag in tags.split('\n') if tag.startswith('v')] + tags.sort(key=version, reverse=True) + groups = [group_for(list(g)) for _, g in itertools.groupby(tags, major_minor)] + groups = groups_for(groups) + html = HTML.format(groups=groups).strip() + html = re.sub('>\\s+<', '><', html) + print(html) diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 49d5d22f96784b..a3a42787b37b78 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -36,7 +36,7 @@ ], 'xcode_settings': { 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ], + 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter', '-Wstrict-prototypes' ], 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], } }, @@ -210,6 +210,7 @@ '-Wall', '-Wextra', '-Wno-unused-parameter', + '-Wstrict-prototypes', ], }], [ 'OS in "mac ios"', { @@ -236,6 +237,9 @@ 'src/unix/linux-inotify.c', 'src/unix/linux-syscalls.c', 'src/unix/linux-syscalls.h', + 'src/unix/procfs-exepath.c', + 'src/unix/sysinfo-loadavg.c', + 'src/unix/sysinfo-memory.c', ], 'link_settings': { 'libraries': [ '-ldl', '-lrt' ], @@ -250,13 +254,19 @@ 'src/unix/pthread-fixes.c', 'src/unix/android-ifaddrs.c', 'src/unix/pthread-barrier.c' + 'src/unix/procfs-exepath.c', + 'src/unix/sysinfo-loadavg.c', + 'src/unix/sysinfo-memory.c', ], 'link_settings': { 'libraries': [ '-ldl' ], }, }], [ 'OS=="solaris"', { - 'sources': [ 'src/unix/sunos.c' ], + 'sources': [ + 'src/unix/no-proctitle.c', + 'src/unix/sunos.c', + ], 'defines': [ '__EXTENSIONS__', '_XOPEN_SOURCE=500', @@ -298,9 +308,13 @@ 'link_settings': { 'libraries': [ '-lkvm' ], }, + 'sources': [ 'src/unix/posix-hrtime.c' ], }], [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', { - 'sources': [ 'src/unix/kqueue.c' ], + 'sources': [ + 'src/unix/bsd-ifaddrs.c', + 'src/unix/kqueue.c', + ], }], ['uv_library=="shared_library"', { 'defines': [ 'BUILDING_UV_SHARED=1' ] @@ -309,6 +323,7 @@ 'sources': [ 'src/unix/pthread-fixes.c', 'src/unix/pthread-barrier.c', + 'src/unix/no-fsevents.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c' ] @@ -343,13 +358,16 @@ 'test/test-error.c', 'test/test-embed.c', 'test/test-emfile.c', + 'test/test-env-vars.c', 'test/test-fail-always.c', + 'test/test-fork.c', 'test/test-fs.c', 'test/test-fs-event.c', 'test/test-get-currentexe.c', 'test/test-get-memory.c', 'test/test-get-passwd.c', 'test/test-getaddrinfo.c', + 'test/test-gethostname.c', 'test/test-getnameinfo.c', 'test/test-getsockname.c', 'test/test-handle-fileno.c', @@ -445,6 +463,7 @@ 'test/test-udp-open.c', 'test/test-udp-options.c', 'test/test-udp-send-and-recv.c', + 'test/test-udp-send-hang-loop.c', 'test/test-udp-send-immediate.c', 'test/test-udp-send-unreachable.c', 'test/test-udp-multicast-join.c', From 3ac769091ca4ad040ababc6a122a3bc00999c94d Mon Sep 17 00:00:00 2001 From: cjihrig Date: Mon, 5 Jun 2017 10:25:22 -0400 Subject: [PATCH 024/128] gitignore: add libuv book and GitHub template PR-URL: https://github.com/nodejs/node/pull/13306 Reviewed-By: Santiago Gimeno Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index b4ba0e2983f12c..dea969504a90f1 100644 --- a/.gitignore +++ b/.gitignore @@ -110,3 +110,8 @@ icu_config.gypi # Xcode workspaces and project folders *.xcodeproj *.xcworkspace + +# libuv book and GitHub template +deps/uv/.github/ +deps/uv/docs/code/ +deps/uv/docs/src/guide/ From a38755d0a445c3b31deed2193dfcc3de1fd813b5 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 6 Jul 2017 19:12:45 -0400 Subject: [PATCH 025/128] deps: upgrade libuv to 1.13.1 PR-URL: https://github.com/nodejs/node/pull/14117 Reviewed-By: Refael Ackermann Reviewed-By: Daniel Bevenius Reviewed-By: James M Snell --- deps/uv/.mailmap | 1 + deps/uv/AUTHORS | 7 + deps/uv/ChangeLog | 56 +++++++ deps/uv/README.md | 163 ++++++++++++++------ deps/uv/appveyor.yml | 2 +- deps/uv/common.gypi | 12 +- deps/uv/configure.ac | 6 +- deps/uv/include/uv-version.h | 4 +- deps/uv/src/unix/aix.c | 1 + deps/uv/src/unix/atomic-ops.h | 5 +- deps/uv/src/unix/core.c | 5 +- deps/uv/src/unix/freebsd.c | 35 ++--- deps/uv/src/unix/os390.c | 8 +- deps/uv/src/unix/process.c | 28 ++++ deps/uv/src/unix/proctitle.c | 4 +- deps/uv/src/unix/stream.c | 32 ++-- deps/uv/src/unix/sunos.c | 3 +- deps/uv/src/win/fs.c | 24 +++ deps/uv/src/win/pipe.c | 47 +++--- deps/uv/src/win/udp.c | 46 +++++- deps/uv/test/run-tests.c | 5 + deps/uv/test/runner-unix.c | 6 +- deps/uv/test/test-async-null-cb.c | 9 ++ deps/uv/test/test-fs.c | 40 +++++ deps/uv/test/test-ipc.c | 96 ++++++++++++ deps/uv/test/test-list.h | 8 + deps/uv/test/test-spawn.c | 21 +++ deps/uv/test/test-udp-try-send.c | 12 -- deps/uv/tools/vswhere_usability_wrapper.cmd | 33 ++++ deps/uv/uv.gyp | 8 +- deps/uv/vcbuild.bat | 30 +++- 31 files changed, 618 insertions(+), 139 deletions(-) create mode 100644 deps/uv/tools/vswhere_usability_wrapper.cmd diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index 618274c0d2e242..896d4065bc486e 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -41,3 +41,4 @@ Yasuhiro Matsumoto Yazhong Liu Yuki Okumura jBarz +jBarz diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index ab4e099f167379..4ef241092701d2 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -292,3 +292,10 @@ Keane James McCoy Bernardo Ramos Juan Cruz Viotti +Gemini Wen +Sebastian Wiedenroth +Sai Ke WANG +Barnabas Gema +Romain Caire +Robert Ayrapetyan +Refael Ackermann diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 71b210f44bddf1..67c99df82eaee7 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,59 @@ +2017.07.07, Version 1.13.1 (Stable), 2bb4b68758f07cd8617838e68c44c125bc567ba6 + +Changes since version 1.13.0: + +* Now working on version 1.13.1 (cjihrig) + +* build: workaround AppVeyor quirk (Refael Ackermann) + + +2017.07.06, Version 1.13.0 (Stable), 8342fcaab815f33b988c1910ea988f28dfe27edb + +Changes since version 1.12.0: + +* Now working on version 1.12.1 (cjihrig) + +* unix: avoid segfault in uv_get_process_title (Michele Caini) + +* build: add a comma to uv.gyp (Gemini Wen) + +* win: restore file pos after positional read/write (Bartosz Sosnowski) + +* unix,stream: return error on closed handle passing (Santiago Gimeno) + +* unix,benchmark: use fd instead of FILE* after fork (jBarz) + +* zos: avoid compiler warnings (jBarz) + +* win,pipe: race condition canceling readfile thread (Jameson Nash) + +* sunos: filter out non-IPv4/IPv6 interfaces (Sebastian Wiedenroth) + +* sunos: fix cmpxchgi and cmpxchgl type error (Sai Ke WANG) + +* unix: reset signal disposition before execve() (Ben Noordhuis) + +* unix: reset signal mask before execve() (Ben Noordhuis) + +* unix: fix POLLIN assertion on server read (jBarz) + +* zos: use stckf builtin for high-res timer (jBarz) + +* win,udp: implements uv_udp_try_send (Barnabas Gema) + +* win,udp: return UV_EINVAL instead of aborting (Romain Caire) + +* freebsd: replace kvm with sysctl (Robert Ayrapetyan) + +* aix: fix un-initialized pointer field in fs handle (Gireesh Punathil) + +* win,build: support building with VS2017 (Refael Ackermann) + +* doc: add instructions for building on Windows (Refael Ackermann) + +* doc: format README (Refael Ackermann) + + 2017.05.31, Version 1.12.0 (Stable), d6ac141ac674657049598c36604f26e031fae917 Changes since version 1.11.0: diff --git a/deps/uv/README.md b/deps/uv/README.md index e5d94faf0fa38e..372d514e049c39 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -3,7 +3,7 @@ ## Overview libuv is a multi-platform support library with a focus on asynchronous I/O. It -was primarily developed for use by [Node.js](http://nodejs.org), but it's also +was primarily developed for use by [Node.js][], but it's also used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/), [pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/wiki/Projects-that-use-libuv). @@ -62,24 +62,34 @@ formats. Show different supported building options: - $ make help +```bash +$ make help +``` Build documentation as HTML: - $ make html +```bash +$ make html +``` Build documentation as HTML and live reload it when it changes (this requires sphinx-autobuild to be installed and is only supported on Unix): - $ make livehtml +```bash +$ make livehtml +``` Build documentation as man pages: - $ make man +```bash +$ make man +``` Build documentation as ePub: - $ make epub +```bash +$ make epub +``` NOTE: Windows users need to use make.bat instead of plain 'make'. @@ -116,25 +126,32 @@ file, but are also available as git blob objects for easier use. Importing a key the usual way: - $ gpg --keyserver pool.sks-keyservers.net \ - --recv-keys AE9BC059 +```bash +$ gpg --keyserver pool.sks-keyservers.net --recv-keys AE9BC059 +``` Importing a key from a git blob object: - $ git show pubkey-saghul | gpg --import +```bash +$ git show pubkey-saghul | gpg --import +``` ### Verifying releases Git tags are signed with the developer's key, they can be verified as follows: - $ git verify-tag v1.6.1 +```bash +$ git verify-tag v1.6.1 +``` Starting with libuv 1.7.0, the tarballs stored in the [downloads site](http://dist.libuv.org/dist/) are signed and an accompanying signature file sit alongside each. Once both the release tarball and the signature file are downloaded, the file can be verified as follows: - $ gpg --verify libuv-1.7.0.tar.gz.sign +```bash +$ gpg --verify libuv-1.7.0.tar.gz.sign +``` ## Build Instructions @@ -144,38 +161,82 @@ backends. It is best used for integration into other projects. To build with autotools: - $ sh autogen.sh - $ ./configure - $ make - $ make check - $ make install +```bash +$ sh autogen.sh +$ ./configure +$ make +$ make check +$ make install +``` ### Windows -First, [Python][] 2.6 or 2.7 must be installed as it is required by [GYP][]. -If python is not in your path, set the environment variable `PYTHON` to its -location. For example: `set PYTHON=C:\Python27\python.exe` +Prerequisites: + +* [Python 2.6 or 2.7][] as it is required + by [GYP][]. + If python is not in your path, set the environment variable `PYTHON` to its + location. For example: `set PYTHON=C:\Python27\python.exe` +* One of: + * [Visual C++ Build Tools][] + * [Visual Studio 2015 Update 3][], all editions + including the Community edition (remember to select + "Common Tools for Visual C++ 2015" feature during installation). + * [Visual Studio 2017][], any edition (including the Build Tools SKU). + **Required Components:** "MSbuild", "VC++ 2017 v141 toolset" and one of the + Windows SDKs (10 or 8.1). +* Basic Unix tools required for some tests, + [Git for Windows][] includes Git Bash + and tools which can be included in the global `PATH`. + +To build, launch a git shell (e.g. Cmd or PowerShell), run `vcbuild.bat` +(to build with VS2017 you need to explicitly add a `vs2017` argument), +which will checkout the GYP code into `build/gyp`, generate `uv.sln` +as well as the necesery related project files, and start building. + +```console +> vcbuild +``` + +Or: + +```console +> vcbuild vs2017 +``` + +To run the tests: + +```console +> vcbuild test +``` + +To see all the options that could passed to `vcbuild`: + +```console +> vcbuild help +vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared] +Examples: + vcbuild.bat : builds debug build + vcbuild.bat test : builds debug build and runs tests + vcbuild.bat release bench: builds release build and runs benchmarks +``` -To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell) -and run vcbuild.bat which will checkout the GYP code into build/gyp and -generate uv.sln as well as related project files. - -To have GYP generate build script for another system, checkout GYP into the -project tree manually: - - $ git clone https://chromium.googlesource.com/external/gyp.git build/gyp ### Unix For Debug builds (recommended) run: - $ ./gyp_uv.py -f make - $ make -C out +```bash +$ ./gyp_uv.py -f make +$ make -C out +``` For Release builds run: - $ ./gyp_uv.py -f make - $ BUILDTYPE=Release make -C out +```bash +$ ./gyp_uv.py -f make +$ BUILDTYPE=Release make -C out +``` Run `./gyp_uv.py -f make -Dtarget_arch=x32` to build [x32][] binaries. @@ -183,13 +244,17 @@ Run `./gyp_uv.py -f make -Dtarget_arch=x32` to build [x32][] binaries. Run: - $ ./gyp_uv.py -f xcode - $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \ - -configuration Release -target All +```bash +$ ./gyp_uv.py -f xcode +$ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \ + -configuration Release -target All +``` Using Homebrew: - $ brew install --HEAD libuv +```bash +$ brew install --HEAD libuv +``` Note to OS X users: @@ -201,8 +266,10 @@ Make sure that you specify the architecture you wish to build for in the Run: - $ source ./android-configure NDK_PATH gyp - $ make -C out +```bash +$ source ./android-configure NDK_PATH gyp +$ make -C out +``` Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and `-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically. @@ -211,18 +278,22 @@ Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and To use ninja for build on ninja supported platforms, run: - $ ./gyp_uv.py -f ninja - $ ninja -C out/Debug #for debug build OR - $ ninja -C out/Release +```bash +$ ./gyp_uv.py -f ninja +$ ninja -C out/Debug #for debug build OR +$ ninja -C out/Release +``` ### Running tests Run: - $ ./gyp_uv.py -f make - $ make -C out - $ ./out/Debug/run-tests +```bash +$ ./gyp_uv.py -f make +$ make -C out +$ ./out/Debug/run-tests +``` ## Supported Platforms @@ -244,7 +315,11 @@ See the [guidelines for contributing][]. [node.js]: http://nodejs.org/ [GYP]: http://code.google.com/p/gyp/ -[Python]: https://www.python.org/downloads/ [guidelines for contributing]: https://github.com/libuv/libuv/blob/master/CONTRIBUTING.md [libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png [x32]: https://en.wikipedia.org/wiki/X32_ABI +[Python 2.6 or 2.7]: https://www.python.org/downloads/ +[Visual C++ Build Tools]: http://landinghub.visualstudio.com/visual-cpp-build-tools +[Visual Studio 2015 Update 3]: https://www.visualstudio.com/vs/older-downloads/ +[Visual Studio 2017]: https://www.visualstudio.com/downloads/ +[Git for Windows]: http://git-scm.com/download/win diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index c542e34b991168..be90ef7b435c74 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -1,4 +1,4 @@ -version: v1.12.0.build{build} +version: v1.13.1.build{build} install: - cinst -y nsis diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi index 94e760030335bc..ec482340c27b47 100644 --- a/deps/uv/common.gypi +++ b/deps/uv/common.gypi @@ -49,9 +49,6 @@ 'cflags': [ '-O3', '-fstrict-aliasing', - '-fomit-frame-pointer', - '-fdata-sections', - '-ffunction-sections', ], 'msvs_settings': { 'VCCLCompilerTool': { @@ -82,6 +79,15 @@ 'LinkIncremental': 1, # disable incremental linking }, }, + 'conditions': [ + ['OS != "os390"', { + 'cflags': [ + '-fomit-frame-pointer', + '-fdata-sections', + '-ffunction-sections', + ], + }], + ] } }, 'msvs_settings': { diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 8ac06f7fc8c84e..a52cfc622cbb5f 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.12.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.13.1], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -66,9 +66,7 @@ AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false]) AS_CASE([$host_os],[mingw*], [ LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32" ]) -AS_CASE([$host_os], [openbsd*], [], [ - AC_CHECK_LIB([kvm], [kvm_open]) -]) +AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])]) AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index 34d4a43f9e5f22..c80c40ea7f1bb0 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 12 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 13 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 388c9cca9707ee..426f7f4735fd39 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -855,6 +855,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup(filename); handle->cb = cb; + handle->dir_filename = NULL; uv__io_start(handle->loop, &handle->event_watcher, POLLIN); diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h index 9dac2557f867e5..7cac1f98890d77 100644 --- a/deps/uv/src/unix/atomic-ops.h +++ b/deps/uv/src/unix/atomic-ops.h @@ -20,7 +20,6 @@ #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) #include -#define __sync_val_compare_and_swap(p, o, n) atomic_cas_ptr(p, o, n) #endif UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); @@ -49,6 +48,8 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { return oldval; else return op4; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_cas_uint(ptr, oldval, newval); #else return __sync_val_compare_and_swap(ptr, oldval, newval); #endif @@ -83,6 +84,8 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) { return oldval; else return op4; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_cas_ulong(ptr, oldval, newval); #else return __sync_val_compare_and_swap(ptr, oldval, newval); #endif diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 8276c604132995..4c744925e29607 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -28,7 +28,6 @@ #include #include #include -#include /* MAXHOSTNAMELEN on Linux and the BSDs */ #include #include #include @@ -82,6 +81,10 @@ #include #endif +#if !defined(__MVS__) +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ +#endif + /* Fallback for the maximum hostname length */ #ifndef MAXHOSTNAMELEN # define MAXHOSTNAMELEN 256 diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index e52ae99dbe9030..c3c4902be9a568 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -203,35 +202,31 @@ int uv_get_process_title(char* buffer, size_t size) { return 0; } - int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc *kinfo = NULL; - pid_t pid; - int nprocs; - size_t page_size = getpagesize(); + struct kinfo_proc kinfo; + size_t page_size; + size_t kinfo_size; + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); - pid = getpid(); + kinfo_size = sizeof(kinfo); - kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); - if (kd == NULL) goto error; + if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0)) + return -errno; - kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); - if (kinfo == NULL) goto error; + page_size = getpagesize(); #ifdef __DragonFly__ - *rss = kinfo->kp_vm_rssize * page_size; + *rss = kinfo.kp_vm_rssize * page_size; #else - *rss = kinfo->ki_rssize * page_size; + *rss = kinfo.ki_rssize * page_size; #endif - kvm_close(kd); - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; } diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index 2ba5abf35490d7..de7df91169ad8f 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -25,6 +25,7 @@ #include #include #include +#include #if defined(__clang__) #include "csrsic.h" #else @@ -118,9 +119,10 @@ void uv__platform_loop_delete(uv_loop_t* loop) { uint64_t uv__hrtime(uv_clocktype_t type) { - struct timeval time; - gettimeofday(&time, NULL); - return (uint64_t) time.tv_sec * 1e9 + time.tv_usec * 1e3; + unsigned long long timestamp; + __stckf(×tamp); + /* Convert to nanoseconds */ + return timestamp / 10; } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index f2fe30521c1d9b..80b9686ec828f4 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -279,9 +279,12 @@ static void uv__process_child_init(const uv_process_options_t* options, int stdio_count, int (*pipes)[2], int error_fd) { + sigset_t set; int close_fd; int use_fd; + int err; int fd; + int n; if (options->flags & UV_PROCESS_DETACHED) setsid(); @@ -376,6 +379,31 @@ static void uv__process_child_init(const uv_process_options_t* options, environ = options->env; } + /* Reset signal disposition. Use a hard-coded limit because NSIG + * is not fixed on Linux: it's either 32, 34 or 64, depending on + * whether RT signals are enabled. We are not allowed to touch + * RT signal handlers, glibc uses them internally. + */ + for (n = 1; n < 32; n += 1) { + if (n == SIGKILL || n == SIGSTOP) + continue; /* Can't be changed. */ + + if (SIG_ERR != signal(n, SIG_DFL)) + continue; + + uv__write_int(error_fd, -errno); + _exit(127); + } + + /* Reset signal mask. */ + sigemptyset(&set); + err = pthread_sigmask(SIG_SETMASK, &set, NULL); + + if (err != 0) { + uv__write_int(error_fd, -err); + _exit(127); + } + execvp(options->file, options->args); uv__write_int(error_fd, -errno); _exit(127); diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 9160f7eafb3729..2ed0b21c6625bd 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -98,7 +98,9 @@ int uv_get_process_title(char* buffer, size_t size) { else if (size <= process_title.len) return -ENOBUFS; - memcpy(buffer, process_title.str, process_title.len + 1); + if (process_title.len != 0) + memcpy(buffer, process_title.str, process_title.len + 1); + buffer[process_title.len] = '\0'; return 0; diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 7b23d16ecf1407..c502098dcf1b38 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -514,7 +514,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { int err; stream = container_of(w, uv_stream_t, io_watcher); - assert(events == POLLIN); + assert(events & POLLIN); assert(stream->accepted_fd == -1); assert(!(stream->flags & UV_CLOSING)); @@ -750,6 +750,7 @@ static void uv__write(uv_stream_t* stream) { int iovmax; int iovcnt; ssize_t n; + int err; start: @@ -782,14 +783,21 @@ static void uv__write(uv_stream_t* stream) { */ if (req->send_handle) { + int fd_to_send; struct msghdr msg; struct cmsghdr *cmsg; - int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); union { char data[64]; struct cmsghdr alias; } scratch; + if (uv__is_closing(req->send_handle)) { + err = -EBADF; + goto error; + } + + fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -852,14 +860,8 @@ static void uv__write(uv_stream_t* stream) { if (n < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { - /* Error */ - req->error = -errno; - uv__write_req_finish(req); - uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); - if (!uv__io_active(&stream->io_watcher, POLLIN)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - return; + err = -errno; + goto error; } else if (stream->flags & UV_STREAM_BLOCKING) { /* If this is a blocking stream, try again. */ goto start; @@ -923,6 +925,16 @@ static void uv__write(uv_stream_t* stream) { /* Notify select() thread about state change */ uv__stream_osx_interrupt_select(stream); + + return; + +error: + req->error = err; + uv__write_req_finish(req); + uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); + if (!uv__io_active(&stream->io_watcher, POLLIN)) + uv__handle_stop(stream); + uv__stream_osx_interrupt_select(stream); } diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index 2dc02ae457cd06..49de5a7fcd5b1f 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -747,7 +747,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent) { return 1; if (ent->ifa_addr == NULL) return 1; - if (ent->ifa_addr->sa_family == PF_PACKET) + if (ent->ifa_addr->sa_family != AF_INET && + ent->ifa_addr->sa_family != AF_INET6) return 1; return 0; } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 2d72cdc70fe7d8..8223d6f655d1df 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -556,9 +556,14 @@ void fs__read(uv_fs_t* req) { DWORD error; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { @@ -569,6 +574,10 @@ void fs__read(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -593,6 +602,9 @@ void fs__read(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { @@ -615,9 +627,14 @@ void fs__write(uv_fs_t* req) { DWORD bytes; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); @@ -627,6 +644,10 @@ void fs__write(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -651,6 +672,9 @@ void fs__write(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index edf30021217980..9b10cc9fe22bf6 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -968,27 +968,31 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { uv_mutex_unlock(m); } restart_readfile: - result = ReadFile(handle->handle, - &uv_zero_, - 0, - &bytes, - NULL); - if (!result) { - err = GetLastError(); - if (err == ERROR_OPERATION_ABORTED && - handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - if (handle->flags & UV_HANDLE_READING) { - /* just a brief break to do something else */ - handle->pipe.conn.readfile_thread = NULL; - /* resume after it is finished */ - uv_mutex_lock(m); - handle->pipe.conn.readfile_thread = hThread; - uv_mutex_unlock(m); - goto restart_readfile; - } else { - result = 1; /* successfully stopped reading */ + if (handle->flags & UV_HANDLE_READING) { + result = ReadFile(handle->handle, + &uv_zero_, + 0, + &bytes, + NULL); + if (!result) { + err = GetLastError(); + if (err == ERROR_OPERATION_ABORTED && + handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { + if (handle->flags & UV_HANDLE_READING) { + /* just a brief break to do something else */ + handle->pipe.conn.readfile_thread = NULL; + /* resume after it is finished */ + uv_mutex_lock(m); + handle->pipe.conn.readfile_thread = hThread; + uv_mutex_unlock(m); + goto restart_readfile; + } else { + result = 1; /* successfully stopped reading */ + } } } + } else { + result = 1; /* successfully aborted read before it even started */ } if (hThread) { assert(hThread == handle->pipe.conn.readfile_thread); @@ -1515,7 +1519,10 @@ static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, int error, uv_buf_t buf) { - if (error == ERROR_BROKEN_PIPE) { + if (error == ERROR_OPERATION_ABORTED) { + /* do nothing (equivalent to EINTR) */ + } + else if (error == ERROR_BROKEN_PIPE) { uv_pipe_read_eof(loop, handle, buf); } else { uv_pipe_read_error(loop, handle, error, buf); diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 2fd15cfa9a64fa..21348f3796926a 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -897,13 +897,12 @@ int uv__udp_send(uv_udp_send_t* req, int err; if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { + else if (addrlen == sizeof(uv_addr_ip6_any_)) bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } + else + return UV_EINVAL; err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); if (err) return uv_translate_sys_error(err); @@ -922,5 +921,40 @@ int uv__udp_try_send(uv_udp_t* handle, unsigned int nbufs, const struct sockaddr* addr, unsigned int addrlen) { - return UV_ENOSYS; + DWORD bytes; + const struct sockaddr* bind_addr; + int err; + + assert(nbufs > 0); + + /* Already sending a message.*/ + if (handle->send_queue_count != 0) + return UV_EAGAIN; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + else if (addrlen == sizeof(uv_addr_ip6_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + else + return UV_EINVAL; + err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); + if (err) + return uv_translate_sys_error(err); + } + + err = WSASendTo(handle->socket, + (WSABUF*)bufs, + nbufs, + &bytes, + 0, + addr, + addrlen, + NULL, + NULL); + + if (err) + return uv_translate_sys_error(WSAGetLastError()); + + return bytes; } diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index 1e344f05002ac6..4e10b68f3b42f7 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -38,6 +38,7 @@ int ipc_helper(int listen_after_write); int ipc_helper_tcp_connection(void); +int ipc_helper_closed_handle(void); int ipc_send_recv_helper(void); int ipc_helper_bind_twice(void); int stdio_over_pipes_helper(void); @@ -89,6 +90,10 @@ static int maybe_run_test(int argc, char **argv) { return ipc_helper_tcp_connection(); } + if (strcmp(argv[1], "ipc_helper_closed_handle") == 0) { + return ipc_helper_closed_handle(); + } + if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) { return ipc_helper_bind_twice(); } diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c index 2ff18ce75647fe..3167ed44bf695a 100644 --- a/deps/uv/test/runner-unix.c +++ b/deps/uv/test/runner-unix.c @@ -61,12 +61,14 @@ int platform_init(int argc, char **argv) { /* Make sure that all stdio output of the processes is buffered up. */ int process_start(char* name, char* part, process_info_t* p, int is_helper) { FILE* stdout_file; + int stdout_fd; const char* arg; char* args[16]; int n; pid_t pid; stdout_file = tmpfile(); + stdout_fd = fileno(stdout_file); if (!stdout_file) { perror("tmpfile"); return -1; @@ -103,8 +105,8 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) { args[n++] = part; args[n++] = NULL; - dup2(fileno(stdout_file), STDOUT_FILENO); - dup2(fileno(stdout_file), STDERR_FILENO); + dup2(stdout_fd, STDOUT_FILENO); + dup2(stdout_fd, STDERR_FILENO); execvp(args[0], args); perror("execvp()"); _exit(127); diff --git a/deps/uv/test/test-async-null-cb.c b/deps/uv/test/test-async-null-cb.c index 757944a2762dd0..52652d91ebf098 100644 --- a/deps/uv/test/test-async-null-cb.c +++ b/deps/uv/test/test-async-null-cb.c @@ -21,6 +21,7 @@ #include "uv.h" #include "task.h" +#include static uv_async_t async_handle; static uv_check_t check_handle; @@ -43,6 +44,14 @@ static void check_cb(uv_check_t* handle) { TEST_IMPL(async_null_cb) { + /* + * Fill async_handle with garbage values. + * uv_async_init() should properly initialize struct fields regardless of + * initial values. + * This is added to verify paddings between fields do not affect behavior. + */ + memset(&async_handle, 0xff, sizeof(async_handle)); + ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL)); ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); ASSERT(0 == uv_check_start(&check_handle, check_cb)); diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index c482ab5c71c06a..404d0426f38aed 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -2804,3 +2804,43 @@ TEST_IMPL(get_osfhandle_valid_handle) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(fs_file_pos_after_op_with_offset) { + int r; + + /* Setup. */ + unlink("test_file"); + loop = uv_default_loop(); + + r = uv_fs_open(loop, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r > 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(strcmp(buf, test_buf) == 0); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index a2fda2458546ba..88d63d4dc670a7 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -44,6 +44,7 @@ static int close_cb_called; static int connection_accepted; static int tcp_conn_read_cb_called; static int tcp_conn_write_cb_called; +static int closed_handle_data_read; typedef struct { uv_connect_t conn_req; @@ -53,6 +54,7 @@ typedef struct { #define CONN_COUNT 100 #define BACKLOG 128 +#define LARGE_SIZE 1000000 static void close_server_conn_cb(uv_handle_t* handle) { @@ -395,6 +397,26 @@ static void on_read_connection(uv_stream_t* handle, } +#ifndef _WIN32 +static void on_read_closed_handle(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + if (nread == 0 || nread == UV_EOF) { + free(buf->base); + return; + } + + if (nread < 0) { + printf("error recving on channel: %s\n", uv_strerror(nread)); + abort(); + } + + closed_handle_data_read += nread; + free(buf->base); +} +#endif + + static int run_ipc_test(const char* helper, uv_read_cb read_cb) { uv_process_t process; int r; @@ -448,6 +470,15 @@ TEST_IMPL(ipc_tcp_connection) { return r; } +#ifndef _WIN32 +TEST_IMPL(ipc_closed_handle) { + int r; + r = run_ipc_test("ipc_helper_closed_handle", on_read_closed_handle); + ASSERT(r == 0); + return 0; +} +#endif + #ifdef _WIN32 TEST_IMPL(listen_with_simultaneous_accepts) { @@ -536,6 +567,17 @@ static void tcp_connection_write_cb(uv_write_t* req, int status) { } +static void closed_handle_large_write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + ASSERT(closed_handle_data_read = LARGE_SIZE); +} + + +static void closed_handle_write_cb(uv_write_t* req, int status) { + ASSERT(status == UV_EBADF); +} + + static void on_tcp_child_process_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { @@ -742,6 +784,60 @@ int ipc_helper_tcp_connection(void) { return 0; } + +int ipc_helper_closed_handle(void) { + int r; + struct sockaddr_in addr; + uv_write_t write_req; + uv_write_t write_req2; + uv_buf_t buf; + char buffer[LARGE_SIZE]; + + r = uv_pipe_init(uv_default_loop(), &channel, 1); + ASSERT(r == 0); + + uv_pipe_open(&channel, 0); + + ASSERT(1 == uv_is_readable((uv_stream_t*) &channel)); + ASSERT(1 == uv_is_writable((uv_stream_t*) &channel)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &channel)); + + memset(buffer, '.', LARGE_SIZE); + buf = uv_buf_init(buffer, LARGE_SIZE); + + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_write(&write_req, + (uv_stream_t*)&channel, + &buf, + 1, + closed_handle_large_write_cb); + ASSERT(r == 0); + + r = uv_write2(&write_req2, + (uv_stream_t*)&channel, + &buf, + 1, + (uv_stream_t*)&tcp_server, + closed_handle_write_cb); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&tcp_server, NULL); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + int ipc_helper_bind_twice(void) { /* * This is launched from test-ipc.c. stdin is a duplex channel diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 3571aa2308397f..0c32d84d2038ba 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -63,6 +63,9 @@ TEST_DECLARE (ipc_send_recv_pipe_inprocess) TEST_DECLARE (ipc_send_recv_tcp) TEST_DECLARE (ipc_send_recv_tcp_inprocess) TEST_DECLARE (ipc_tcp_connection) +#ifndef _WIN32 +TEST_DECLARE (ipc_closed_handle) +#endif TEST_DECLARE (tcp_alloc_cb_fail) TEST_DECLARE (tcp_ping_pong) TEST_DECLARE (tcp_ping_pong_v6) @@ -308,6 +311,7 @@ TEST_DECLARE (fs_read_write_null_arguments) TEST_DECLARE (get_osfhandle_valid_handle) TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) +TEST_DECLARE (fs_file_pos_after_op_with_offset) TEST_DECLARE (threadpool_queue_work_simple) TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) @@ -443,6 +447,9 @@ TASK_LIST_START TEST_ENTRY (ipc_send_recv_tcp) TEST_ENTRY (ipc_send_recv_tcp_inprocess) TEST_ENTRY (ipc_tcp_connection) +#ifndef _WIN32 + TEST_ENTRY (ipc_closed_handle) +#endif TEST_ENTRY (tcp_alloc_cb_fail) @@ -793,6 +800,7 @@ TASK_LIST_START TEST_ENTRY (fs_write_alotof_bufs) TEST_ENTRY (fs_write_alotof_bufs_with_offset) TEST_ENTRY (fs_read_write_null_arguments) + TEST_ENTRY (fs_file_pos_after_op_with_offset) TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 52fc7f6cc5e95d..bb35e32b28a285 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -929,9 +929,30 @@ TEST_IMPL(kill) { init_process_options("spawn_helper4", kill_cb); + /* Verify that uv_spawn() resets the signal disposition. */ +#ifndef _WIN32 + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGTERM); + ASSERT(0 == pthread_sigmask(SIG_BLOCK, &set, NULL)); + } + ASSERT(SIG_ERR != signal(SIGTERM, SIG_IGN)); +#endif + r = uv_spawn(uv_default_loop(), &process, &options); ASSERT(r == 0); +#ifndef _WIN32 + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGTERM); + ASSERT(0 == pthread_sigmask(SIG_UNBLOCK, &set, NULL)); + } + ASSERT(SIG_ERR != signal(SIGTERM, SIG_DFL)); +#endif + /* Sending signum == 0 should check if the * child process is still alive, not kill it. */ diff --git a/deps/uv/test/test-udp-try-send.c b/deps/uv/test/test-udp-try-send.c index 7b6de365487274..a31d3822955632 100644 --- a/deps/uv/test/test-udp-try-send.c +++ b/deps/uv/test/test-udp-try-send.c @@ -26,16 +26,6 @@ #include #include -#ifdef _WIN32 - -TEST_IMPL(udp_try_send) { - - MAKE_VALGRIND_HAPPY(); - return 0; -} - -#else /* !_WIN32 */ - #define CHECK_HANDLE(handle) \ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) @@ -129,5 +119,3 @@ TEST_IMPL(udp_try_send) { MAKE_VALGRIND_HAPPY(); return 0; } - -#endif /* !_WIN32 */ diff --git a/deps/uv/tools/vswhere_usability_wrapper.cmd b/deps/uv/tools/vswhere_usability_wrapper.cmd new file mode 100644 index 00000000000000..e4acf03e1ee952 --- /dev/null +++ b/deps/uv/tools/vswhere_usability_wrapper.cmd @@ -0,0 +1,33 @@ +:: Copyright 2017 - Refael Ackermann +:: Distributed under MIT style license or the libuv license +:: See accompanying file LICENSE at https://github.com/node4good/windows-autoconf +:: or libuv LICENSE file at https://github.com/libuv/libuv +:: version: 1.15.3 + +@if not defined DEBUG_HELPER @ECHO OFF +setlocal +set "InstallerPath=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" +if not exist "%InstallerPath%" set "InstallerPath=%ProgramFiles%\Microsoft Visual Studio\Installer" +if not exist "%InstallerPath%" exit goto :no-vswhere +:: Manipulate %Path% for easier " handeling +set Path=%Path%;%InstallerPath% +where vswhere 2> nul > nul +if errorlevel 1 goto :no-vswhere +set VSWHERE_REQ=-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 +set VSWHERE_PRP=-property installationPath +set VSWHERE_LMT=-version "[15.0,16.0)" +vswhere -prerelease > nul +if "%~1"=="prerelase" set VSWHERE_WITH_PRERELASE=1 +if not errorlevel 1 if "%VSWHERE_WITH_PRERELASE%"=="1" set "VSWHERE_LMT=%VSWHERE_LMT% -prerelease" +SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% +for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do ( + endlocal + set "VCINSTALLDIR=%%i\VC\" + set "VS150COMNTOOLS=%%i\Common7\Tools\" + exit /B 0 +) + +:no-vswhere +endlocal +echo could not find "vswhere" +exit /B 1 \ No newline at end of file diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index a3a42787b37b78..6f61d725a90b99 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -253,7 +253,7 @@ 'src/unix/linux-syscalls.h', 'src/unix/pthread-fixes.c', 'src/unix/android-ifaddrs.c', - 'src/unix/pthread-barrier.c' + 'src/unix/pthread-barrier.c', 'src/unix/procfs-exepath.c', 'src/unix/sysinfo-loadavg.c', 'src/unix/sysinfo-memory.c', @@ -302,12 +302,12 @@ 'sources': [ 'src/unix/openbsd.c' ], }], [ 'OS=="netbsd"', { - 'sources': [ 'src/unix/netbsd.c' ], - }], - [ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', { 'link_settings': { 'libraries': [ '-lkvm' ], }, + 'sources': [ 'src/unix/netbsd.c' ], + }], + [ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', { 'sources': [ 'src/unix/posix-hrtime.c' ], }], [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', { diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat index 91f45b72195301..e33573d108e16f 100644 --- a/deps/uv/vcbuild.bat +++ b/deps/uv/vcbuild.bat @@ -14,10 +14,11 @@ if /i "%1"=="/?" goto help @rem Process arguments. set config= set target=Build +set target_arch=ia32 +set target_env= set noprojgen= set nobuild= set run= -set target_arch=ia32 set vs_toolset=x86 set msbuild_platform=WIN32 set library=static_library @@ -29,6 +30,7 @@ if /i "%1"=="release" set config=Release&goto arg-ok if /i "%1"=="test" set run=run-tests.exe&goto arg-ok if /i "%1"=="bench" set run=run-benchmarks.exe&goto arg-ok if /i "%1"=="clean" set target=Clean&goto arg-ok +if /i "%1"=="vs2017" set target_env=vs2017&goto arg-ok if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok if /i "%1"=="nobuild" set nobuild=1&goto arg-ok if /i "%1"=="x86" set target_arch=ia32&set msbuild_platform=WIN32&set vs_toolset=x86&goto arg-ok @@ -41,10 +43,28 @@ shift goto next-arg :args-done -if defined WindowsSDKDir goto select-target -if defined VCINSTALLDIR goto select-target +@rem Look for Visual Studio 2017 only if explicitly requested. +if "%target_env%" NEQ "vs2017" goto vs-set-2015 +echo Looking for Visual Studio 2017 +@rem Check if VS2017 is already setup, and for the requested arch. +if "_%VisualStudioVersion%_" == "_15.0_" if "_%VSCMD_ARG_TGT_ARCH%_"=="_%vs_toolset%_" goto found_vs2017 +set "VSINSTALLDIR=" +call tools\vswhere_usability_wrapper.cmd +if "_%VCINSTALLDIR%_" == "__" goto vs-set-2015 +@rem Need to clear VSINSTALLDIR for vcvarsall to work as expected. +set vcvars_call="%VCINSTALLDIR%\Auxiliary\Build\vcvarsall.bat" %vs_toolset% +echo calling: %vcvars_call% +call %vcvars_call% + +:found_vs2017 +echo Found MSVS version %VisualStudioVersion% +if %VSCMD_ARG_TGT_ARCH%==x64 set target_arch=x64&set msbuild_platform=x64&set vs_toolset=x64 +set GYP_MSVS_VERSION=2017 +goto select-target + @rem Look for Visual Studio 2015 +:vs-set-2015 if not defined VS140COMNTOOLS goto vc-set-2013 if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2013 call "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset% @@ -148,7 +168,9 @@ echo Failed to create vc project files. exit /b 1 :help -echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [x86/x64] [static/shared] + +echo "vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared]" + echo Examples: echo vcbuild.bat : builds debug build echo vcbuild.bat test : builds debug build and runs tests From 08d683053f88609e34aa28b68968f26d9175f1b1 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Wed, 6 Sep 2017 09:59:10 -0400 Subject: [PATCH 026/128] deps: upgrade libuv to 1.14.1 Fixes: https://github.com/nodejs/node/issues/12737 Fixes: https://github.com/nodejs/node/issues/13581 Fixes: https://github.com/nodejs/node/issues/15117 PR-URL: https://github.com/nodejs/node/pull/14866 Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- deps/uv/.gitignore | 1 + deps/uv/AUTHORS | 9 + deps/uv/ChangeLog | 115 ++++++++ deps/uv/LICENSE | 4 +- deps/uv/Makefile.am | 14 +- deps/uv/README.md | 9 +- deps/uv/SUPPORTED_PLATFORMS.md | 6 +- deps/uv/android-configure | 5 +- deps/uv/appveyor.yml | 5 +- deps/uv/checksparse.sh | 1 + deps/uv/configure.ac | 2 +- deps/uv/docs/src/async.rst | 6 +- deps/uv/docs/src/fs.rst | 19 +- deps/uv/docs/src/misc.rst | 23 +- deps/uv/docs/src/poll.rst | 15 +- deps/uv/docs/src/stream.rst | 2 +- deps/uv/include/pthread-barrier.h | 1 + deps/uv/include/uv-errno.h | 6 + deps/uv/include/uv-version.h | 2 +- deps/uv/include/uv.h | 19 +- deps/uv/src/unix/aix.c | 21 +- deps/uv/src/unix/android-ifaddrs.c | 41 +-- deps/uv/src/unix/bsd-ifaddrs.c | 15 +- deps/uv/src/unix/core.c | 11 +- deps/uv/src/unix/freebsd.c | 6 +- deps/uv/src/unix/fs.c | 139 ++++++++- deps/uv/src/unix/internal.h | 12 + deps/uv/src/unix/kqueue.c | 35 +++ deps/uv/src/unix/linux-core.c | 14 +- deps/uv/src/unix/netbsd.c | 8 +- deps/uv/src/unix/openbsd.c | 7 +- deps/uv/src/unix/os390-syscalls.c | 23 +- deps/uv/src/unix/os390.c | 38 ++- deps/uv/src/unix/poll.c | 25 +- deps/uv/src/unix/pthread-barrier.c | 121 -------- deps/uv/src/unix/thread.c | 122 +++++++- deps/uv/src/win/dl.c | 55 ++-- deps/uv/src/win/fs.c | 448 +++++++++++------------------ deps/uv/src/win/pipe.c | 2 + deps/uv/src/win/process.c | 9 +- deps/uv/src/win/tcp.c | 15 + deps/uv/src/win/tty.c | 1 + deps/uv/src/win/winapi.h | 4 + deps/uv/test/runner-win.c | 1 - deps/uv/test/test-dlerror.c | 2 + deps/uv/test/test-fs-copyfile.c | 150 ++++++++++ deps/uv/test/test-fs.c | 111 ++++++- deps/uv/test/test-list.h | 20 ++ deps/uv/test/test-poll-oob.c | 205 +++++++++++++ deps/uv/test/test-spawn.c | 32 ++- deps/uv/test/test-tcp-oob.c | 13 + deps/uv/test/test-tcp-open.c | 57 ++++ deps/uv/uv.gyp | 7 +- deps/uv/vcbuild.bat | 7 +- 54 files changed, 1486 insertions(+), 555 deletions(-) delete mode 100644 deps/uv/src/unix/pthread-barrier.c create mode 100644 deps/uv/test/test-fs-copyfile.c create mode 100644 deps/uv/test/test-poll-oob.c diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore index eb54f92488d7b2..7536abd54970a2 100644 --- a/deps/uv/.gitignore +++ b/deps/uv/.gitignore @@ -39,6 +39,7 @@ Makefile.in # Generated by gyp for android *.target.mk +/android-toolchain /out/ /build/gyp diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 4ef241092701d2..3562bb81698b66 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -299,3 +299,12 @@ Barnabas Gema Romain Caire Robert Ayrapetyan Refael Ackermann +André Klitzing +Matthew Taylor +CurlyMoo +XadillaX +Anticrisis +Jacob Segal +Maciej Szeptuch (Neverous) +Joel Winarske +Gergely Nagy diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 67c99df82eaee7..d0b55750172152 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,118 @@ +2017.09.07, Version 1.14.1 (Stable), b0f9fb2a07a5e638b1580fe9a42a356c3ab35f37 + +Changes since version 1.14.0: + +* fs, win: add support for user symlinks (Bartosz Sosnowski) + +* cygwin: include uv-posix.h header (Joel Winarske) + +* zos: fix semaphore initialization (jBarz) + +* zos: improve loop_count benchmark performance (jBarz) + +* zos, test: flush out the oob data in callback (jBarz) + +* unix,win: check for bad flags in uv_fs_copyfile() (cjihrig) + +* unix: modify argv[0] when process title is set (Matthew Taylor) + +* unix: don't use req->loop in uv__fs_copyfile() (cjihrig) + +* doc: fix a trivial typo (Vladimír Čunát) + +* android: fix uv_cond_timedwait on API level < 21 (Gergely Nagy) + +* win: add uv__once_init() calls (Bartosz Sosnowski) + +* unix,windows: init all requests in fs calls (cjihrig) + +* unix,windows: return UV_EINVAL on NULL fs reqs (cjihrig) + +* windows: add POST macro to fs functions (cjihrig) + +* unix: handle partial sends in uv_fs_copyfile() (A. Hauptmann) + +* Revert "win, test: fix double close in test runner" (Bartosz Sosnowski) + +* win, test: remove surplus CloseHandle (Bartosz Sosnowski) + + +2017.08.17, Version 1.14.0 (Stable), e0d31e9e21870f88277746b6d59cf07b977cdfea + +Changes since version 1.13.1: + +* unix: check for NULL in uv_os_unsetenv for parameter name (André Klitzing) + +* doc: add thread safety warning for process title (Matthew Taylor) + +* unix: always copy process title into local buffer (Matthew Taylor) + +* poll: add support for OOB TCP and GPIO interrupts (CurlyMoo) + +* win,build: fix appveyor properly (Refael Ackermann) + +* win: include filename in dlopen error message (Ben Noordhuis) + +* aix: add netmask, mac address into net interfaces (Gireesh Punathil) + +* unix, windows: map EREMOTEIO errno (Ben Noordhuis) + +* unix: fix wrong MAC of uv_interface_address (XadillaX) + +* win,build: fix building from Windows SDK or VS console (Saúl Ibarra Corretgé) + +* github: fix link to help repo in issue template (Ben Noordhuis) + +* zos: remove nonexistent include from autotools build (Saúl Ibarra Corretgé) + +* misc: remove reference to pthread-fixes.h from LICENSE (Saúl Ibarra Corretgé) + +* docs: fix guide source code example paths (Anticrisis) + +* android: fix compilation with new NDK versions (Saúl Ibarra Corretgé) + +* misc: add android-toolchain to .gitignore (Saúl Ibarra Corretgé) + +* win, fs: support unusual reparse points (Bartosz Sosnowski) + +* android: fix detection of pthread_condattr_setclock (Saúl Ibarra Corretgé) + +* android: remove no longer needed check (Saúl Ibarra Corretgé) + +* doc: update instructions for building on Android (Saúl Ibarra Corretgé) + +* win, process: support semicolons in PATH variable (Bartosz Sosnowski) + +* doc: document uv_async_(init|send) return values (Ben Noordhuis) + +* doc: add Android as a tier 3 supported platform (Saúl Ibarra Corretgé) + +* unix: add missing semicolon (jBarz) + +* win, test: fix double close in test runner (Bartosz Sosnowski) + +* doc: update supported windows version baseline (Ben Noordhuis) + +* test,zos: skip chown root test (jBarz) + +* test,zos: use gid=-1 to test spawn_setgid_fails (jBarz) + +* zos: fix hr timer resolution (jBarz) + +* android: fix blocking recvmsg due to netlink bug (Jacob Segal) + +* zos: read more accurate rss info from RSM (jBarz) + +* win: allow bound/connected socket in uv_tcp_open() (Maciej Szeptuch + (Neverous)) + +* doc: differentiate SmartOS and SunOS support (cjihrig) + +* unix: make uv_poll_stop() remove fd from pollset (Ben Noordhuis) + +* unix, windows: add basic uv_fs_copyfile() (cjihrig) + + 2017.07.07, Version 1.13.1 (Stable), 2bb4b68758f07cd8617838e68c44c125bc567ba6 Changes since version 1.13.0: diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE index 41ba44c2857a49..28f17339e29ca6 100644 --- a/deps/uv/LICENSE +++ b/deps/uv/LICENSE @@ -62,8 +62,8 @@ The externally maintained libraries used by libuv are: - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three clause BSD license. - - pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile - Communications AB. Three clause BSD license. + - pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB. + Three clause BSD license. - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 404674baf211d5..b94fdd63b58eea 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -169,6 +169,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-env-vars.c \ test/test-error.c \ test/test-fail-always.c \ + test/test-fs-copyfile.c \ test/test-fs-event.c \ test/test-fs-poll.c \ test/test-fs.c \ @@ -212,10 +213,11 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-pipe-close-stdout-read-stdin.c \ test/test-pipe-set-non-blocking.c \ test/test-platform-output.c \ + test/test-poll.c \ test/test-poll-close.c \ test/test-poll-close-doesnt-corrupt-stack.c \ test/test-poll-closesocket.c \ - test/test-poll.c \ + test/test-poll-oob.c \ test/test-process-title.c \ test/test-queue-foreach-delete.c \ test/test-ref.c \ @@ -333,11 +335,11 @@ if ANDROID include_HEADERS += include/android-ifaddrs.h \ include/pthread-barrier.h libuv_la_SOURCES += src/unix/android-ifaddrs.c \ - src/unix/pthread-fixes.c \ - src/unix/pthread-barrier.c + src/unix/pthread-fixes.c endif if CYGWIN +include_HEADERS += include/uv-posix.h libuv_la_CFLAGS += -D_GNU_SOURCE libuv_la_SOURCES += src/unix/cygwin.c \ src/unix/bsd-ifaddrs.c \ @@ -360,8 +362,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ - src/unix/proctitle.c \ - src/unix/pthread-barrier.c + src/unix/proctitle.c test_run_tests_LDFLAGS += -lutil endif @@ -436,7 +437,7 @@ libuv_la_SOURCES += src/unix/no-proctitle.c \ endif if OS390 -include_HEADERS += include/pthread-fixes.h include/pthread-barrier.h +include_HEADERS += include/pthread-barrier.h libuv_la_CFLAGS += -D_UNIX03_THREADS \ -D_UNIX03_SOURCE \ -D_OPEN_SYS_IF_EXT=1 \ @@ -453,7 +454,6 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \ -qFLOAT=IEEE libuv_la_LDFLAGS += -qXPLINK libuv_la_SOURCES += src/unix/pthread-fixes.c \ - src/unix/pthread-barrier.c \ src/unix/no-fsevents.c \ src/unix/os390.c \ src/unix/os390-syscalls.c \ diff --git a/deps/uv/README.md b/deps/uv/README.md index 372d514e049c39..733171be085ab5 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -267,7 +267,14 @@ Make sure that you specify the architecture you wish to build for in the Run: ```bash -$ source ./android-configure NDK_PATH gyp +$ source ./android-configure NDK_PATH gyp [API_LEVEL] +$ make -C out +``` + +The default API level is 24, but a different one can be selected as follows: + +```bash +$ source ./android-configure ~/android-ndk-r15b gyp 21 $ make -C out ``` diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index 3a000c5dd25e35..08fd5f4a9a1100 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -4,13 +4,15 @@ |---|---|---|---| | GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | -| Windows | Tier 1 | Windows >= XP SP1 | MSVC 2008 and later are supported | +| Windows | Tier 1 | Windows >= 8.1 | MSVC 2008 and later are supported | | FreeBSD | Tier 1 | >= 9 (see note) | | | AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix | | z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos | | Linux with musl | Tier 2 | musl >= 1.0 | | -| SunOS | Tier 2 | Solaris 121 and later | Maintainers: @libuv/sunos | +| SmartOS | Tier 2 | >= 14.4 | Maintainers: @libuv/smartos | +| Android | Tier 3 | NDK >= r15b | | | MinGW | Tier 3 | MinGW32 and MinGW-w64 | | +| SunOS | Tier 3 | Solaris 121 and later | | | Other | Tier 3 | N/A | | #### Note on FreeBSD 9 diff --git a/deps/uv/android-configure b/deps/uv/android-configure index 7ffc035c1bfbfc..b5c11cd40c6873 100755 --- a/deps/uv/android-configure +++ b/deps/uv/android-configure @@ -2,17 +2,20 @@ export TOOLCHAIN=$PWD/android-toolchain mkdir -p $TOOLCHAIN +API=${3:-24} $1/build/tools/make-standalone-toolchain.sh \ --toolchain=arm-linux-androideabi-4.9 \ --arch=arm \ --install-dir=$TOOLCHAIN \ - --platform=android-21 + --platform=android-$API \ + --force export PATH=$TOOLCHAIN/bin:$PATH export AR=arm-linux-androideabi-ar export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export LINK=arm-linux-androideabi-g++ export PLATFORM=android +export CFLAGS="-D__ANDROID_API__=$API" if [[ $2 == 'gyp' ]] then diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index be90ef7b435c74..986c0d44030e5b 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -1,4 +1,7 @@ -version: v1.13.1.build{build} +version: v1.14.1.build{build} + +init: + - git config --global core.autocrlf true install: - cinst -y nsis diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index 9782718a23266c..ae0e5374f5efba 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -96,6 +96,7 @@ test/test-embed.c test/test-env-vars.c test/test-error.c test/test-fail-always.c +test/test-fs-copyfile.c test/test-fs-event.c test/test-fs-poll.c test/test-fs.c diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index a52cfc622cbb5f..41349a092c85e6 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.13.1], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.14.1], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/docs/src/async.rst b/deps/uv/docs/src/async.rst index 5c400458244a86..02e6a58e7838db 100644 --- a/deps/uv/docs/src/async.rst +++ b/deps/uv/docs/src/async.rst @@ -35,12 +35,16 @@ API Initialize the handle. A NULL callback is allowed. + :returns: 0 on success, or an error code < 0 on failure. + .. note:: Unlike other handle initialization functions, it immediately starts the handle. .. c:function:: int uv_async_send(uv_async_t* async) - Wakeup the event loop and call the async handle's callback. + Wake up the event loop and call the async handle's callback. + + :returns: 0 on success, or an error code < 0 on failure. .. note:: It's safe to call this function from any thread. The callback will be called on the diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index 3f766e393f2fa7..2db915bc9e6706 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -92,7 +92,8 @@ Data types UV_FS_READLINK, UV_FS_CHOWN, UV_FS_FCHOWN, - UV_FS_REALPATH + UV_FS_REALPATH, + UV_FS_COPYFILE } uv_fs_type; .. c:type:: uv_dirent_t @@ -241,6 +242,22 @@ API Equivalent to :man:`ftruncate(2)`. +.. c:function:: int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) + + Copies a file from `path` to `new_path`. Supported `flags` are described below. + + - `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with + `UV_EEXIST` if the destination path already exists. The default behavior + is to overwrite the destination if it exists. + + .. warning:: + If the destination path is created, but an error occurs while copying + the data, then the destination path is removed. There is a brief window + of time between closing and removing the file where another process + could access the file. + + .. versionadded:: 1.14.0 + .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) Limited equivalent to :man:`sendfile(2)`. diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 9d7c3617e864bb..3fea708a8d38e2 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -186,17 +186,24 @@ API .. c:function:: int uv_get_process_title(char* buffer, size_t size) - Gets the title of the current process. If `buffer` is `NULL` or `size` is - zero, `UV_EINVAL` is returned. If `size` cannot accommodate the process - title and terminating `NULL` character, the function returns `UV_ENOBUFS`. + Gets the title of the current process. You *must* call `uv_setup_args` + before calling this function. If `buffer` is `NULL` or `size` is zero, + `UV_EINVAL` is returned. If `size` cannot accommodate the process title and + terminating `NULL` character, the function returns `UV_ENOBUFS`. + + .. warning:: + `uv_get_process_title` is not thread safe on any platform except Windows. .. c:function:: int uv_set_process_title(const char* title) - Sets the current process title. On platforms with a fixed size buffer for the - process title the contents of `title` will be copied to the buffer and - truncated if larger than the available space. Other platforms will return - `UV_ENOMEM` if they cannot allocate enough space to duplicate the contents of - `title`. + Sets the current process title. You *must* call `uv_setup_args` before + calling this function. On platforms with a fixed size buffer for the process + title the contents of `title` will be copied to the buffer and truncated if + larger than the available space. Other platforms will return `UV_ENOMEM` if + they cannot allocate enough space to duplicate the contents of `title`. + + .. warning:: + `uv_set_process_title` is not thread safe on any platform except Windows. .. c:function:: int uv_resident_set_memory(size_t* rss) diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst index 004ff4b92e5ea5..aba8915886bb5f 100644 --- a/deps/uv/docs/src/poll.rst +++ b/deps/uv/docs/src/poll.rst @@ -54,7 +54,8 @@ Data types enum uv_poll_event { UV_READABLE = 1, UV_WRITABLE = 2, - UV_DISCONNECT = 4 + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 }; @@ -84,10 +85,13 @@ API .. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) - Starts polling the file descriptor. `events` is a bitmask consisting made up - of UV_READABLE, UV_WRITABLE and UV_DISCONNECT. As soon as an event is detected - the callback will be called with `status` set to 0, and the detected events set on the - `events` field. + Starts polling the file descriptor. `events` is a bitmask made up of + UV_READABLE, UV_WRITABLE, UV_PRIORITIZED and UV_DISCONNECT. As soon as an + event is detected the callback will be called with `status` set to 0, and the + detected events set on the `events` field. + + The UV_PRIORITIZED event is used to watch for sysfs interrupts or TCP out-of-band + messages. The UV_DISCONNECT event is optional in the sense that it may not be reported and the user is free to ignore it, but it can help optimize the shutdown @@ -108,6 +112,7 @@ API on the `events` field in the callback. .. versionchanged:: 1.9.0 Added the UV_DISCONNECT event. + .. versionchanged:: 1.14.0 Added the UV_PRIORITIZED event. .. c:function:: int uv_poll_stop(uv_poll_t* poll) diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst index de492b3578152b..1f4e87e63a9db3 100644 --- a/deps/uv/docs/src/stream.rst +++ b/deps/uv/docs/src/stream.rst @@ -6,7 +6,7 @@ Stream handles provide an abstraction of a duplex communication channel. :c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations -in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`. +in the form of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`. Data types diff --git a/deps/uv/include/pthread-barrier.h b/deps/uv/include/pthread-barrier.h index 900ebedd308b26..07db9b8a6a27e0 100644 --- a/deps/uv/include/pthread-barrier.h +++ b/deps/uv/include/pthread-barrier.h @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #define PTHREAD_BARRIER_SERIAL_THREAD 0x12345 +#define UV__PTHREAD_BARRIER_FALLBACK 1 /* * To maintain ABI compatibility with diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h index f1371517cc32fe..32bbc5177e4b2d 100644 --- a/deps/uv/include/uv-errno.h +++ b/deps/uv/include/uv-errno.h @@ -416,4 +416,10 @@ # define UV__EHOSTDOWN (-4031) #endif +#if defined(EREMOTEIO) && !defined(_WIN32) +# define UV__EREMOTEIO (-EREMOTEIO) +#else +# define UV__EREMOTEIO (-4030) +#endif + #endif /* UV_ERRNO_H_ */ diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index c80c40ea7f1bb0..9b891499eb5f4a 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 13 +#define UV_VERSION_MINOR 14 #define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index f076094ccdc24c..eac63dde445829 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -140,6 +140,7 @@ extern "C" { XX(ENXIO, "no such device or address") \ XX(EMLINK, "too many links") \ XX(EHOSTDOWN, "host is down") \ + XX(EREMOTEIO, "remote I/O error") \ #define UV_HANDLE_TYPE_MAP(XX) \ XX(ASYNC, async) \ @@ -719,7 +720,8 @@ struct uv_poll_s { enum uv_poll_event { UV_READABLE = 1, UV_WRITABLE = 2, - UV_DISCONNECT = 4 + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 }; UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd); @@ -1112,7 +1114,8 @@ typedef enum { UV_FS_READLINK, UV_FS_CHOWN, UV_FS_FCHOWN, - UV_FS_REALPATH + UV_FS_REALPATH, + UV_FS_COPYFILE } uv_fs_type; /* uv_fs_t is a subclass of uv_req_t. */ @@ -1157,6 +1160,18 @@ UV_EXTERN int uv_fs_write(uv_loop_t* loop, unsigned int nbufs, int64_t offset, uv_fs_cb cb); +/* + * This flag can be used with uv_fs_copyfile() to return an error if the + * destination already exists. + */ +#define UV_FS_COPYFILE_EXCL 0x0001 + +UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 426f7f4735fd39..56a8f4ffe753e8 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -1108,9 +1108,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; - int sockfd, size = 1; + int sockfd, inet6, size = 1; struct ifconf ifc; struct ifreq *ifr, *p, flg; + struct sockaddr_dl* sa_addr; *count = 0; @@ -1174,6 +1175,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, p->ifr_addr.sa_family == AF_INET)) continue; + inet6 = (p->ifr_addr.sa_family == AF_INET6); + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { uv__close(sockfd); @@ -1187,13 +1190,23 @@ int uv_interface_addresses(uv_interface_address_t** addresses, address->name = uv__strdup(p->ifr_name); - if (p->ifr_addr.sa_family == AF_INET6) { + if (inet6) address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); - } else { + else address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); + + sa_addr = (struct sockaddr_dl*) &p->ifr_addr; + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + + if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) { + uv__close(sockfd); + return -ENOSYS; } - /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */ + if (inet6) + address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr); + else + address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c index 30f681b7d04a41..1a842ced48f9b5 100644 --- a/deps/uv/src/unix/android-ifaddrs.c +++ b/deps/uv/src/unix/android-ifaddrs.c @@ -43,9 +43,10 @@ typedef struct NetlinkList unsigned int m_size; } NetlinkList; -static int netlink_socket(void) +static int netlink_socket(pid_t *p_pid) { struct sockaddr_nl l_addr; + socklen_t l_len; int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if(l_socket < 0) @@ -61,6 +62,14 @@ static int netlink_socket(void) return -1; } + l_len = sizeof(l_addr); + if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0) + { + close(l_socket); + return -1; + } + *p_pid = l_addr.nl_pid; + return l_socket; } @@ -128,7 +137,7 @@ static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) } } -static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done) +static struct nlmsghdr *getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done) { size_t l_size = 4096; void *l_buffer = NULL; @@ -153,11 +162,10 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don } if(l_read >= 0) { - pid_t l_pid = getpid(); struct nlmsghdr *l_hdr; for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) { continue; } @@ -207,7 +215,7 @@ static void freeResultList(NetlinkList *p_list) } } -static NetlinkList *getResultList(int p_socket, int p_request) +static NetlinkList *getResultList(int p_socket, int p_request, pid_t p_pid) { int l_size; int l_done; @@ -227,7 +235,7 @@ static NetlinkList *getResultList(int p_socket, int p_request) { NetlinkList *l_item; - struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); + struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done); /* Error */ if(!l_hdr) { @@ -578,18 +586,17 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, return 0; } -static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) +static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) { int l_numLinks = 0; - pid_t l_pid = getpid(); for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) { unsigned int l_nlsize = p_netlinkList->m_size; struct nlmsghdr *l_hdr; for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) { continue; } @@ -612,16 +619,15 @@ static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifadd return l_numLinks; } -static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) +static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) { - pid_t l_pid = getpid(); for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) { unsigned int l_nlsize = p_netlinkList->m_size; struct nlmsghdr *l_hdr; for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) { continue; } @@ -648,6 +654,7 @@ int getifaddrs(struct ifaddrs **ifap) int l_socket; int l_result; int l_numLinks; + pid_t l_pid; NetlinkList *l_linkResults; NetlinkList *l_addrResults; @@ -657,20 +664,20 @@ int getifaddrs(struct ifaddrs **ifap) } *ifap = NULL; - l_socket = netlink_socket(); + l_socket = netlink_socket(&l_pid); if(l_socket < 0) { return -1; } - l_linkResults = getResultList(l_socket, RTM_GETLINK); + l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid); if(!l_linkResults) { close(l_socket); return -1; } - l_addrResults = getResultList(l_socket, RTM_GETADDR); + l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid); if(!l_addrResults) { close(l_socket); @@ -679,8 +686,8 @@ int getifaddrs(struct ifaddrs **ifap) } l_result = 0; - l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); - if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1) + l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap); + if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1) { l_result = -1; } diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c index 414789451ab3d6..ffcf156440d559 100644 --- a/deps/uv/src/unix/bsd-ifaddrs.c +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -31,11 +31,18 @@ #include #endif -static int uv__ifaddr_exclude(struct ifaddrs *ent) { +static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) return 1; if (ent->ifa_addr == NULL) return 1; + /* + * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family` + * equals to `AF_LINK` or not. Otherwise, the result depends on the operation + * system with `AF_LINK` or `PF_INET`. + */ + if (exclude_type == UV__EXCLUDE_IFPHYS) + return (ent->ifa_addr->sa_family != AF_LINK); #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) /* * On BSD getifaddrs returns information related to the raw underlying @@ -63,7 +70,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; (*count)++; } @@ -78,7 +85,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; address->name = uv__strdup(ent->ifa_name); @@ -102,7 +109,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) continue; address = *addresses; diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 4c744925e29607..bee641cb440410 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -838,7 +838,7 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) { void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP))); + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); assert(0 != events); assert(w->fd >= 0); assert(w->fd < INT_MAX); @@ -866,7 +866,7 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP))); + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); assert(0 != events); if (w->fd == -1) @@ -898,7 +898,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { void uv__io_close(uv_loop_t* loop, uv__io_t* w) { - uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP); + uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); QUEUE_REMOVE(&w->pending_queue); /* Remove stale events for this file descriptor */ @@ -913,7 +913,7 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { int uv__io_active(const uv__io_t* w, unsigned int events) { - assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP))); + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); assert(0 != events); return 0 != (w->pevents & events); } @@ -1292,6 +1292,9 @@ int uv_os_setenv(const char* name, const char* value) { int uv_os_unsetenv(const char* name) { + if (name == NULL) + return -EINVAL; + if (unsetenv(name) != 0) return -errno; diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index c3c4902be9a568..dba94298d1c06d 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -160,9 +160,13 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { int oid[4]; + char* new_title; + new_title = uv__strdup(title); + if (process_title == NULL) + return -ENOMEM; uv__free(process_title); - process_title = uv__strdup(title); + process_title = new_title; oid[0] = CTL_KERN; oid[1] = KERN_PROC; diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index f9513ea55a03eb..5a172cc7805171 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -60,8 +60,14 @@ # include #endif +#if defined(__APPLE__) +# include +#endif + #define INIT(subtype) \ do { \ + if (req == NULL) \ + return -EINVAL; \ req->type = UV_FS; \ if (cb != NULL) \ uv__req_init(loop, req, UV_FS); \ @@ -766,6 +772,112 @@ static ssize_t uv__fs_write(uv_fs_t* req) { return r; } +static ssize_t uv__fs_copyfile(uv_fs_t* req) { +#if defined(__APPLE__) && !TARGET_OS_IPHONE + /* On macOS, use the native copyfile(3). */ + copyfile_flags_t flags; + + flags = COPYFILE_ALL; + + if (req->flags & UV_FS_COPYFILE_EXCL) + flags |= COPYFILE_EXCL; + + return copyfile(req->path, req->new_path, NULL, flags); +#else + uv_fs_t fs_req; + uv_file srcfd; + uv_file dstfd; + struct stat statsbuf; + int dst_flags; + int result; + int err; + size_t bytes_to_send; + int64_t in_offset; + + dstfd = -1; + + /* Open the source file. */ + srcfd = uv_fs_open(NULL, &fs_req, req->path, O_RDONLY, 0, NULL); + uv_fs_req_cleanup(&fs_req); + + if (srcfd < 0) + return srcfd; + + /* Get the source file's mode. */ + if (fstat(srcfd, &statsbuf)) { + err = -errno; + goto out; + } + + dst_flags = O_WRONLY | O_CREAT; + + if (req->flags & UV_FS_COPYFILE_EXCL) + dst_flags |= O_EXCL; + + /* Open the destination file. */ + dstfd = uv_fs_open(NULL, + &fs_req, + req->new_path, + dst_flags, + statsbuf.st_mode, + NULL); + uv_fs_req_cleanup(&fs_req); + + if (dstfd < 0) { + err = dstfd; + goto out; + } + + bytes_to_send = statsbuf.st_size; + in_offset = 0; + while (bytes_to_send != 0) { + err = uv_fs_sendfile(NULL, + &fs_req, + dstfd, + srcfd, + in_offset, + bytes_to_send, + NULL); + uv_fs_req_cleanup(&fs_req); + if (err < 0) + break; + bytes_to_send -= fs_req.result; + in_offset += fs_req.result; + } + +out: + if (err < 0) + result = err; + else + result = 0; + + /* Close the source file. */ + err = uv__close_nocheckstdio(srcfd); + + /* Don't overwrite any existing errors. */ + if (err != 0 && result == 0) + result = err; + + /* Close the destination file if it is open. */ + if (dstfd >= 0) { + err = uv__close_nocheckstdio(dstfd); + + /* Don't overwrite any existing errors. */ + if (err != 0 && result == 0) + result = err; + + /* Remove the destination file if something went wrong. */ + if (result != 0) { + uv_fs_unlink(NULL, &fs_req, req->new_path, NULL); + /* Ignore the unlink return value, as an error already happened. */ + uv_fs_req_cleanup(&fs_req); + } + } + + return result; +#endif +} + static void uv__to_stat(struct stat* src, uv_stat_t* dst) { dst->st_dev = src->st_dev; dst->st_mode = src->st_mode; @@ -946,6 +1058,7 @@ static void uv__fs_work(struct uv__work* w) { X(CHMOD, chmod(req->path, req->mode)); X(CHOWN, chown(req->path, req->uid, req->gid)); X(CLOSE, close(req->file)); + X(COPYFILE, uv__fs_copyfile(req)); X(FCHMOD, fchmod(req->file, req->mode)); X(FCHOWN, fchown(req->file, req->uid, req->gid)); X(FDATASYNC, uv__fs_fdatasync(req)); @@ -1186,10 +1299,11 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, unsigned int nbufs, int64_t off, uv_fs_cb cb) { + INIT(READ); + if (bufs == NULL || nbufs == 0) return -EINVAL; - INIT(READ); req->file = file; req->nbufs = nbufs; @@ -1324,10 +1438,11 @@ int uv_fs_write(uv_loop_t* loop, unsigned int nbufs, int64_t off, uv_fs_cb cb) { + INIT(WRITE); + if (bufs == NULL || nbufs == 0) return -EINVAL; - INIT(WRITE); req->file = file; req->nbufs = nbufs; @@ -1349,6 +1464,9 @@ int uv_fs_write(uv_loop_t* loop, void uv_fs_req_cleanup(uv_fs_t* req) { + if (req == NULL) + return; + /* Only necessary for asychronous requests, i.e., requests with a callback. * Synchronous ones don't copy their arguments and have req->path and * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the @@ -1367,3 +1485,20 @@ void uv_fs_req_cleanup(uv_fs_t* req) { uv__free(req->ptr); req->ptr = NULL; } + + +int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb) { + INIT(COPYFILE); + + if (flags & ~UV_FS_COPYFILE_EXCL) + return -EINVAL; + + PATH2; + req->flags = flags; + POST; +} diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 2e3afa6c856827..c0898d982e9815 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -110,6 +110,12 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset); # define UV__POLLRDHUP 0x2000 #endif +#ifdef POLLPRI +# define UV__POLLPRI POLLPRI +#else +# define UV__POLLPRI 0 +#endif + #if !defined(O_CLOEXEC) && defined(__FreeBSD__) /* * It may be that we are just missing `__POSIX_VISIBLE >= 200809`. @@ -145,6 +151,12 @@ enum { UV_LOOP_BLOCK_SIGPROF = 1 }; +/* flags of excluding ifaddr */ +enum { + UV__EXCLUDE_IFPHYS, + UV__EXCLUDE_IFADDR +}; + typedef enum { UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index 6bc60bbe46885e..300bac07c3322f 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -34,6 +34,17 @@ #include #include +/* + * Required on + * - Until at least FreeBSD 11.0 + * - Older versions of Mac OS X + * + * http://www.boost.org/doc/libs/1_61_0/boost/asio/detail/kqueue_reactor.hpp + */ +#ifndef EV_OOBAND +#define EV_OOBAND EV_FLAG1 +#endif + static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags); @@ -166,6 +177,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } } + if ((w->events & UV__POLLPRI) == 0 && (w->pevents & UV__POLLPRI) != 0) { + EV_SET(events + nevents, w->fd, EV_OOBAND, EV_ADD, 0, 0, 0); + + if (++nevents == ARRAY_SIZE(events)) { + if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + abort(); + nevents = 0; + } + } + w->events = w->pevents; } @@ -275,6 +296,20 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { } } + if (ev->filter == EV_OOBAND) { + if (w->pevents & UV__POLLPRI) { + revents |= UV__POLLPRI; + w->rcount = ev->data; + } else { + /* TODO batch up */ + struct kevent events[1]; + EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); + if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (errno != ENOENT) + abort(); + } + } + if (ev->filter == EVFILT_WRITE) { if (w->pevents & POLLOUT) { revents |= POLLOUT; diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 2866e938545cb3..4d480ce10a2585 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -388,7 +388,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { * free when we switch over to edge-triggered I/O. */ if (pe->events == POLLERR || pe->events == POLLHUP) - pe->events |= w->pevents & (POLLIN | POLLOUT); + pe->events |= w->pevents & (POLLIN | POLLOUT | UV__POLLPRI); if (pe->events != 0) { /* Run signal watchers last. This also affects child process watchers @@ -837,7 +837,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } -static int uv__ifaddr_exclude(struct ifaddrs *ent) { +static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) return 1; if (ent->ifa_addr == NULL) @@ -847,8 +847,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent) { * devices. We're not interested in this information yet. */ if (ent->ifa_addr->sa_family == PF_PACKET) - return 1; - return 0; + return exclude_type; + return !exclude_type; } int uv_interface_addresses(uv_interface_address_t** addresses, @@ -869,7 +869,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; (*count)++; @@ -887,7 +887,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; address->name = uv__strdup(ent->ifa_name); @@ -911,7 +911,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (uv__ifaddr_exclude(ent)) + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) continue; address = *addresses; diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 9b5546b7e6959b..c54c04df28c201 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -124,9 +124,13 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { - if (process_title) uv__free(process_title); + char* new_title; - process_title = uv__strdup(title); + new_title = uv__strdup(title); + if (process_title == NULL) + return -ENOMEM; + uv__free(process_title); + process_title = new_title; setproctitle("%s", title); return 0; diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 56f0af15c3ef3f..d1c90289e5691e 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -146,8 +146,13 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { + char* new_title; + + new_title = uv__strdup(title); + if (process_title == NULL) + return -ENOMEM; uv__free(process_title); - process_title = uv__strdup(title); + process_title = new_title; setproctitle("%s", title); return 0; } diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 7edf2358d43a49..08623f4eafa137 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -183,33 +183,22 @@ int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, int pollret; int reventcount; - uv_mutex_lock(&global_epoll_lock); - uv_mutex_unlock(&global_epoll_lock); size = lst->size; pfds = lst->items; pollret = poll(pfds, size, timeout); - if(pollret == -1) + if (pollret <= 0) return pollret; reventcount = 0; - for (int i = 0; i < lst->size && i < maxevents; ++i) { + for (int i = 0; + i < lst->size && i < maxevents && reventcount < pollret; ++i) { struct epoll_event ev; - ev.events = 0; - ev.fd = pfds[i].fd; - if(!pfds[i].revents) + if (pfds[i].fd == -1 || pfds[i].revents == 0) continue; - if(pfds[i].revents & POLLRDNORM) - ev.events = ev.events | POLLIN; - - if(pfds[i].revents & POLLWRNORM) - ev.events = ev.events | POLLOUT; - - if(pfds[i].revents & POLLHUP) - ev.events = ev.events | POLLHUP; - - pfds[i].revents = 0; + ev.fd = pfds[i].fd; + ev.events = pfds[i].revents; events[reventcount++] = ev; } diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index de7df91169ad8f..559970de2c3d59 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -33,6 +33,7 @@ #endif #define CVT_PTR 0x10 +#define PSA_PTR 0x00 #define CSD_OFFSET 0x294 /* @@ -70,6 +71,18 @@ /* CPC model length from the CSRSI Service. */ #define CPCMODEL_LENGTH 16 +/* Pointer to the home (current) ASCB. */ +#define PSAAOLD 0x224 + +/* Pointer to rsm address space block extension. */ +#define ASCBRSME 0x16C + +/* + NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE. + It does not include 2G frames. +*/ +#define RAXFMCT 0x2C + /* Thread Entry constants */ #define PGTH_CURRENT 1 #define PGTH_LEN 26 @@ -77,6 +90,9 @@ #pragma linkage(BPX4GTH, OS) #pragma linkage(BPX1GTH, OS) +/* TOD Clock resolution in nanoseconds */ +#define TOD_RES 4.096 + typedef unsigned data_area_ptr_assign_type; typedef union { @@ -122,7 +138,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) { unsigned long long timestamp; __stckf(×tamp); /* Convert to nanoseconds */ - return timestamp / 10; + return timestamp / TOD_RES; } @@ -339,13 +355,17 @@ uint64_t uv_get_total_memory(void) { int uv_resident_set_memory(size_t* rss) { - W_PSPROC buf; + char* psa; + char* ascb; + char* rax; + size_t nframes; - memset(&buf, 0, sizeof(buf)); - if (w_getpsent(0, &buf, sizeof(W_PSPROC)) == -1) - return -EINVAL; + psa = PSA_PTR; + ascb = *(char* __ptr32 *)(psa + PSAAOLD); + rax = *(char* __ptr32 *)(ascb + ASCBRSME); + nframes = *(unsigned int*)(rax + RAXFMCT); - *rss = buf.ps_size; + *rss = nframes * sysconf(_SC_PAGESIZE); return 0; } @@ -747,9 +767,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { SAVE_ERRNO(uv__update_time(loop)); if (nfds == 0) { assert(timeout != -1); - timeout = real_timeout - timeout; - if (timeout > 0) + + if (timeout > 0) { + timeout = real_timeout - timeout; continue; + } return; } diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c index 370994bd572ceb..816c7dc2eb9e0b 100644 --- a/deps/uv/src/unix/poll.c +++ b/deps/uv/src/unix/poll.c @@ -33,8 +33,19 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { handle = container_of(w, uv_poll_t, io_watcher); - if (events & POLLERR) { - uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP); + /* + * As documented in the kernel source fs/kernfs/file.c #780 + * poll will return POLLERR|POLLPRI in case of sysfs + * polling. This does not happen in case of out-of-band + * TCP messages. + * + * The above is the case on (at least) FreeBSD and Linux. + * + * So to properly determine a POLLPRI or a POLLERR we need + * to check for both. + */ + if ((events & POLLERR) && !(events & UV__POLLPRI)) { + uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); uv__handle_stop(handle); handle->poll_cb(handle, -EBADF, 0); return; @@ -43,6 +54,8 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { pevents = 0; if (events & POLLIN) pevents |= UV_READABLE; + if (events & UV__POLLPRI) + pevents |= UV_PRIORITIZED; if (events & POLLOUT) pevents |= UV_WRITABLE; if (events & UV__POLLRDHUP) @@ -86,8 +99,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, static void uv__poll_stop(uv_poll_t* handle) { uv__io_stop(handle->loop, &handle->io_watcher, - POLLIN | POLLOUT | UV__POLLRDHUP); + POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); uv__handle_stop(handle); + uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd); } @@ -101,7 +115,8 @@ int uv_poll_stop(uv_poll_t* handle) { int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { int events; - assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0); + assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT | + UV_PRIORITIZED)) == 0); assert(!uv__is_closing(handle)); uv__poll_stop(handle); @@ -112,6 +127,8 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { events = 0; if (pevents & UV_READABLE) events |= POLLIN; + if (pevents & UV_PRIORITIZED) + events |= UV__POLLPRI; if (pevents & UV_WRITABLE) events |= POLLOUT; if (pevents & UV_DISCONNECT) diff --git a/deps/uv/src/unix/pthread-barrier.c b/deps/uv/src/unix/pthread-barrier.c deleted file mode 100644 index b6e604d46d825c..00000000000000 --- a/deps/uv/src/unix/pthread-barrier.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright (c) 2016, Kari Tristan Helgason - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#include "uv-common.h" -#include "pthread-barrier.h" - -#include -#include - -/* TODO: support barrier_attr */ -int pthread_barrier_init(pthread_barrier_t* barrier, - const void* barrier_attr, - unsigned count) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || count == 0) - return EINVAL; - - if (barrier_attr != NULL) - return ENOTSUP; - - b = uv__malloc(sizeof(*b)); - if (b == NULL) - return ENOMEM; - - b->in = 0; - b->out = 0; - b->threshold = count; - - if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0) - goto error2; - if ((rc = pthread_cond_init(&b->cond, NULL)) != 0) - goto error; - - barrier->b = b; - return 0; - -error: - pthread_mutex_destroy(&b->mutex); -error2: - uv__free(b); - return rc; -} - -int pthread_barrier_wait(pthread_barrier_t* barrier) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || barrier->b == NULL) - return EINVAL; - - b = barrier->b; - /* Lock the mutex*/ - if ((rc = pthread_mutex_lock(&b->mutex)) != 0) - return rc; - - /* Increment the count. If this is the first thread to reach the threshold, - wake up waiters, unlock the mutex, then return - PTHREAD_BARRIER_SERIAL_THREAD. */ - if (++b->in == b->threshold) { - b->in = 0; - b->out = b->threshold - 1; - rc = pthread_cond_signal(&b->cond); - assert(rc == 0); - - pthread_mutex_unlock(&b->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } - /* Otherwise, wait for other threads until in is set to 0, - then return 0 to indicate this is not the first thread. */ - do { - if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0) - break; - } while (b->in != 0); - - /* mark thread exit */ - b->out--; - pthread_cond_signal(&b->cond); - pthread_mutex_unlock(&b->mutex); - return rc; -} - -int pthread_barrier_destroy(pthread_barrier_t* barrier) { - int rc; - _uv_barrier* b; - - if (barrier == NULL || barrier->b == NULL) - return EINVAL; - - b = barrier->b; - - if ((rc = pthread_mutex_lock(&b->mutex)) != 0) - return rc; - - if (b->in > 0 || b->out > 0) - rc = EBUSY; - - pthread_mutex_unlock(&b->mutex); - - if (rc) - return rc; - - pthread_cond_destroy(&b->cond); - pthread_mutex_destroy(&b->mutex); - uv__free(barrier->b); - barrier->b = NULL; - return 0; -} diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c index a9b5e4c02a8e9a..f8846225910a80 100644 --- a/deps/uv/src/unix/thread.c +++ b/deps/uv/src/unix/thread.c @@ -41,6 +41,110 @@ #define NANOSEC ((uint64_t) 1e9) +#if defined(UV__PTHREAD_BARRIER_FALLBACK) +/* TODO: support barrier_attr */ +int pthread_barrier_init(pthread_barrier_t* barrier, + const void* barrier_attr, + unsigned count) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || count == 0) + return EINVAL; + + if (barrier_attr != NULL) + return ENOTSUP; + + b = uv__malloc(sizeof(*b)); + if (b == NULL) + return ENOMEM; + + b->in = 0; + b->out = 0; + b->threshold = count; + + if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0) + goto error2; + if ((rc = pthread_cond_init(&b->cond, NULL)) != 0) + goto error; + + barrier->b = b; + return 0; + +error: + pthread_mutex_destroy(&b->mutex); +error2: + uv__free(b); + return rc; +} + +int pthread_barrier_wait(pthread_barrier_t* barrier) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || barrier->b == NULL) + return EINVAL; + + b = barrier->b; + /* Lock the mutex*/ + if ((rc = pthread_mutex_lock(&b->mutex)) != 0) + return rc; + + /* Increment the count. If this is the first thread to reach the threshold, + wake up waiters, unlock the mutex, then return + PTHREAD_BARRIER_SERIAL_THREAD. */ + if (++b->in == b->threshold) { + b->in = 0; + b->out = b->threshold - 1; + rc = pthread_cond_signal(&b->cond); + assert(rc == 0); + + pthread_mutex_unlock(&b->mutex); + return PTHREAD_BARRIER_SERIAL_THREAD; + } + /* Otherwise, wait for other threads until in is set to 0, + then return 0 to indicate this is not the first thread. */ + do { + if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0) + break; + } while (b->in != 0); + + /* mark thread exit */ + b->out--; + pthread_cond_signal(&b->cond); + pthread_mutex_unlock(&b->mutex); + return rc; +} + +int pthread_barrier_destroy(pthread_barrier_t* barrier) { + int rc; + _uv_barrier* b; + + if (barrier == NULL || barrier->b == NULL) + return EINVAL; + + b = barrier->b; + + if ((rc = pthread_mutex_lock(&b->mutex)) != 0) + return rc; + + if (b->in > 0 || b->out > 0) + rc = EBUSY; + + pthread_mutex_unlock(&b->mutex); + + if (rc) + return rc; + + pthread_cond_destroy(&b->cond); + pthread_mutex_destroy(&b->mutex); + uv__free(barrier->b); + barrier->b = NULL; + return 0; +} +#endif + + int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { int err; pthread_attr_t* attr; @@ -283,16 +387,19 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) { uv_sem_t semid; struct sembuf buf; int err; + union { + int val; + struct semid_ds* buf; + unsigned short* array; + } arg; - buf.sem_num = 0; - buf.sem_op = value; - buf.sem_flg = 0; semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR); if (semid == -1) return -errno; - if (-1 == semop(semid, &buf, 1)) { + arg.val = value; + if (-1 == semctl(semid, 0, SETVAL, arg)) { err = errno; if (-1 == semctl(*sem, 0, IPC_RMID)) abort(); @@ -424,7 +531,7 @@ int uv_cond_init(uv_cond_t* cond) { if (err) return -err; -#if !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) +#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21) err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); if (err) goto error2; @@ -511,7 +618,8 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { timeout += uv__hrtime(UV_CLOCK_PRECISE); ts.tv_sec = timeout / NANOSEC; ts.tv_nsec = timeout % NANOSEC; -#if defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) +#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 + /* * The bionic pthread implementation doesn't support CLOCK_MONOTONIC, * but has this alternative function instead. @@ -519,7 +627,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts); #else r = pthread_cond_timedwait(cond, mutex, &ts); -#endif /* __ANDROID__ */ +#endif /* __ANDROID_API__ */ #endif diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c index 39e400ab2dbd19..d454014d8adf6e 100644 --- a/deps/uv/src/win/dl.c +++ b/deps/uv/src/win/dl.c @@ -22,7 +22,7 @@ #include "uv.h" #include "internal.h" -static int uv__dlerror(uv_lib_t* lib, int errorno); +static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno); int uv_dlopen(const char* filename, uv_lib_t* lib) { @@ -37,12 +37,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) { -1, filename_w, ARRAY_SIZE(filename_w))) { - return uv__dlerror(lib, GetLastError()); + return uv__dlerror(lib, filename, GetLastError()); } lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (lib->handle == NULL) { - return uv__dlerror(lib, GetLastError()); + return uv__dlerror(lib, filename, GetLastError()); } return 0; @@ -65,7 +65,7 @@ void uv_dlclose(uv_lib_t* lib) { int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { *ptr = (void*) GetProcAddress(lib->handle, name); - return uv__dlerror(lib, *ptr ? 0 : GetLastError()); + return uv__dlerror(lib, "", *ptr ? 0 : GetLastError()); } @@ -88,31 +88,46 @@ static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ -static int uv__dlerror(uv_lib_t* lib, int errorno) { +static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) { + static const char not_win32_app_msg[] = "%1 is not a valid Win32 application"; + DWORD_PTR arg; DWORD res; if (lib->errmsg) { - LocalFree((void*)lib->errmsg); + LocalFree(lib->errmsg); lib->errmsg = NULL; } - if (errorno) { + if (errorno == 0) + return 0; + + res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (LPSTR) &lib->errmsg, 0, NULL); + + if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) { res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPSTR) &lib->errmsg, 0, NULL); - if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) { - res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - 0, (LPSTR) &lib->errmsg, 0, NULL); - } - - if (!res) { - uv__format_fallback_error(lib, errorno); - } + 0, (LPSTR) &lib->errmsg, 0, NULL); + } + + /* Inexpert hack to get the filename into the error message. */ + if (res && strstr(lib->errmsg, not_win32_app_msg)) { + LocalFree(lib->errmsg); + lib->errmsg = NULL; + arg = (DWORD_PTR) filename; + res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_ARGUMENT_ARRAY | + FORMAT_MESSAGE_FROM_STRING, + not_win32_app_msg, + 0, 0, (LPSTR) &lib->errmsg, 0, (va_list*) &arg); } - return errorno ? -1 : 0; + if (!res) + uv__format_fallback_error(lib, errorno); + + return -1; } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 8223d6f655d1df..c374a82ca01f75 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -43,11 +43,26 @@ #define UV_FS_CLEANEDUP 0x0010 -#define QUEUE_FS_TP_JOB(loop, req) \ - do { \ - uv__req_register(loop, req); \ - uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \ - } while (0) +#define INIT(subtype) \ + do { \ + if (req == NULL) \ + return UV_EINVAL; \ + uv_fs_req_init(loop, req, subtype, cb); \ + } \ + while (0) + +#define POST \ + do { \ + if (cb != NULL) { \ + uv__req_register(loop, req); \ + uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \ + return 0; \ + } else { \ + uv__fs_work(&req->work_req); \ + return req->result; \ + } \ + } \ + while (0) #define SET_REQ_RESULT(req, result_value) \ do { \ @@ -113,6 +128,7 @@ const WCHAR LONG_PATH_PREFIX_LEN = 4; const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; const WCHAR UNC_PATH_PREFIX_LEN = 8; +static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; void uv_fs_init(void) { _fmode = _O_BINARY; @@ -220,6 +236,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type, const uv_fs_cb cb) { + uv__once_init(); UV_REQ_INIT(req, UV_FS); req->loop = loop; req->flags = 0; @@ -1118,8 +1135,6 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { */ if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) { statbuf->st_mode |= S_IFLNK; - } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) { - return -1; } } @@ -1333,6 +1348,22 @@ static void fs__ftruncate(uv_fs_t* req) { } +static void fs__copyfile(uv_fs_t* req) { + int flags; + int overwrite; + + flags = req->fs.info.file_flags; + overwrite = flags & UV_FS_COPYFILE_EXCL; + + if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + SET_REQ_RESULT(req, 0); +} + + static void fs__sendfile(uv_fs_t* req) { int fd_in = req->file.fd, fd_out = req->fs.info.fd_out; size_t length = req->fs.info.bufsml[0].len; @@ -1699,25 +1730,46 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path, static void fs__symlink(uv_fs_t* req) { - WCHAR* pathw = req->file.pathw; - WCHAR* new_pathw = req->fs.info.new_pathw; - int flags = req->fs.info.file_flags; - int result; + WCHAR* pathw; + WCHAR* new_pathw; + int flags; + int err; + pathw = req->file.pathw; + new_pathw = req->fs.info.new_pathw; - if (flags & UV_FS_SYMLINK_JUNCTION) { + if (req->fs.info.file_flags & UV_FS_SYMLINK_JUNCTION) { fs__create_junction(req, pathw, new_pathw); - } else if (pCreateSymbolicLinkW) { - result = pCreateSymbolicLinkW(new_pathw, - pathw, - flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } - } else { + return; + } + if (!pCreateSymbolicLinkW) { SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); + return; + } + + if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR) + flags = SYMBOLIC_LINK_FLAG_DIRECTORY; + else + flags = uv__file_symlink_usermode_flag; + + if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) { + SET_REQ_RESULT(req, 0); + return; + } + + /* Something went wrong. We will test if it is because of user-mode + * symlinks. + */ + err = GetLastError(); + if (err == ERROR_INVALID_PARAMETER && + flags & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) { + /* This system does not support user-mode symlinks. We will clear the + * unsupported flag and retry. + */ + uv__file_symlink_usermode_flag = 0; + fs__symlink(req); + } else { + SET_REQ_WIN32_ERROR(req, err); } } @@ -1855,6 +1907,7 @@ static void uv__fs_work(struct uv__work* w) { XX(CLOSE, close) XX(READ, read) XX(WRITE, write) + XX(COPYFILE, copyfile) XX(SENDFILE, sendfile) XX(STAT, stat) XX(LSTAT, lstat) @@ -1901,6 +1954,9 @@ static void uv__fs_done(struct uv__work* w, int status) { void uv_fs_req_cleanup(uv_fs_t* req) { + if (req == NULL) + return; + if (req->flags & UV_FS_CLEANEDUP) return; @@ -1931,8 +1987,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_OPEN, cb); - + INIT(UV_FS_OPEN); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); @@ -1940,28 +1995,14 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, req->fs.info.file_flags = flags; req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__open(req); - return req->result; - } + POST; } int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_CLOSE, cb); + INIT(UV_FS_CLOSE); req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__close(req); - return req->result; - } + POST; } @@ -1972,11 +2013,11 @@ int uv_fs_read(uv_loop_t* loop, unsigned int nbufs, int64_t offset, uv_fs_cb cb) { + INIT(UV_FS_READ); + if (bufs == NULL || nbufs == 0) return UV_EINVAL; - uv_fs_req_init(loop, req, UV_FS_READ, cb); - req->file.fd = fd; req->fs.info.nbufs = nbufs; @@ -1990,14 +2031,7 @@ int uv_fs_read(uv_loop_t* loop, memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__read(req); - return req->result; - } + POST; } @@ -2008,11 +2042,11 @@ int uv_fs_write(uv_loop_t* loop, unsigned int nbufs, int64_t offset, uv_fs_cb cb) { + INIT(UV_FS_WRITE); + if (bufs == NULL || nbufs == 0) return UV_EINVAL; - uv_fs_req_init(loop, req, UV_FS_WRITE, cb); - req->file.fd = fd; req->fs.info.nbufs = nbufs; @@ -2026,14 +2060,7 @@ int uv_fs_write(uv_loop_t* loop, memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__write(req); - return req->result; - } + POST; } @@ -2041,20 +2068,13 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_UNLINK, cb); - + INIT(UV_FS_UNLINK); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__unlink(req); - return req->result; - } + POST; } @@ -2062,22 +2082,14 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_MKDIR, cb); - + INIT(UV_FS_MKDIR); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdir(req); - return req->result; - } + POST; } @@ -2085,39 +2097,25 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb); - + INIT(UV_FS_MKDTEMP); err = fs__capture_path(req, tpl, NULL, TRUE); if (err) return uv_translate_sys_error(err); - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdtemp(req); - return req->result; - } + POST; } int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_RMDIR, cb); - + INIT(UV_FS_RMDIR); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rmdir(req); - return req->result; - } + POST; } @@ -2125,22 +2123,14 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb); - + INIT(UV_FS_SCANDIR); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__scandir(req); - return req->result; - } + POST; } @@ -2148,20 +2138,13 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_LINK, cb); - + INIT(UV_FS_LINK); err = fs__capture_path(req, path, new_path, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__link(req); - return req->result; - } + POST; } @@ -2169,22 +2152,14 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb); - + INIT(UV_FS_SYMLINK); err = fs__capture_path(req, path, new_path, cb != NULL); if (err) { return uv_translate_sys_error(err); } req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__symlink(req); - return req->result; - } + POST; } @@ -2192,20 +2167,13 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_READLINK, cb); - + INIT(UV_FS_READLINK); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__readlink(req); - return req->result; - } + POST; } @@ -2213,24 +2181,18 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - if (!req || !path) { + INIT(UV_FS_REALPATH); + + if (!path) { return UV_EINVAL; } - uv_fs_req_init(loop, req, UV_FS_REALPATH, cb); - err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__realpath(req); - return req->result; - } + POST; } @@ -2238,88 +2200,53 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_CHOWN, cb); - + INIT(UV_FS_CHOWN); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chown(req); - return req->result; - } + POST; } int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchown(req); - return req->result; - } + INIT(UV_FS_FCHOWN); + POST; } int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_STAT, cb); - + INIT(UV_FS_STAT); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__stat(req); - return req->result; - } + POST; } int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_LSTAT, cb); - + INIT(UV_FS_LSTAT); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__lstat(req); - return req->result; - } + POST; } int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSTAT, cb); + INIT(UV_FS_FSTAT); req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fstat(req); - return req->result; - } + POST; } @@ -2327,85 +2254,70 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_RENAME, cb); - + INIT(UV_FS_RENAME); err = fs__capture_path(req, path, new_path, cb != NULL); if (err) { return uv_translate_sys_error(err); } - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rename(req); - return req->result; - } + POST; } int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSYNC, cb); + INIT(UV_FS_FSYNC); req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fsync(req); - return req->result; - } + POST; } int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb); + INIT(UV_FS_FDATASYNC); req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fdatasync(req); - return req->result; - } + POST; } int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb); - + INIT(UV_FS_FTRUNCATE); req->file.fd = fd; req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__ftruncate(req); - return req->result; - } + POST; } +int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_COPYFILE); + + if (flags & ~UV_FS_COPYFILE_EXCL) + return UV_EINVAL; + + err = fs__capture_path(req, path, new_path, cb != NULL); + + if (err) + return uv_translate_sys_error(err); + + req->fs.info.file_flags = flags; + POST; +} + int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out, uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb); - + INIT(UV_FS_SENDFILE); req->file.fd = fd_in; req->fs.info.fd_out = fd_out; req->fs.info.offset = in_offset; req->fs.info.bufsml[0].len = length; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__sendfile(req); - return req->result; - } + POST; } @@ -2416,21 +2328,13 @@ int uv_fs_access(uv_loop_t* loop, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_ACCESS, cb); - + INIT(UV_FS_ACCESS); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) return uv_translate_sys_error(err); req->fs.info.mode = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } - - fs__access(req); - return req->result; + POST; } @@ -2438,39 +2342,23 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_CHMOD, cb); - + INIT(UV_FS_CHMOD); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); } req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chmod(req); - return req->result; - } + POST; } int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb); - + INIT(UV_FS_FCHMOD); req->file.fd = fd; req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchmod(req); - return req->result; - } + POST; } @@ -2478,8 +2366,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) { int err; - uv_fs_req_init(loop, req, UV_FS_UTIME, cb); - + INIT(UV_FS_UTIME); err = fs__capture_path(req, path, NULL, cb != NULL); if (err) { return uv_translate_sys_error(err); @@ -2487,30 +2374,15 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, req->fs.time.atime = atime; req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__utime(req); - return req->result; - } + POST; } int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime, double mtime, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FUTIME, cb); - + INIT(UV_FS_FUTIME); req->file.fd = fd; req->fs.time.atime = atime; req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__futime(req); - return req->result; - } + POST; } diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 9b10cc9fe22bf6..5c666788fd67f5 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -1913,6 +1913,7 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { if (os_handle == INVALID_HANDLE_VALUE) return UV_EBADF; + uv__once_init(); /* In order to avoid closing a stdio file descriptor 0-2, duplicate the * underlying OS handle and forget about the original fd. * We could also opt to use the original OS handle and just never close it, @@ -1986,6 +1987,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) unsigned int name_len; int err; + uv__once_init(); name_info = NULL; if (handle->handle == INVALID_HANDLE_VALUE) { diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index d141601607851b..97b67ca529582e 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -405,8 +405,15 @@ static WCHAR* search_path(const WCHAR *file, /* Next slice starts just after where the previous one ended */ dir_start = dir_end; + /* If path is quoted, find quote end */ + if (*dir_start == L'"' || *dir_start == L'\'') { + dir_end = wcschr(dir_start + 1, *dir_start); + if (dir_end == NULL) { + dir_end = wcschr(dir_start, L'\0'); + } + } /* Slice until the next ; or \0 is found */ - dir_end = wcschr(dir_start, L';'); + dir_end = wcschr(dir_end, L';'); if (dir_end == NULL) { dir_end = wcschr(dir_start, L'\0'); } diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 972539f4df49d0..e63a63e7712af1 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -1446,6 +1446,8 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { WSAPROTOCOL_INFOW protocol_info; int opt_len; int err; + struct sockaddr_storage saddr; + int saddr_len; /* Detect the address family of the socket. */ opt_len = (int) sizeof protocol_info; @@ -1466,6 +1468,19 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { return uv_translate_sys_error(err); } + /* Support already active socket. */ + saddr_len = sizeof(saddr); + if (!uv_tcp_getsockname(handle, (struct sockaddr*) &saddr, &saddr_len)) { + /* Socket is already bound. */ + handle->flags |= UV_HANDLE_BOUND; + saddr_len = sizeof(saddr); + if (!uv_tcp_getpeername(handle, (struct sockaddr*) &saddr, &saddr_len)) { + /* Socket is already connected. */ + uv_connection_init((uv_stream_t*) handle); + handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + } + } + return 0; } diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index a6f583956fe6b3..c4f99bdc7961b8 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -148,6 +148,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { HANDLE handle; CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; + uv__once_init(); handle = (HANDLE) uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) return UV_EBADF; diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index 9401676fbdc3ad..6c699bfe170c25 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4104,6 +4104,10 @@ # define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 #endif +#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x00000002 +#endif + /* from winternl.h */ typedef struct _UNICODE_STRING { USHORT Length; diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 0f1b56e777c6cb..d86fda3c5d7b8c 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -300,7 +300,6 @@ int process_reap(process_info_t *p) { void process_cleanup(process_info_t *p) { CloseHandle(p->process); CloseHandle(p->stdio_in); - CloseHandle(p->stdio_out); } diff --git a/deps/uv/test/test-dlerror.c b/deps/uv/test/test-dlerror.c index 091200edbed591..8f7697b594129c 100644 --- a/deps/uv/test/test-dlerror.c +++ b/deps/uv/test/test-dlerror.c @@ -42,11 +42,13 @@ TEST_IMPL(dlerror) { msg = uv_dlerror(&lib); ASSERT(msg != NULL); + ASSERT(strstr(msg, path) != NULL); ASSERT(strstr(msg, dlerror_no_error) == NULL); /* Should return the same error twice in a row. */ msg = uv_dlerror(&lib); ASSERT(msg != NULL); + ASSERT(strstr(msg, path) != NULL); ASSERT(strstr(msg, dlerror_no_error) == NULL); uv_dlclose(&lib); diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c new file mode 100644 index 00000000000000..2d1f9079a5f915 --- /dev/null +++ b/deps/uv/test/test-fs-copyfile.c @@ -0,0 +1,150 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#if defined(__unix__) || defined(__POSIX__) || \ + defined(__APPLE__) || defined(_AIX) || defined(__MVS__) +#include /* unlink, etc. */ +#else +# include +# include +# define unlink _unlink +#endif + +static const char fixture[] = "test/fixtures/load_error.node"; +static const char dst[] = "test_file_dst"; +static int result_check_count; + + +static void handle_result(uv_fs_t* req) { + uv_fs_t stat_req; + uint64_t size; + uint64_t mode; + int r; + + ASSERT(req->fs_type == UV_FS_COPYFILE); + ASSERT(req->result == 0); + + /* Verify that the file size and mode are the same. */ + r = uv_fs_stat(NULL, &stat_req, req->path, NULL); + ASSERT(r == 0); + size = stat_req.statbuf.st_size; + mode = stat_req.statbuf.st_mode; + uv_fs_req_cleanup(&stat_req); + r = uv_fs_stat(NULL, &stat_req, dst, NULL); + ASSERT(r == 0); + ASSERT(stat_req.statbuf.st_size == size); + ASSERT(stat_req.statbuf.st_mode == mode); + uv_fs_req_cleanup(&stat_req); + uv_fs_req_cleanup(req); + result_check_count++; +} + + +static void touch_file(const char* name, unsigned int size) { + uv_file file; + uv_fs_t req; + uv_buf_t buf; + int r; + unsigned int i; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r >= 0); + file = r; + + buf = uv_buf_init("a", 1); + + /* Inefficient but simple. */ + for (i = 0; i < size; i++) { + r = uv_fs_write(NULL, &req, file, &buf, 1, i, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r >= 0); + } + + r = uv_fs_close(NULL, &req, file, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r == 0); +} + + +TEST_IMPL(fs_copyfile) { + const char src[] = "test_file_src"; + uv_loop_t* loop; + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + /* Fails with EINVAL if bad flags are passed. */ + r = uv_fs_copyfile(NULL, &req, src, dst, -1, NULL); + ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&req); + + /* Fails with ENOENT if source does not exist. */ + unlink(src); + unlink(dst); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(req.result == UV_ENOENT); + ASSERT(r == UV_ENOENT); + uv_fs_req_cleanup(&req); + /* The destination should not exist. */ + r = uv_fs_stat(NULL, &req, dst, NULL); + ASSERT(r != 0); + uv_fs_req_cleanup(&req); + + /* Copies file synchronously. Creates new file. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies file synchronously. Overwrites existing file. */ + r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Fails to overwrites existing file. */ + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_EXCL, NULL); + ASSERT(r == UV_EEXIST); + uv_fs_req_cleanup(&req); + + /* Copies a larger file. */ + unlink(dst); + touch_file(src, 4096 * 2); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + unlink(src); + + /* Copies file asynchronously */ + unlink(dst); + r = uv_fs_copyfile(loop, &req, fixture, dst, 0, handle_result); + ASSERT(r == 0); + ASSERT(result_check_count == 3); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(result_check_count == 4); + unlink(dst); /* Cleanup */ + + return 0; +} diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 404d0426f38aed..0000e563a73ffc 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -1492,12 +1492,14 @@ TEST_IMPL(fs_chown) { uv_run(loop, UV_RUN_DEFAULT); ASSERT(chown_cb_count == 1); +#ifndef __MVS__ /* chown to root (fail) */ chown_cb_count = 0; r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); ASSERT(r == 0); uv_run(loop, UV_RUN_DEFAULT); ASSERT(chown_cb_count == 1); +#endif /* async fchown */ r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb); @@ -2749,19 +2751,23 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) { TEST_IMPL(fs_read_write_null_arguments) { int r; - r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL); + r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL); ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&read_req); - r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL); + r = uv_fs_write(NULL, &write_req, 0, NULL, 0, -1, NULL); ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&write_req); iov = uv_buf_init(NULL, 0); - r = uv_fs_read(NULL, NULL, 0, &iov, 0, -1, NULL); + r = uv_fs_read(NULL, &read_req, 0, &iov, 0, -1, NULL); ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&read_req); iov = uv_buf_init(NULL, 0); - r = uv_fs_write(NULL, NULL, 0, &iov, 0, -1, NULL); + r = uv_fs_write(NULL, &write_req, 0, &iov, 0, -1, NULL); ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&write_req); return 0; } @@ -2844,3 +2850,100 @@ TEST_IMPL(fs_file_pos_after_op_with_offset) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(fs_null_req) { + /* Verify that all fs functions return UV_EINVAL when the request is NULL. */ + int r; + + r = uv_fs_open(NULL, NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_close(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_unlink(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_mkdir(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_rmdir(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_scandir(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_link(NULL, NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_symlink(NULL, NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_readlink(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_realpath(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_chown(NULL, NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fchown(NULL, NULL, 0, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_stat(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_lstat(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fstat(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_rename(NULL, NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fsync(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fdatasync(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_ftruncate(NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_copyfile(NULL, NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_sendfile(NULL, NULL, 0, 0, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_access(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_chmod(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fchmod(NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_utime(NULL, NULL, NULL, 0.0, 0.0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL); + ASSERT(r == UV_EINVAL); + + /* This should be a no-op. */ + uv_fs_req_cleanup(NULL); + + return 0; +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 0c32d84d2038ba..6e84653e8b4f83 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -81,6 +81,8 @@ TEST_DECLARE (tcp_try_write) TEST_DECLARE (tcp_write_queue_order) TEST_DECLARE (tcp_open) TEST_DECLARE (tcp_open_twice) +TEST_DECLARE (tcp_open_bound) +TEST_DECLARE (tcp_open_connected) TEST_DECLARE (tcp_connect_error_after_write) TEST_DECLARE (tcp_shutdown_after_write) TEST_DECLARE (tcp_bind_error_addrinuse) @@ -256,6 +258,7 @@ TEST_DECLARE (spawn_auto_unref) TEST_DECLARE (spawn_closed_process_io) TEST_DECLARE (spawn_reads_child_path) TEST_DECLARE (spawn_inherit_streams) +TEST_DECLARE (spawn_quoted_path) TEST_DECLARE (fs_poll) TEST_DECLARE (fs_poll_getpath) TEST_DECLARE (kill) @@ -271,6 +274,7 @@ TEST_DECLARE (fs_mkdtemp) TEST_DECLARE (fs_fstat) TEST_DECLARE (fs_access) TEST_DECLARE (fs_chmod) +TEST_DECLARE (fs_copyfile) TEST_DECLARE (fs_unlink_readonly) TEST_DECLARE (fs_chown) TEST_DECLARE (fs_link) @@ -312,6 +316,7 @@ TEST_DECLARE (get_osfhandle_valid_handle) TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) TEST_DECLARE (fs_file_pos_after_op_with_offset) +TEST_DECLARE (fs_null_req) TEST_DECLARE (threadpool_queue_work_simple) TEST_DECLARE (threadpool_queue_work_einval) TEST_DECLARE (threadpool_multiple_event_loops) @@ -328,6 +333,10 @@ TEST_DECLARE (thread_rwlock_trylock) TEST_DECLARE (thread_create) TEST_DECLARE (thread_equal) TEST_DECLARE (dlerror) +#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \ + !defined(__sun) +TEST_DECLARE (poll_oob) +#endif TEST_DECLARE (poll_duplex) TEST_DECLARE (poll_unidirectional) TEST_DECLARE (poll_close) @@ -486,6 +495,9 @@ TASK_LIST_START TEST_ENTRY (tcp_open) TEST_HELPER (tcp_open, tcp4_echo_server) TEST_ENTRY (tcp_open_twice) + TEST_ENTRY (tcp_open_bound) + TEST_ENTRY (tcp_open_connected) + TEST_HELPER (tcp_open_connected, tcp4_echo_server) TEST_ENTRY (tcp_shutdown_after_write) TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server) @@ -681,6 +693,11 @@ TASK_LIST_START TEST_ENTRY (poll_unidirectional) TEST_ENTRY (poll_close) TEST_ENTRY (poll_bad_fdtype) +#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \ + !defined(__sun) + TEST_ENTRY (poll_oob) +#endif + #ifdef __linux__ TEST_ENTRY (poll_nested_epoll) #endif @@ -714,6 +731,7 @@ TASK_LIST_START TEST_ENTRY (spawn_closed_process_io) TEST_ENTRY (spawn_reads_child_path) TEST_ENTRY (spawn_inherit_streams) + TEST_ENTRY (spawn_quoted_path) TEST_ENTRY (fs_poll) TEST_ENTRY (fs_poll_getpath) TEST_ENTRY (kill) @@ -762,6 +780,7 @@ TASK_LIST_START TEST_ENTRY (fs_fstat) TEST_ENTRY (fs_access) TEST_ENTRY (fs_chmod) + TEST_ENTRY (fs_copyfile) TEST_ENTRY (fs_unlink_readonly) TEST_ENTRY (fs_chown) TEST_ENTRY (fs_utime) @@ -801,6 +820,7 @@ TASK_LIST_START TEST_ENTRY (fs_write_alotof_bufs_with_offset) TEST_ENTRY (fs_read_write_null_arguments) TEST_ENTRY (fs_file_pos_after_op_with_offset) + TEST_ENTRY (fs_null_req) TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) diff --git a/deps/uv/test/test-poll-oob.c b/deps/uv/test/test-poll-oob.c new file mode 100644 index 00000000000000..2a6da843c616ad --- /dev/null +++ b/deps/uv/test/test-poll-oob.c @@ -0,0 +1,205 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if !defined(_WIN32) + +#include "uv.h" +#include "task.h" + +#include +#include +#include +#include +#include + +static uv_tcp_t server_handle; +static uv_tcp_t client_handle; +static uv_tcp_t peer_handle; +static uv_poll_t poll_req[2]; +static uv_idle_t idle; +static uv_os_fd_t client_fd; +static uv_os_fd_t server_fd; +static int ticks; +static const int kMaxTicks = 10; +static int cli_pr_check = 0; +static int cli_rd_check = 0; +static int srv_rd_check = 0; + +static int got_eagain(void) { + return errno == EAGAIN + || errno == EINPROGRESS +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +#endif + ; +} + +static void idle_cb(uv_idle_t* idle) { + uv_sleep(100); + if (++ticks < kMaxTicks) + return; + + uv_poll_stop(&poll_req[0]); + uv_poll_stop(&poll_req[1]); + uv_close((uv_handle_t*) &server_handle, NULL); + uv_close((uv_handle_t*) &client_handle, NULL); + uv_close((uv_handle_t*) &peer_handle, NULL); + uv_close((uv_handle_t*) idle, NULL); +} + +static void poll_cb(uv_poll_t* handle, int status, int events) { + char buffer[5]; + int n; + int fd; + + ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); + memset(buffer, 0, 5); + + if (events & UV_PRIORITIZED) { + do + n = recv(client_fd, &buffer, 5, MSG_OOB); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + cli_pr_check = 1; + ASSERT(0 == uv_poll_stop(&poll_req[0])); + ASSERT(0 == uv_poll_start(&poll_req[0], + UV_READABLE | UV_WRITABLE, + poll_cb)); + } + if (events & UV_READABLE) { + if (fd == client_fd) { + do + n = recv(client_fd, &buffer, 5, 0); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + if (cli_rd_check == 1) { + ASSERT(strncmp(buffer, "world", n) == 0); + ASSERT(5 == n); + cli_rd_check = 2; + } + if (cli_rd_check == 0) { + ASSERT(n == 4); + ASSERT(strncmp(buffer, "hello", n) == 0); + cli_rd_check = 1; + do { + do + n = recv(server_fd, &buffer, 5, 0); + while (n == -1 && errno == EINTR); + if (n > 0) { + ASSERT(n == 5); + ASSERT(strncmp(buffer, "world", n) == 0); + cli_rd_check = 2; + } + } while (n > 0); + + ASSERT(got_eagain()); + } + } + if (fd == server_fd) { + do + n = recv(server_fd, &buffer, 3, 0); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + ASSERT(3 == n); + ASSERT(strncmp(buffer, "foo", n) == 0); + srv_rd_check = 1; + uv_poll_stop(&poll_req[1]); + } + } + if (events & UV_WRITABLE) { + do { + n = send(client_fd, "foo", 3, 0); + } while (n < 0 && errno == EINTR); + ASSERT(3 == n); + } +} + +static void connection_cb(uv_stream_t* handle, int status) { + int r; + + ASSERT(0 == status); + ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); + ASSERT(0 == uv_fileno((uv_handle_t*) &peer_handle, &server_fd)); + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[0], client_fd)); + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[1], server_fd)); + ASSERT(0 == uv_poll_start(&poll_req[0], + UV_PRIORITIZED | UV_READABLE | UV_WRITABLE, + poll_cb)); + ASSERT(0 == uv_poll_start(&poll_req[1], + UV_READABLE, + poll_cb)); + do { + r = send(server_fd, "hello", 5, MSG_OOB); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + do { + r = send(server_fd, "world", 5, 0); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + ASSERT(0 == uv_idle_start(&idle, idle_cb)); +} + + +TEST_IMPL(poll_oob) { + struct sockaddr_in addr; + int r = 0; + uv_loop_t* loop; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + ASSERT(0 == uv_tcp_init(loop, &server_handle)); + ASSERT(0 == uv_tcp_init(loop, &client_handle)); + ASSERT(0 == uv_tcp_init(loop, &peer_handle)); + ASSERT(0 == uv_idle_init(loop, &idle)); + ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); + + /* Ensure two separate packets */ + ASSERT(0 == uv_tcp_nodelay(&client_handle, 1)); + + client_fd = socket(PF_INET, SOCK_STREAM, 0); + ASSERT(client_fd >= 0); + do { + errno = 0; + r = connect(client_fd, (const struct sockaddr*)&addr, sizeof(addr)); + } while (r == -1 && errno == EINTR); + ASSERT(r == 0); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(ticks == kMaxTicks); + + /* Did client receive the POLLPRI message */ + ASSERT(cli_pr_check == 1); + /* Did client receive the POLLIN message */ + ASSERT(cli_rd_check == 2); + /* Could we write with POLLOUT and did the server receive our POLLOUT message + * through POLLIN. + */ + ASSERT(srv_rd_check == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index bb35e32b28a285..91d831e19b92fe 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -1,3 +1,4 @@ + /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -1350,10 +1351,14 @@ TEST_IMPL(spawn_setgid_fails) { init_process_options("spawn_helper1", fail_cb); options.flags |= UV_PROCESS_SETGID; +#if defined(__MVS__) + options.gid = -1; +#else options.gid = 0; +#endif r = uv_spawn(uv_default_loop(), &process, &options); -#if defined(__CYGWIN__) +#if defined(__CYGWIN__) || defined(__MVS__) ASSERT(r == UV_EINVAL); #else ASSERT(r == UV_EPERM); @@ -1711,6 +1716,31 @@ TEST_IMPL(spawn_inherit_streams) { return 0; } +TEST_IMPL(spawn_quoted_path) { +#ifndef _WIN32 + RETURN_SKIP("Test for Windows"); +#else + char* quoted_path_env[2]; + options.file = "not_existing"; + args[0] = options.file; + args[1] = NULL; + options.args = args; + options.exit_cb = exit_cb; + options.flags = 0; + /* We test if search_path works correctly with semicolons in quoted path. */ + /* We will use invalid drive, so we are sure no executable is spawned */ + quoted_path_env[0] = "PATH=\"xyz:\\test;\";xyz:\\other"; + quoted_path_env[1] = NULL; + options.env = quoted_path_env; + + /* We test if libuv will not segfault. */ + uv_spawn(uv_default_loop(), &process, &options); + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + /* Helper for child process of spawn_inherit_streams */ #ifndef _WIN32 int spawn_stdin_stdout(void) { diff --git a/deps/uv/test/test-tcp-oob.c b/deps/uv/test/test-tcp-oob.c index fc011ee495f1f6..4f1397a82ffed7 100644 --- a/deps/uv/test/test-tcp-oob.c +++ b/deps/uv/test/test-tcp-oob.c @@ -56,8 +56,21 @@ static void idle_cb(uv_idle_t* idle) { static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { +#ifdef __MVS__ + char lbuf[12]; +#endif + uv_os_fd_t fd; + ASSERT(nread > 0); + ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); ASSERT(0 == uv_idle_start(&idle, idle_cb)); + +#ifdef __MVS__ + /* Need to flush out the OOB data. Otherwise, this callback will get + * triggered on every poll with nread = 0. + */ + ASSERT(-1 != recv(fd, lbuf, sizeof(lbuf), MSG_OOB)); +#endif } diff --git a/deps/uv/test/test-tcp-open.c b/deps/uv/test/test-tcp-open.c index 6c8d43d0009e79..cb74c50e2c9929 100644 --- a/deps/uv/test/test-tcp-open.c +++ b/deps/uv/test/test-tcp-open.c @@ -218,3 +218,60 @@ TEST_IMPL(tcp_open_twice) { MAKE_VALGRIND_HAPPY(); return 0; } + + +TEST_IMPL(tcp_open_bound) { + struct sockaddr_in addr; + uv_tcp_t server; + uv_os_sock_t sock; + + startup(); + sock = create_tcp_socket(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + + ASSERT(0 == bind(sock, (struct sockaddr*) &addr, sizeof(addr))); + + ASSERT(0 == uv_tcp_open(&server, sock)); + + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, NULL)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_open_connected) { + struct sockaddr_in addr; + uv_tcp_t client; + uv_os_sock_t sock; + uv_buf_t buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_tcp_socket(); + + ASSERT(0 == connect(sock, (struct sockaddr*) &addr, sizeof(addr))); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + + ASSERT(0 == uv_tcp_open(&client, sock)); + + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &client, &buf, 1, write_cb)); + + ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb)); + + ASSERT(0 == uv_read_start((uv_stream_t*) &client, alloc_cb, read_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(shutdown_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 6f61d725a90b99..cac6da819b2196 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -217,8 +217,7 @@ 'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c', - 'src/unix/darwin-proctitle.c', - 'src/unix/pthread-barrier.c' + 'src/unix/darwin-proctitle.c' ], 'defines': [ '_DARWIN_USE_64_BIT_INODE=1', @@ -253,7 +252,6 @@ 'src/unix/linux-syscalls.h', 'src/unix/pthread-fixes.c', 'src/unix/android-ifaddrs.c', - 'src/unix/pthread-barrier.c', 'src/unix/procfs-exepath.c', 'src/unix/sysinfo-loadavg.c', 'src/unix/sysinfo-memory.c', @@ -322,7 +320,6 @@ ['OS=="os390"', { 'sources': [ 'src/unix/pthread-fixes.c', - 'src/unix/pthread-barrier.c', 'src/unix/no-fsevents.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c' @@ -362,6 +359,7 @@ 'test/test-fail-always.c', 'test/test-fork.c', 'test/test-fs.c', + 'test/test-fs-copyfile.c', 'test/test-fs-event.c', 'test/test-get-currentexe.c', 'test/test-get-memory.c', @@ -405,6 +403,7 @@ 'test/test-poll-close.c', 'test/test-poll-close-doesnt-corrupt-stack.c', 'test/test-poll-closesocket.c', + 'test/test-poll-oob.c', 'test/test-process-title.c', 'test/test-queue-foreach-delete.c', 'test/test-ref.c', diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat index e33573d108e16f..698044df490c02 100644 --- a/deps/uv/vcbuild.bat +++ b/deps/uv/vcbuild.bat @@ -43,6 +43,9 @@ shift goto next-arg :args-done +if defined WindowsSDKDir goto select-target +if defined VCINSTALLDIR goto select-target + @rem Look for Visual Studio 2017 only if explicitly requested. if "%target_env%" NEQ "vs2017" goto vs-set-2015 echo Looking for Visual Studio 2017 @@ -168,9 +171,7 @@ echo Failed to create vc project files. exit /b 1 :help - -echo "vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared]" - +echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared] echo Examples: echo vcbuild.bat : builds debug build echo vcbuild.bat test : builds debug build and runs tests From 4030c7e0775cf0cf5ab8bdcb4f46d8b5984fe47d Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 20 Aug 2017 00:04:43 -0400 Subject: [PATCH 027/128] test: update windows module load error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libuv 1.14.0 includes a fix for the "%1 is not a valid Win32 application" error message. Refs: https://github.com/nodejs/node/pull/14866 PR-URL: https://github.com/nodejs/node/pull/14950 Reviewed-By: Richard Lau Reviewed-By: Tobias Nießen Reviewed-By: Gibson Fahnestock Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- test/parallel/test-module-loading-error.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-module-loading-error.js b/test/parallel/test-module-loading-error.js index 80918d5fdb0eb3..ac709df19f58cf 100644 --- a/test/parallel/test-module-loading-error.js +++ b/test/parallel/test-module-loading-error.js @@ -2,17 +2,15 @@ const common = require('../common'); const assert = require('assert'); -console.error('load test-module-loading-error.js'); - -const error_desc = { - win32: ['%1 is not a valid Win32 application'], +const errorMessagesByPlatform = { + win32: ['is not a valid Win32 application'], linux: ['file too short', 'Exec format error'], sunos: ['unknown file type', 'not an ELF file'], darwin: ['file too short'], aix: ['Cannot load module', 'Cannot run a file that does not have a valid format.'] }; -const dlerror_msg = error_desc[process.platform]; +const dlerror_msg = errorMessagesByPlatform[process.platform]; if (!dlerror_msg) common.skip('platform not supported.'); From a0b38054d935d13e1acb2a23f417c3fb76e27156 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Wed, 24 May 2017 11:00:28 -0400 Subject: [PATCH 028/128] doc: make socket IPC examples more robust This commit aims to improve the documentation examples that send sockets over IPC channels. Specifically, pauseOnConnect is added to a server that inspects the socket before sending and a 'message' handler adds a check that the socket still exists. PR-URL: https://github.com/nodejs/node/pull/13196 Reviewed-By: Santiago Gimeno Reviewed-By: Refael Ackermann --- doc/api/child_process.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index d04f756eb7f140..c5f5dfe7c515c1 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -1052,8 +1052,9 @@ const { fork } = require('child_process'); const normal = fork('subprocess.js', ['normal']); const special = fork('subprocess.js', ['special']); -// Open up the server and send sockets to child -const server = require('net').createServer(); +// Open up the server and send sockets to child. Use pauseOnConnect to prevent +// the sockets from being read before they are sent to the child process. +const server = require('net').createServer({ pauseOnConnect: true }); server.on('connection', (socket) => { // If this is special priority @@ -1073,7 +1074,12 @@ passed to the event callback function: ```js process.on('message', (m, socket) => { if (m === 'socket') { - socket.end(`Request handled with ${process.argv[2]} priority`); + if (socket) { + // Check that the client socket exists. + // It is possible for the socket to be closed between the time it is + // sent and the time it is received in the child process. + socket.end(`Request handled with ${process.argv[2]} priority`); + } } }); ``` @@ -1083,6 +1089,10 @@ tracking when the socket is destroyed. To indicate this, the `.connections` property becomes `null`. It is recommended not to use `.maxConnections` when this occurs. +It is also recommended that any `'message'` handlers in the child process +verify that `socket` exists, as the connection may have been closed during the +time it takes to send the connection to the child. + *Note: this function uses [`JSON.stringify()`][] internally to serialize the `message`.* From f87a62699ba99c9367957dc2b62c1c0d02df929d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 6 Jul 2017 17:14:16 +0200 Subject: [PATCH 029/128] path: fix normalize on directories with two dots PR-URL: https://github.com/nodejs/node/pull/14107 Fixes: https://github.com/nodejs/node/issues/14105 Reviewed-By: Refael Ackermann --- lib/path.js | 14 ++++++++++++-- test/parallel/test-path.js | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/path.js b/lib/path.js index dc8a33f4996e5f..2d09eb595a2e2a 100644 --- a/lib/path.js +++ b/lib/path.js @@ -14,6 +14,7 @@ function normalizeStringWin32(path, allowAboveRoot) { var lastSlash = -1; var dots = 0; var code; + var isAboveRoot = false; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); @@ -25,7 +26,7 @@ function normalizeStringWin32(path, allowAboveRoot) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || + if (res.length < 2 || !isAboveRoot || res.charCodeAt(res.length - 1) !== 46/*.*/ || res.charCodeAt(res.length - 2) !== 46/*.*/) { if (res.length > 2) { @@ -42,12 +43,14 @@ function normalizeStringWin32(path, allowAboveRoot) { res = res.slice(0, j); lastSlash = i; dots = 0; + isAboveRoot = false; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; lastSlash = i; dots = 0; + isAboveRoot = false; continue; } } @@ -56,12 +59,14 @@ function normalizeStringWin32(path, allowAboveRoot) { res += '\\..'; else res = '..'; + isAboveRoot = true; } } else { if (res.length > 0) res += '\\' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); + isAboveRoot = false; } lastSlash = i; dots = 0; @@ -80,6 +85,7 @@ function normalizeStringPosix(path, allowAboveRoot) { var lastSlash = -1; var dots = 0; var code; + var isAboveRoot = false; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); @@ -91,7 +97,7 @@ function normalizeStringPosix(path, allowAboveRoot) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || + if (res.length < 2 || !isAboveRoot || res.charCodeAt(res.length - 1) !== 46/*.*/ || res.charCodeAt(res.length - 2) !== 46/*.*/) { if (res.length > 2) { @@ -108,12 +114,14 @@ function normalizeStringPosix(path, allowAboveRoot) { res = res.slice(0, j); lastSlash = i; dots = 0; + isAboveRoot = false; continue; } } else if (res.length === 2 || res.length === 1) { res = ''; lastSlash = i; dots = 0; + isAboveRoot = false; continue; } } @@ -122,12 +130,14 @@ function normalizeStringPosix(path, allowAboveRoot) { res += '/..'; else res = '..'; + isAboveRoot = true; } } else { if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); + isAboveRoot = false; } lastSlash = i; dots = 0; diff --git a/test/parallel/test-path.js b/test/parallel/test-path.js index 531b5d69e7b483..96d5f1709eac91 100644 --- a/test/parallel/test-path.js +++ b/test/parallel/test-path.js @@ -411,6 +411,11 @@ assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'), 'C:..\\..\\def'); assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\'); assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..'); assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), 'fixtures/b/c.js'); @@ -420,6 +425,11 @@ assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c'); assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b'); assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z'); assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/'); +assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz'); +assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../'); +assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..'); // path.resolve tests From 06ee10e52330c0498ed267408a5fe9ca1dfeecc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Wed, 30 Aug 2017 15:34:45 +0200 Subject: [PATCH 030/128] test: split path tests into multiple files Create one file for testing each function of the path module. Keep general error tests and tests for constant properties in test-path.js. PR-URL: https://github.com/nodejs/node/pull/15093 Reviewed-By: Colin Ihrig Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater Reviewed-By: Yuta Hiroto --- test/parallel/test-path-basename.js | 70 +++ test/parallel/test-path-dirname.js | 56 +++ test/parallel/test-path-extname.js | 99 +++++ test/parallel/test-path-isabsolute.js | 28 ++ test/parallel/test-path-join.js | 142 +++++++ test/parallel/test-path-makelong.js | 34 ++ test/parallel/test-path-normalize.js | 39 ++ test/parallel/test-path-relative.js | 67 +++ test/parallel/test-path-resolve.js | 70 +++ test/parallel/test-path.js | 587 -------------------------- 10 files changed, 605 insertions(+), 587 deletions(-) create mode 100644 test/parallel/test-path-basename.js create mode 100644 test/parallel/test-path-dirname.js create mode 100644 test/parallel/test-path-extname.js create mode 100644 test/parallel/test-path-isabsolute.js create mode 100644 test/parallel/test-path-join.js create mode 100644 test/parallel/test-path-normalize.js create mode 100644 test/parallel/test-path-relative.js create mode 100644 test/parallel/test-path-resolve.js diff --git a/test/parallel/test-path-basename.js b/test/parallel/test-path-basename.js new file mode 100644 index 00000000000000..6b64e40b7eca7a --- /dev/null +++ b/test/parallel/test-path-basename.js @@ -0,0 +1,70 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.basename(__filename), 'test-path-basename.js'); +assert.strictEqual(path.basename(__filename, '.js'), 'test-path-basename'); +assert.strictEqual(path.basename('.js', '.js'), ''); +assert.strictEqual(path.basename(''), ''); +assert.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('/basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext/'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext//'), 'basename.ext'); +assert.strictEqual(path.basename('aaa/bbb', '/bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'a/bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb//', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'bb'), 'b'); +assert.strictEqual(path.basename('aaa/bbb', 'b'), 'bb'); +assert.strictEqual(path.basename('/aaa/bbb', '/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'a/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb//', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'bb'), 'b'); +assert.strictEqual(path.basename('/aaa/bbb', 'b'), 'bb'); +assert.strictEqual(path.basename('/aaa/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/'), 'aaa'); +assert.strictEqual(path.basename('/aaa/b'), 'b'); +assert.strictEqual(path.basename('/a/b'), 'b'); +assert.strictEqual(path.basename('//a'), 'a'); + +// On Windows a backslash acts as a path separator. +assert.strictEqual(path.win32.basename('\\dir\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext\\\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('foo'), 'foo'); +assert.strictEqual(path.win32.basename('aaa\\bbb', '\\bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'a\\bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb\\\\\\\\', 'bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'bb'), 'b'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'b'), 'bb'); +assert.strictEqual(path.win32.basename('C:'), ''); +assert.strictEqual(path.win32.basename('C:.'), '.'); +assert.strictEqual(path.win32.basename('C:\\'), ''); +assert.strictEqual(path.win32.basename('C:\\dir\\base.ext'), 'base.ext'); +assert.strictEqual(path.win32.basename('C:\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext\\\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:foo'), 'foo'); +assert.strictEqual(path.win32.basename('file:stream'), 'file:stream'); + +// On unix a backslash is just treated as any other character. +assert.strictEqual(path.posix.basename('\\dir\\basename.ext'), + '\\dir\\basename.ext'); +assert.strictEqual(path.posix.basename('\\basename.ext'), '\\basename.ext'); +assert.strictEqual(path.posix.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.posix.basename('basename.ext\\'), 'basename.ext\\'); +assert.strictEqual(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\'); +assert.strictEqual(path.posix.basename('foo'), 'foo'); + +// POSIX filenames may include control characters +// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html +const controlCharFilename = `Icon${String.fromCharCode(13)}`; +assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`), + controlCharFilename); diff --git a/test/parallel/test-path-dirname.js b/test/parallel/test-path-dirname.js new file mode 100644 index 00000000000000..6ecb5c93b4db74 --- /dev/null +++ b/test/parallel/test-path-dirname.js @@ -0,0 +1,56 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.dirname(__filename).substr(-13), + common.isWindows ? 'test\\parallel' : 'test/parallel'); + +assert.strictEqual(path.posix.dirname('/a/b/'), '/a'); +assert.strictEqual(path.posix.dirname('/a/b'), '/a'); +assert.strictEqual(path.posix.dirname('/a'), '/'); +assert.strictEqual(path.posix.dirname(''), '.'); +assert.strictEqual(path.posix.dirname('/'), '/'); +assert.strictEqual(path.posix.dirname('////'), '/'); +assert.strictEqual(path.posix.dirname('//a'), '//'); +assert.strictEqual(path.posix.dirname('foo'), '.'); + +assert.strictEqual(path.win32.dirname('c:\\'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo\\'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar'), 'c:\\foo'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\'), 'c:\\foo'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar'); +assert.strictEqual(path.win32.dirname('\\'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo\\'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo\\bar'), '\\foo'); +assert.strictEqual(path.win32.dirname('\\foo\\bar\\'), '\\foo'); +assert.strictEqual(path.win32.dirname('\\foo\\bar\\baz'), '\\foo\\bar'); +assert.strictEqual(path.win32.dirname('c:'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo\\'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo\\bar'), 'c:foo'); +assert.strictEqual(path.win32.dirname('c:foo\\bar\\'), 'c:foo'); +assert.strictEqual(path.win32.dirname('c:foo\\bar\\baz'), 'c:foo\\bar'); +assert.strictEqual(path.win32.dirname('file:stream'), '.'); +assert.strictEqual(path.win32.dirname('dir\\file:stream'), 'dir'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share'), + '\\\\unc\\share'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo'), + '\\\\unc\\share\\'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\'), + '\\\\unc\\share\\'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar'), + '\\\\unc\\share\\foo'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'), + '\\\\unc\\share\\foo'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'), + '\\\\unc\\share\\foo\\bar'); +assert.strictEqual(path.win32.dirname('/a/b/'), '/a'); +assert.strictEqual(path.win32.dirname('/a/b'), '/a'); +assert.strictEqual(path.win32.dirname('/a'), '/'); +assert.strictEqual(path.win32.dirname(''), '.'); +assert.strictEqual(path.win32.dirname('/'), '/'); +assert.strictEqual(path.win32.dirname('////'), '/'); +assert.strictEqual(path.win32.dirname('foo'), '.'); diff --git a/test/parallel/test-path-extname.js b/test/parallel/test-path-extname.js new file mode 100644 index 00000000000000..47b327d370d78e --- /dev/null +++ b/test/parallel/test-path-extname.js @@ -0,0 +1,99 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; +const slashRE = /\//g; + +[ + [__filename, '.js'], + ['', ''], + ['/path/to/file', ''], + ['/path/to/file.ext', '.ext'], + ['/path.to/file.ext', '.ext'], + ['/path.to/file', ''], + ['/path.to/.file', ''], + ['/path.to/.file.ext', '.ext'], + ['/path/to/f.ext', '.ext'], + ['/path/to/..ext', '.ext'], + ['/path/to/..', ''], + ['file', ''], + ['file.ext', '.ext'], + ['.file', ''], + ['.file.ext', '.ext'], + ['/file', ''], + ['/file.ext', '.ext'], + ['/.file', ''], + ['/.file.ext', '.ext'], + ['.path/file.ext', '.ext'], + ['file.ext.ext', '.ext'], + ['file.', '.'], + ['.', ''], + ['./', ''], + ['.file.ext', '.ext'], + ['.file', ''], + ['.file.', '.'], + ['.file..', '.'], + ['..', ''], + ['../', ''], + ['..file.ext', '.ext'], + ['..file', '.file'], + ['..file.', '.'], + ['..file..', '.'], + ['...', '.'], + ['...ext', '.ext'], + ['....', '.'], + ['file.ext/', '.ext'], + ['file.ext//', '.ext'], + ['file/', ''], + ['file//', ''], + ['file./', '.'], + ['file.//', '.'], +].forEach((test) => { + const expected = test[1]; + [path.posix.extname, path.win32.extname].forEach((extname) => { + let input = test[0]; + let os; + if (extname === path.win32.extname) { + input = input.replace(slashRE, '\\'); + os = 'win32'; + } else { + os = 'posix'; + } + const actual = extname(input); + const message = `path.${os}.extname(${JSON.stringify(input)})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected) + failures.push(`\n${message}`); + }); + { + const input = `C:${test[0].replace(slashRE, '\\')}`; + const actual = path.win32.extname(input); + const message = `path.win32.extname(${JSON.stringify(input)})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected) + failures.push(`\n${message}`); + } +}); +assert.strictEqual(failures.length, 0, failures.join('')); + +// On Windows, backslash is a path separator. +assert.strictEqual(path.win32.extname('.\\'), ''); +assert.strictEqual(path.win32.extname('..\\'), ''); +assert.strictEqual(path.win32.extname('file.ext\\'), '.ext'); +assert.strictEqual(path.win32.extname('file.ext\\\\'), '.ext'); +assert.strictEqual(path.win32.extname('file\\'), ''); +assert.strictEqual(path.win32.extname('file\\\\'), ''); +assert.strictEqual(path.win32.extname('file.\\'), '.'); +assert.strictEqual(path.win32.extname('file.\\\\'), '.'); + +// On *nix, backslash is a valid name component like any other character. +assert.strictEqual(path.posix.extname('.\\'), ''); +assert.strictEqual(path.posix.extname('..\\'), '.\\'); +assert.strictEqual(path.posix.extname('file.ext\\'), '.ext\\'); +assert.strictEqual(path.posix.extname('file.ext\\\\'), '.ext\\\\'); +assert.strictEqual(path.posix.extname('file\\'), ''); +assert.strictEqual(path.posix.extname('file\\\\'), ''); +assert.strictEqual(path.posix.extname('file.\\'), '.\\'); +assert.strictEqual(path.posix.extname('file.\\\\'), '.\\\\'); diff --git a/test/parallel/test-path-isabsolute.js b/test/parallel/test-path-isabsolute.js new file mode 100644 index 00000000000000..66b4f1ee51103a --- /dev/null +++ b/test/parallel/test-path-isabsolute.js @@ -0,0 +1,28 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.win32.isAbsolute('/'), true); +assert.strictEqual(path.win32.isAbsolute('//'), true); +assert.strictEqual(path.win32.isAbsolute('//server'), true); +assert.strictEqual(path.win32.isAbsolute('//server/file'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\server\\file'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\server'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\'), true); +assert.strictEqual(path.win32.isAbsolute('c'), false); +assert.strictEqual(path.win32.isAbsolute('c:'), false); +assert.strictEqual(path.win32.isAbsolute('c:\\'), true); +assert.strictEqual(path.win32.isAbsolute('c:/'), true); +assert.strictEqual(path.win32.isAbsolute('c://'), true); +assert.strictEqual(path.win32.isAbsolute('C:/Users/'), true); +assert.strictEqual(path.win32.isAbsolute('C:\\Users\\'), true); +assert.strictEqual(path.win32.isAbsolute('C:cwd/another'), false); +assert.strictEqual(path.win32.isAbsolute('C:cwd\\another'), false); +assert.strictEqual(path.win32.isAbsolute('directory/directory'), false); +assert.strictEqual(path.win32.isAbsolute('directory\\directory'), false); + +assert.strictEqual(path.posix.isAbsolute('/home/foo'), true); +assert.strictEqual(path.posix.isAbsolute('/home/foo/..'), true); +assert.strictEqual(path.posix.isAbsolute('bar/'), false); +assert.strictEqual(path.posix.isAbsolute('./baz'), false); diff --git a/test/parallel/test-path-join.js b/test/parallel/test-path-join.js new file mode 100644 index 00000000000000..691ba98f9bc095 --- /dev/null +++ b/test/parallel/test-path-join.js @@ -0,0 +1,142 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; +const backslashRE = /\\/g; + +const joinTests = [ + [ [path.posix.join, path.win32.join], + // arguments result + [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], + [[], '.'], + [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], + [['/foo', '../../../bar'], '/bar'], + [['foo', '../../../bar'], '../../bar'], + [['foo/', '../../../bar'], '../../bar'], + [['foo/x', '../../../bar'], '../bar'], + [['foo/x', './bar'], 'foo/x/bar'], + [['foo/x/', './bar'], 'foo/x/bar'], + [['foo/x/', '.', 'bar'], 'foo/x/bar'], + [['./'], './'], + [['.', './'], './'], + [['.', '.', '.'], '.'], + [['.', './', '.'], '.'], + [['.', '/./', '.'], '.'], + [['.', '/////./', '.'], '.'], + [['.'], '.'], + [['', '.'], '.'], + [['', 'foo'], 'foo'], + [['foo', '/bar'], 'foo/bar'], + [['', '/foo'], '/foo'], + [['', '', '/foo'], '/foo'], + [['', '', 'foo'], 'foo'], + [['foo', ''], 'foo'], + [['foo/', ''], 'foo/'], + [['foo', '', '/bar'], 'foo/bar'], + [['./', '..', '/foo'], '../foo'], + [['./', '..', '..', '/foo'], '../../foo'], + [['.', '..', '..', '/foo'], '../../foo'], + [['', '..', '..', '/foo'], '../../foo'], + [['/'], '/'], + [['/', '.'], '/'], + [['/', '..'], '/'], + [['/', '..', '..'], '/'], + [[''], '.'], + [['', ''], '.'], + [[' /foo'], ' /foo'], + [[' ', 'foo'], ' /foo'], + [[' ', '.'], ' '], + [[' ', '/'], ' /'], + [[' ', ''], ' '], + [['/', 'foo'], '/foo'], + [['/', '/foo'], '/foo'], + [['/', '//foo'], '/foo'], + [['/', '', '/foo'], '/foo'], + [['', '/', 'foo'], '/foo'], + [['', '/', '/foo'], '/foo'] + ] + ] +]; + +// Windows-specific join tests +joinTests.push([ + path.win32.join, + joinTests[0][1].slice(0).concat( + [// arguments result + // UNC path expected + [['//foo/bar'], '\\\\foo\\bar\\'], + [['\\/foo/bar'], '\\\\foo\\bar\\'], + [['\\\\foo/bar'], '\\\\foo\\bar\\'], + // UNC path expected - server and share separate + [['//foo', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', 'bar'], '\\\\foo\\bar\\'], + [['//foo', '/bar'], '\\\\foo\\bar\\'], + // UNC path expected - questionable + [['//foo', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', '/bar'], '\\\\foo\\bar\\'], + // UNC path expected - even more questionable + [['', '//foo', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', '/bar'], '\\\\foo\\bar\\'], + // No UNC path expected (no double slash in first component) + [['\\', 'foo/bar'], '\\foo\\bar'], + [['\\', '/foo/bar'], '\\foo\\bar'], + [['', '/', '/foo/bar'], '\\foo\\bar'], + // No UNC path expected (no non-slashes in first component - + // questionable) + [['//', 'foo/bar'], '\\foo\\bar'], + [['//', '/foo/bar'], '\\foo\\bar'], + [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], + [['//'], '/'], + // No UNC path expected (share name missing - questionable). + [['//foo'], '\\foo'], + [['//foo/'], '\\foo\\'], + [['//foo', '/'], '\\foo\\'], + [['//foo', '', '/'], '\\foo\\'], + // No UNC path expected (too many leading slashes - questionable) + [['///foo/bar'], '\\foo\\bar'], + [['////foo', 'bar'], '\\foo\\bar'], + [['\\\\\\/foo/bar'], '\\foo\\bar'], + // Drive-relative vs drive-absolute paths. This merely describes the + // status quo, rather than being obviously right + [['c:'], 'c:.'], + [['c:.'], 'c:.'], + [['c:', ''], 'c:.'], + [['', 'c:'], 'c:.'], + [['c:.', '/'], 'c:.\\'], + [['c:.', 'file'], 'c:file'], + [['c:', '/'], 'c:\\'], + [['c:', 'file'], 'c:\\file'] + ] + ) +]); +joinTests.forEach((test) => { + if (!Array.isArray(test[0])) + test[0] = [test[0]]; + test[0].forEach((join) => { + test[1].forEach((test) => { + const actual = join.apply(null, test[0]); + const expected = test[1]; + // For non-Windows specific tests with the Windows join(), we need to try + // replacing the slashes since the non-Windows specific tests' `expected` + // use forward slashes + let actualAlt; + let os; + if (join === path.win32.join) { + actualAlt = actual.replace(backslashRE, '/'); + os = 'win32'; + } else { + os = 'posix'; + } + const message = + `path.${os}.join(${test[0].map(JSON.stringify).join(',')})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected && actualAlt !== expected) + failures.push(`\n${message}`); + }); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); diff --git a/test/parallel/test-path-makelong.js b/test/parallel/test-path-makelong.js index 769f81bdb81735..4e33d359e6cf11 100644 --- a/test/parallel/test-path-makelong.js +++ b/test/parallel/test-path-makelong.js @@ -23,3 +23,37 @@ assert.strictEqual(path._makeLong(100), 100); assert.strictEqual(path._makeLong(path), path); assert.strictEqual(path._makeLong(false), false); assert.strictEqual(path._makeLong(true), true); + +const emptyObj = {}; +assert.strictEqual(path.posix._makeLong('/foo/bar'), '/foo/bar'); +assert.strictEqual(path.posix._makeLong('foo/bar'), 'foo/bar'); +assert.strictEqual(path.posix._makeLong(null), null); +assert.strictEqual(path.posix._makeLong(true), true); +assert.strictEqual(path.posix._makeLong(1), 1); +assert.strictEqual(path.posix._makeLong(), undefined); +assert.strictEqual(path.posix._makeLong(emptyObj), emptyObj); +if (common.isWindows) { + // These tests cause resolve() to insert the cwd, so we cannot test them from + // non-Windows platforms (easily) + assert.strictEqual(path.win32._makeLong('foo\\bar').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); + assert.strictEqual(path.win32._makeLong('foo/bar').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); + const currentDeviceLetter = path.parse(process.cwd()).root.substring(0, 2); + assert.strictEqual(path.win32._makeLong(currentDeviceLetter).toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}`); + assert.strictEqual(path.win32._makeLong('C').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\c`); +} +assert.strictEqual(path.win32._makeLong('C:\\foo'), '\\\\?\\C:\\foo'); +assert.strictEqual(path.win32._makeLong('C:/foo'), '\\\\?\\C:\\foo'); +assert.strictEqual(path.win32._makeLong('\\\\foo\\bar'), + '\\\\?\\UNC\\foo\\bar\\'); +assert.strictEqual(path.win32._makeLong('//foo//bar'), + '\\\\?\\UNC\\foo\\bar\\'); +assert.strictEqual(path.win32._makeLong('\\\\?\\foo'), '\\\\?\\foo'); +assert.strictEqual(path.win32._makeLong(null), null); +assert.strictEqual(path.win32._makeLong(true), true); +assert.strictEqual(path.win32._makeLong(1), 1); +assert.strictEqual(path.win32._makeLong(), undefined); +assert.strictEqual(path.win32._makeLong(emptyObj), emptyObj); diff --git a/test/parallel/test-path-normalize.js b/test/parallel/test-path-normalize.js new file mode 100644 index 00000000000000..db91432b3e0955 --- /dev/null +++ b/test/parallel/test-path-normalize.js @@ -0,0 +1,39 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.win32.normalize('./fixtures///b/../b/c.js'), + 'fixtures\\b\\c.js'); +assert.strictEqual(path.win32.normalize('/foo/../../../bar'), '\\bar'); +assert.strictEqual(path.win32.normalize('a//b//../b'), 'a\\b'); +assert.strictEqual(path.win32.normalize('a//b//./c'), 'a\\b\\c'); +assert.strictEqual(path.win32.normalize('a//b//.'), 'a\\b'); +assert.strictEqual(path.win32.normalize('//server/share/dir/file.ext'), + '\\\\server\\share\\dir\\file.ext'); +assert.strictEqual(path.win32.normalize('/a/b/c/../../../x/y/z'), '\\x\\y\\z'); +assert.strictEqual(path.win32.normalize('C:'), 'C:.'); +assert.strictEqual(path.win32.normalize('C:..\\abc'), 'C:..\\abc'); +assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'), + 'C:..\\..\\def'); +assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\'); +assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..'); + +assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), + 'fixtures/b/c.js'); +assert.strictEqual(path.posix.normalize('/foo/../../../bar'), '/bar'); +assert.strictEqual(path.posix.normalize('a//b//../b'), 'a/b'); +assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c'); +assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b'); +assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z'); +assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/'); +assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz'); +assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../'); +assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..'); diff --git a/test/parallel/test-path-relative.js b/test/parallel/test-path-relative.js new file mode 100644 index 00000000000000..bd2c3f75a52dd2 --- /dev/null +++ b/test/parallel/test-path-relative.js @@ -0,0 +1,67 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; + +const relativeTests = [ + [ path.win32.relative, + // arguments result + [['c:/blah\\blah', 'd:/games', 'd:\\games'], + ['c:/aaaa/bbbb', 'c:/aaaa', '..'], + ['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'], + ['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'], + ['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'], + ['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'], + ['c:/aaaa/bbbb', 'd:\\', 'd:\\'], + ['c:/AaAa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaaa/', 'c:/aaaa/cccc', '..\\aaaa\\cccc'], + ['C:\\foo\\bar\\baz\\quux', 'C:\\', '..\\..\\..\\..'], + ['C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json', 'bar\\package.json'], + ['C:\\foo\\bar\\baz-quux', 'C:\\foo\\bar\\baz', '..\\baz'], + ['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz-quux', '..\\baz-quux'], + ['\\\\foo\\bar', '\\\\foo\\bar\\baz', 'baz'], + ['\\\\foo\\bar\\baz', '\\\\foo\\bar', '..'], + ['\\\\foo\\bar\\baz-quux', '\\\\foo\\bar\\baz', '..\\baz'], + ['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'], + ['C:\\baz-quux', 'C:\\baz', '..\\baz'], + ['C:\\baz', 'C:\\baz-quux', '..\\baz-quux'], + ['\\\\foo\\baz-quux', '\\\\foo\\baz', '..\\baz'], + ['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'], + ['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'], + ['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'] + ] + ], + [ path.posix.relative, + // arguments result + [['/var/lib', '/var', '..'], + ['/var/lib', '/bin', '../../bin'], + ['/var/lib', '/var/lib', ''], + ['/var/lib', '/var/apache', '../apache'], + ['/var/', '/var/lib', 'lib'], + ['/', '/var/lib', 'var/lib'], + ['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'], + ['/Users/a/web/b/test/mails', '/Users/a/web/b', '../..'], + ['/foo/bar/baz-quux', '/foo/bar/baz', '../baz'], + ['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'], + ['/baz-quux', '/baz', '../baz'], + ['/baz', '/baz-quux', '../baz-quux'] + ] + ] +]; +relativeTests.forEach((test) => { + const relative = test[0]; + test[1].forEach((test) => { + const actual = relative(test[0], test[1]); + const expected = test[2]; + const os = relative === path.win32.relative ? 'win32' : 'posix'; + const message = `path.${os}.relative(${ + test.slice(0, 2).map(JSON.stringify).join(',')})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected) + failures.push(`\n${message}`); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); diff --git a/test/parallel/test-path-resolve.js b/test/parallel/test-path-resolve.js new file mode 100644 index 00000000000000..91a2807648fa40 --- /dev/null +++ b/test/parallel/test-path-resolve.js @@ -0,0 +1,70 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const child = require('child_process'); +const path = require('path'); + +const failures = []; +const slashRE = /\//g; +const backslashRE = /\\/g; + +const resolveTests = [ + [ path.win32.resolve, + // arguments result + [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], + [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], + [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], + [['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'], + [['.'], process.cwd()], + [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'], + [['c:/', '//'], 'c:\\'], + [['c:/', '//dir'], 'c:\\dir'], + [['c:/', '//server/share'], '\\\\server\\share\\'], + [['c:/', '//server//share'], '\\\\server\\share\\'], + [['c:/', '///some//dir'], 'c:\\some\\dir'], + [['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'], + 'C:\\foo\\tmp.3\\cycles\\root.js'] + ] + ], + [ path.posix.resolve, + // arguments result + [[['/var/lib', '../', 'file/'], '/var/file'], + [['/var/lib', '/../', 'file/'], '/file'], + [['a/b/c/', '../../..'], process.cwd()], + [['.'], process.cwd()], + [['/some/dir', '.', '/absolute/'], '/absolute'], + [['/foo/tmp.3/', '../tmp.3/cycles/root.js'], '/foo/tmp.3/cycles/root.js'] + ] + ] +]; +resolveTests.forEach((test) => { + const resolve = test[0]; + test[1].forEach((test) => { + const actual = resolve.apply(null, test[0]); + let actualAlt; + const os = resolve === path.win32.resolve ? 'win32' : 'posix'; + if (resolve === path.win32.resolve && !common.isWindows) + actualAlt = actual.replace(backslashRE, '/'); + else if (resolve !== path.win32.resolve && common.isWindows) + actualAlt = actual.replace(slashRE, '\\'); + + const expected = test[1]; + const message = + `path.${os}.resolve(${test[0].map(JSON.stringify).join(',')})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected && actualAlt !== expected) + failures.push(`\n${message}`); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); + +if (common.isWindows) { + // Test resolving the current Windows drive letter from a spawned process. + // See https://github.com/nodejs/node/issues/7215 + const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 2); + const resolveFixture = path.join(common.fixturesDir, 'path-resolve.js'); + const spawnResult = child.spawnSync( + process.argv[0], [resolveFixture, currentDriveLetter]); + const resolvedPath = spawnResult.stdout.toString().trim(); + assert.strictEqual(resolvedPath.toLowerCase(), process.cwd().toLowerCase()); +} diff --git a/test/parallel/test-path.js b/test/parallel/test-path.js index 96d5f1709eac91..18eedbeb076681 100644 --- a/test/parallel/test-path.js +++ b/test/parallel/test-path.js @@ -1,368 +1,8 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); -const child = require('child_process'); const path = require('path'); -const f = __filename; -const failures = []; - -const slashRE = /\//g; -const backslashRE = /\\/g; - -// path.basename tests -assert.strictEqual(path.basename(f), 'test-path.js'); -assert.strictEqual(path.basename(f, '.js'), 'test-path'); -assert.strictEqual(path.basename('.js', '.js'), ''); -assert.strictEqual(path.basename(''), ''); -assert.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext'); -assert.strictEqual(path.basename('/basename.ext'), 'basename.ext'); -assert.strictEqual(path.basename('basename.ext'), 'basename.ext'); -assert.strictEqual(path.basename('basename.ext/'), 'basename.ext'); -assert.strictEqual(path.basename('basename.ext//'), 'basename.ext'); -assert.strictEqual(path.basename('aaa/bbb', '/bbb'), 'bbb'); -assert.strictEqual(path.basename('aaa/bbb', 'a/bbb'), 'bbb'); -assert.strictEqual(path.basename('aaa/bbb', 'bbb'), 'bbb'); -assert.strictEqual(path.basename('aaa/bbb//', 'bbb'), 'bbb'); -assert.strictEqual(path.basename('aaa/bbb', 'bb'), 'b'); -assert.strictEqual(path.basename('aaa/bbb', 'b'), 'bb'); -assert.strictEqual(path.basename('/aaa/bbb', '/bbb'), 'bbb'); -assert.strictEqual(path.basename('/aaa/bbb', 'a/bbb'), 'bbb'); -assert.strictEqual(path.basename('/aaa/bbb', 'bbb'), 'bbb'); -assert.strictEqual(path.basename('/aaa/bbb//', 'bbb'), 'bbb'); -assert.strictEqual(path.basename('/aaa/bbb', 'bb'), 'b'); -assert.strictEqual(path.basename('/aaa/bbb', 'b'), 'bb'); -assert.strictEqual(path.basename('/aaa/bbb'), 'bbb'); -assert.strictEqual(path.basename('/aaa/'), 'aaa'); -assert.strictEqual(path.basename('/aaa/b'), 'b'); -assert.strictEqual(path.basename('/a/b'), 'b'); -assert.strictEqual(path.basename('//a'), 'a'); - -// On Windows a backslash acts as a path separator. -assert.strictEqual(path.win32.basename('\\dir\\basename.ext'), 'basename.ext'); -assert.strictEqual(path.win32.basename('\\basename.ext'), 'basename.ext'); -assert.strictEqual(path.win32.basename('basename.ext'), 'basename.ext'); -assert.strictEqual(path.win32.basename('basename.ext\\'), 'basename.ext'); -assert.strictEqual(path.win32.basename('basename.ext\\\\'), 'basename.ext'); -assert.strictEqual(path.win32.basename('foo'), 'foo'); -assert.strictEqual(path.win32.basename('aaa\\bbb', '\\bbb'), 'bbb'); -assert.strictEqual(path.win32.basename('aaa\\bbb', 'a\\bbb'), 'bbb'); -assert.strictEqual(path.win32.basename('aaa\\bbb', 'bbb'), 'bbb'); -assert.strictEqual(path.win32.basename('aaa\\bbb\\\\\\\\', 'bbb'), 'bbb'); -assert.strictEqual(path.win32.basename('aaa\\bbb', 'bb'), 'b'); -assert.strictEqual(path.win32.basename('aaa\\bbb', 'b'), 'bb'); -assert.strictEqual(path.win32.basename('C:'), ''); -assert.strictEqual(path.win32.basename('C:.'), '.'); -assert.strictEqual(path.win32.basename('C:\\'), ''); -assert.strictEqual(path.win32.basename('C:\\dir\\base.ext'), 'base.ext'); -assert.strictEqual(path.win32.basename('C:\\basename.ext'), 'basename.ext'); -assert.strictEqual(path.win32.basename('C:basename.ext'), 'basename.ext'); -assert.strictEqual(path.win32.basename('C:basename.ext\\'), 'basename.ext'); -assert.strictEqual(path.win32.basename('C:basename.ext\\\\'), 'basename.ext'); -assert.strictEqual(path.win32.basename('C:foo'), 'foo'); -assert.strictEqual(path.win32.basename('file:stream'), 'file:stream'); - -// On unix a backslash is just treated as any other character. -assert.strictEqual(path.posix.basename('\\dir\\basename.ext'), - '\\dir\\basename.ext'); -assert.strictEqual(path.posix.basename('\\basename.ext'), '\\basename.ext'); -assert.strictEqual(path.posix.basename('basename.ext'), 'basename.ext'); -assert.strictEqual(path.posix.basename('basename.ext\\'), 'basename.ext\\'); -assert.strictEqual(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\'); -assert.strictEqual(path.posix.basename('foo'), 'foo'); - -// POSIX filenames may include control characters -// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html -const controlCharFilename = `Icon${String.fromCharCode(13)}`; -assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`), - controlCharFilename); - - -// path.dirname tests -assert.strictEqual(path.dirname(f).substr(-13), - common.isWindows ? 'test\\parallel' : 'test/parallel'); - -assert.strictEqual(path.posix.dirname('/a/b/'), '/a'); -assert.strictEqual(path.posix.dirname('/a/b'), '/a'); -assert.strictEqual(path.posix.dirname('/a'), '/'); -assert.strictEqual(path.posix.dirname(''), '.'); -assert.strictEqual(path.posix.dirname('/'), '/'); -assert.strictEqual(path.posix.dirname('////'), '/'); -assert.strictEqual(path.posix.dirname('//a'), '//'); -assert.strictEqual(path.posix.dirname('foo'), '.'); - -assert.strictEqual(path.win32.dirname('c:\\'), 'c:\\'); -assert.strictEqual(path.win32.dirname('c:\\foo'), 'c:\\'); -assert.strictEqual(path.win32.dirname('c:\\foo\\'), 'c:\\'); -assert.strictEqual(path.win32.dirname('c:\\foo\\bar'), 'c:\\foo'); -assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\'), 'c:\\foo'); -assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar'); -assert.strictEqual(path.win32.dirname('\\'), '\\'); -assert.strictEqual(path.win32.dirname('\\foo'), '\\'); -assert.strictEqual(path.win32.dirname('\\foo\\'), '\\'); -assert.strictEqual(path.win32.dirname('\\foo\\bar'), '\\foo'); -assert.strictEqual(path.win32.dirname('\\foo\\bar\\'), '\\foo'); -assert.strictEqual(path.win32.dirname('\\foo\\bar\\baz'), '\\foo\\bar'); -assert.strictEqual(path.win32.dirname('c:'), 'c:'); -assert.strictEqual(path.win32.dirname('c:foo'), 'c:'); -assert.strictEqual(path.win32.dirname('c:foo\\'), 'c:'); -assert.strictEqual(path.win32.dirname('c:foo\\bar'), 'c:foo'); -assert.strictEqual(path.win32.dirname('c:foo\\bar\\'), 'c:foo'); -assert.strictEqual(path.win32.dirname('c:foo\\bar\\baz'), 'c:foo\\bar'); -assert.strictEqual(path.win32.dirname('file:stream'), '.'); -assert.strictEqual(path.win32.dirname('dir\\file:stream'), 'dir'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share'), - '\\\\unc\\share'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo'), - '\\\\unc\\share\\'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\'), - '\\\\unc\\share\\'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar'), - '\\\\unc\\share\\foo'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'), - '\\\\unc\\share\\foo'); -assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'), - '\\\\unc\\share\\foo\\bar'); -assert.strictEqual(path.win32.dirname('/a/b/'), '/a'); -assert.strictEqual(path.win32.dirname('/a/b'), '/a'); -assert.strictEqual(path.win32.dirname('/a'), '/'); -assert.strictEqual(path.win32.dirname(''), '.'); -assert.strictEqual(path.win32.dirname('/'), '/'); -assert.strictEqual(path.win32.dirname('////'), '/'); -assert.strictEqual(path.win32.dirname('foo'), '.'); - - -// path.extname tests -[ - [f, '.js'], - ['', ''], - ['/path/to/file', ''], - ['/path/to/file.ext', '.ext'], - ['/path.to/file.ext', '.ext'], - ['/path.to/file', ''], - ['/path.to/.file', ''], - ['/path.to/.file.ext', '.ext'], - ['/path/to/f.ext', '.ext'], - ['/path/to/..ext', '.ext'], - ['/path/to/..', ''], - ['file', ''], - ['file.ext', '.ext'], - ['.file', ''], - ['.file.ext', '.ext'], - ['/file', ''], - ['/file.ext', '.ext'], - ['/.file', ''], - ['/.file.ext', '.ext'], - ['.path/file.ext', '.ext'], - ['file.ext.ext', '.ext'], - ['file.', '.'], - ['.', ''], - ['./', ''], - ['.file.ext', '.ext'], - ['.file', ''], - ['.file.', '.'], - ['.file..', '.'], - ['..', ''], - ['../', ''], - ['..file.ext', '.ext'], - ['..file', '.file'], - ['..file.', '.'], - ['..file..', '.'], - ['...', '.'], - ['...ext', '.ext'], - ['....', '.'], - ['file.ext/', '.ext'], - ['file.ext//', '.ext'], - ['file/', ''], - ['file//', ''], - ['file./', '.'], - ['file.//', '.'], -].forEach((test) => { - const expected = test[1]; - [path.posix.extname, path.win32.extname].forEach((extname) => { - let input = test[0]; - let os; - if (extname === path.win32.extname) { - input = input.replace(slashRE, '\\'); - os = 'win32'; - } else { - os = 'posix'; - } - const actual = extname(input); - const message = `path.${os}.extname(${JSON.stringify(input)})\n expect=${ - JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; - if (actual !== expected) - failures.push(`\n${message}`); - }); - { - const input = `C:${test[0].replace(slashRE, '\\')}`; - const actual = path.win32.extname(input); - const message = `path.win32.extname(${JSON.stringify(input)})\n expect=${ - JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; - if (actual !== expected) - failures.push(`\n${message}`); - } -}); -assert.strictEqual(failures.length, 0, failures.join('')); - -// On Windows, backslash is a path separator. -assert.strictEqual(path.win32.extname('.\\'), ''); -assert.strictEqual(path.win32.extname('..\\'), ''); -assert.strictEqual(path.win32.extname('file.ext\\'), '.ext'); -assert.strictEqual(path.win32.extname('file.ext\\\\'), '.ext'); -assert.strictEqual(path.win32.extname('file\\'), ''); -assert.strictEqual(path.win32.extname('file\\\\'), ''); -assert.strictEqual(path.win32.extname('file.\\'), '.'); -assert.strictEqual(path.win32.extname('file.\\\\'), '.'); - -// On *nix, backslash is a valid name component like any other character. -assert.strictEqual(path.posix.extname('.\\'), ''); -assert.strictEqual(path.posix.extname('..\\'), '.\\'); -assert.strictEqual(path.posix.extname('file.ext\\'), '.ext\\'); -assert.strictEqual(path.posix.extname('file.ext\\\\'), '.ext\\\\'); -assert.strictEqual(path.posix.extname('file\\'), ''); -assert.strictEqual(path.posix.extname('file\\\\'), ''); -assert.strictEqual(path.posix.extname('file.\\'), '.\\'); -assert.strictEqual(path.posix.extname('file.\\\\'), '.\\\\'); - - -// path.join tests -const joinTests = [ - [ [path.posix.join, path.win32.join], - // arguments result - [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], - [[], '.'], - [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], - [['/foo', '../../../bar'], '/bar'], - [['foo', '../../../bar'], '../../bar'], - [['foo/', '../../../bar'], '../../bar'], - [['foo/x', '../../../bar'], '../bar'], - [['foo/x', './bar'], 'foo/x/bar'], - [['foo/x/', './bar'], 'foo/x/bar'], - [['foo/x/', '.', 'bar'], 'foo/x/bar'], - [['./'], './'], - [['.', './'], './'], - [['.', '.', '.'], '.'], - [['.', './', '.'], '.'], - [['.', '/./', '.'], '.'], - [['.', '/////./', '.'], '.'], - [['.'], '.'], - [['', '.'], '.'], - [['', 'foo'], 'foo'], - [['foo', '/bar'], 'foo/bar'], - [['', '/foo'], '/foo'], - [['', '', '/foo'], '/foo'], - [['', '', 'foo'], 'foo'], - [['foo', ''], 'foo'], - [['foo/', ''], 'foo/'], - [['foo', '', '/bar'], 'foo/bar'], - [['./', '..', '/foo'], '../foo'], - [['./', '..', '..', '/foo'], '../../foo'], - [['.', '..', '..', '/foo'], '../../foo'], - [['', '..', '..', '/foo'], '../../foo'], - [['/'], '/'], - [['/', '.'], '/'], - [['/', '..'], '/'], - [['/', '..', '..'], '/'], - [[''], '.'], - [['', ''], '.'], - [[' /foo'], ' /foo'], - [[' ', 'foo'], ' /foo'], - [[' ', '.'], ' '], - [[' ', '/'], ' /'], - [[' ', ''], ' '], - [['/', 'foo'], '/foo'], - [['/', '/foo'], '/foo'], - [['/', '//foo'], '/foo'], - [['/', '', '/foo'], '/foo'], - [['', '/', 'foo'], '/foo'], - [['', '/', '/foo'], '/foo'] - ] - ] -]; - -// Windows-specific join tests -joinTests.push([ - path.win32.join, - joinTests[0][1].slice(0).concat( - [// arguments result - // UNC path expected - [['//foo/bar'], '\\\\foo\\bar\\'], - [['\\/foo/bar'], '\\\\foo\\bar\\'], - [['\\\\foo/bar'], '\\\\foo\\bar\\'], - // UNC path expected - server and share separate - [['//foo', 'bar'], '\\\\foo\\bar\\'], - [['//foo/', 'bar'], '\\\\foo\\bar\\'], - [['//foo', '/bar'], '\\\\foo\\bar\\'], - // UNC path expected - questionable - [['//foo', '', 'bar'], '\\\\foo\\bar\\'], - [['//foo/', '', 'bar'], '\\\\foo\\bar\\'], - [['//foo/', '', '/bar'], '\\\\foo\\bar\\'], - // UNC path expected - even more questionable - [['', '//foo', 'bar'], '\\\\foo\\bar\\'], - [['', '//foo/', 'bar'], '\\\\foo\\bar\\'], - [['', '//foo/', '/bar'], '\\\\foo\\bar\\'], - // No UNC path expected (no double slash in first component) - [['\\', 'foo/bar'], '\\foo\\bar'], - [['\\', '/foo/bar'], '\\foo\\bar'], - [['', '/', '/foo/bar'], '\\foo\\bar'], - // No UNC path expected (no non-slashes in first component - - // questionable) - [['//', 'foo/bar'], '\\foo\\bar'], - [['//', '/foo/bar'], '\\foo\\bar'], - [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], - [['//'], '/'], - // No UNC path expected (share name missing - questionable). - [['//foo'], '\\foo'], - [['//foo/'], '\\foo\\'], - [['//foo', '/'], '\\foo\\'], - [['//foo', '', '/'], '\\foo\\'], - // No UNC path expected (too many leading slashes - questionable) - [['///foo/bar'], '\\foo\\bar'], - [['////foo', 'bar'], '\\foo\\bar'], - [['\\\\\\/foo/bar'], '\\foo\\bar'], - // Drive-relative vs drive-absolute paths. This merely describes the - // status quo, rather than being obviously right - [['c:'], 'c:.'], - [['c:.'], 'c:.'], - [['c:', ''], 'c:.'], - [['', 'c:'], 'c:.'], - [['c:.', '/'], 'c:.\\'], - [['c:.', 'file'], 'c:file'], - [['c:', '/'], 'c:\\'], - [['c:', 'file'], 'c:\\file'] - ] - ) -]); -joinTests.forEach((test) => { - if (!Array.isArray(test[0])) - test[0] = [test[0]]; - test[0].forEach((join) => { - test[1].forEach((test) => { - const actual = join.apply(null, test[0]); - const expected = test[1]; - // For non-Windows specific tests with the Windows join(), we need to try - // replacing the slashes since the non-Windows specific tests' `expected` - // use forward slashes - let actualAlt; - let os; - if (join === path.win32.join) { - actualAlt = actual.replace(backslashRE, '/'); - os = 'win32'; - } else { - os = 'posix'; - } - const message = - `path.${os}.join(${test[0].map(JSON.stringify).join(',')})\n expect=${ - JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; - if (actual !== expected && actualAlt !== expected) - failures.push(`\n${message}`); - }); - }); -}); -assert.strictEqual(failures.length, 0, failures.join('')); - - // Test thrown TypeErrors const typeErrorTests = [true, false, 7, null, {}, undefined, [], NaN]; @@ -394,196 +34,6 @@ typeErrorTests.forEach((test) => { }); }); - -// path.normalize tests -assert.strictEqual(path.win32.normalize('./fixtures///b/../b/c.js'), - 'fixtures\\b\\c.js'); -assert.strictEqual(path.win32.normalize('/foo/../../../bar'), '\\bar'); -assert.strictEqual(path.win32.normalize('a//b//../b'), 'a\\b'); -assert.strictEqual(path.win32.normalize('a//b//./c'), 'a\\b\\c'); -assert.strictEqual(path.win32.normalize('a//b//.'), 'a\\b'); -assert.strictEqual(path.win32.normalize('//server/share/dir/file.ext'), - '\\\\server\\share\\dir\\file.ext'); -assert.strictEqual(path.win32.normalize('/a/b/c/../../../x/y/z'), '\\x\\y\\z'); -assert.strictEqual(path.win32.normalize('C:'), 'C:.'); -assert.strictEqual(path.win32.normalize('C:..\\abc'), 'C:..\\abc'); -assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'), - 'C:..\\..\\def'); -assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\'); -assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream'); -assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\'); -assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar'); -assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz'); -assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\'); -assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..'); - -assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), - 'fixtures/b/c.js'); -assert.strictEqual(path.posix.normalize('/foo/../../../bar'), '/bar'); -assert.strictEqual(path.posix.normalize('a//b//../b'), 'a/b'); -assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c'); -assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b'); -assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z'); -assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar'); -assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/'); -assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar'); -assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz'); -assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../'); -assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..'); - - -// path.resolve tests -const resolveTests = [ - [ path.win32.resolve, - // arguments result - [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], - [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], - [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], - [['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'], - [['.'], process.cwd()], - [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'], - [['c:/', '//'], 'c:\\'], - [['c:/', '//dir'], 'c:\\dir'], - [['c:/', '//server/share'], '\\\\server\\share\\'], - [['c:/', '//server//share'], '\\\\server\\share\\'], - [['c:/', '///some//dir'], 'c:\\some\\dir'], - [['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'], - 'C:\\foo\\tmp.3\\cycles\\root.js'] - ] - ], - [ path.posix.resolve, - // arguments result - [[['/var/lib', '../', 'file/'], '/var/file'], - [['/var/lib', '/../', 'file/'], '/file'], - [['a/b/c/', '../../..'], process.cwd()], - [['.'], process.cwd()], - [['/some/dir', '.', '/absolute/'], '/absolute'], - [['/foo/tmp.3/', '../tmp.3/cycles/root.js'], '/foo/tmp.3/cycles/root.js'] - ] - ] -]; -resolveTests.forEach((test) => { - const resolve = test[0]; - test[1].forEach((test) => { - const actual = resolve.apply(null, test[0]); - let actualAlt; - const os = resolve === path.win32.resolve ? 'win32' : 'posix'; - if (resolve === path.win32.resolve && !common.isWindows) - actualAlt = actual.replace(backslashRE, '/'); - else if (resolve !== path.win32.resolve && common.isWindows) - actualAlt = actual.replace(slashRE, '\\'); - - const expected = test[1]; - const message = - `path.${os}.resolve(${test[0].map(JSON.stringify).join(',')})\n expect=${ - JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; - if (actual !== expected && actualAlt !== expected) - failures.push(`\n${message}`); - }); -}); -assert.strictEqual(failures.length, 0, failures.join('')); - -if (common.isWindows) { - // Test resolving the current Windows drive letter from a spawned process. - // See https://github.com/nodejs/node/issues/7215 - const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 2); - const resolveFixture = path.join(common.fixturesDir, 'path-resolve.js'); - const spawnResult = child.spawnSync( - process.argv[0], [resolveFixture, currentDriveLetter]); - const resolvedPath = spawnResult.stdout.toString().trim(); - assert.strictEqual(resolvedPath.toLowerCase(), process.cwd().toLowerCase()); -} - - -// path.isAbsolute tests -assert.strictEqual(path.win32.isAbsolute('/'), true); -assert.strictEqual(path.win32.isAbsolute('//'), true); -assert.strictEqual(path.win32.isAbsolute('//server'), true); -assert.strictEqual(path.win32.isAbsolute('//server/file'), true); -assert.strictEqual(path.win32.isAbsolute('\\\\server\\file'), true); -assert.strictEqual(path.win32.isAbsolute('\\\\server'), true); -assert.strictEqual(path.win32.isAbsolute('\\\\'), true); -assert.strictEqual(path.win32.isAbsolute('c'), false); -assert.strictEqual(path.win32.isAbsolute('c:'), false); -assert.strictEqual(path.win32.isAbsolute('c:\\'), true); -assert.strictEqual(path.win32.isAbsolute('c:/'), true); -assert.strictEqual(path.win32.isAbsolute('c://'), true); -assert.strictEqual(path.win32.isAbsolute('C:/Users/'), true); -assert.strictEqual(path.win32.isAbsolute('C:\\Users\\'), true); -assert.strictEqual(path.win32.isAbsolute('C:cwd/another'), false); -assert.strictEqual(path.win32.isAbsolute('C:cwd\\another'), false); -assert.strictEqual(path.win32.isAbsolute('directory/directory'), false); -assert.strictEqual(path.win32.isAbsolute('directory\\directory'), false); - -assert.strictEqual(path.posix.isAbsolute('/home/foo'), true); -assert.strictEqual(path.posix.isAbsolute('/home/foo/..'), true); -assert.strictEqual(path.posix.isAbsolute('bar/'), false); -assert.strictEqual(path.posix.isAbsolute('./baz'), false); - - -// path.relative tests -const relativeTests = [ - [ path.win32.relative, - // arguments result - [['c:/blah\\blah', 'd:/games', 'd:\\games'], - ['c:/aaaa/bbbb', 'c:/aaaa', '..'], - ['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'], - ['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''], - ['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'], - ['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'], - ['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'], - ['c:/aaaa/bbbb', 'd:\\', 'd:\\'], - ['c:/AaAa/bbbb', 'c:/aaaa/bbbb', ''], - ['c:/aaaaa/', 'c:/aaaa/cccc', '..\\aaaa\\cccc'], - ['C:\\foo\\bar\\baz\\quux', 'C:\\', '..\\..\\..\\..'], - ['C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json', 'bar\\package.json'], - ['C:\\foo\\bar\\baz-quux', 'C:\\foo\\bar\\baz', '..\\baz'], - ['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz-quux', '..\\baz-quux'], - ['\\\\foo\\bar', '\\\\foo\\bar\\baz', 'baz'], - ['\\\\foo\\bar\\baz', '\\\\foo\\bar', '..'], - ['\\\\foo\\bar\\baz-quux', '\\\\foo\\bar\\baz', '..\\baz'], - ['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'], - ['C:\\baz-quux', 'C:\\baz', '..\\baz'], - ['C:\\baz', 'C:\\baz-quux', '..\\baz-quux'], - ['\\\\foo\\baz-quux', '\\\\foo\\baz', '..\\baz'], - ['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'], - ['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'], - ['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'] - ] - ], - [ path.posix.relative, - // arguments result - [['/var/lib', '/var', '..'], - ['/var/lib', '/bin', '../../bin'], - ['/var/lib', '/var/lib', ''], - ['/var/lib', '/var/apache', '../apache'], - ['/var/', '/var/lib', 'lib'], - ['/', '/var/lib', 'var/lib'], - ['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'], - ['/Users/a/web/b/test/mails', '/Users/a/web/b', '../..'], - ['/foo/bar/baz-quux', '/foo/bar/baz', '../baz'], - ['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'], - ['/baz-quux', '/baz', '../baz'], - ['/baz', '/baz-quux', '../baz-quux'] - ] - ] -]; -relativeTests.forEach((test) => { - const relative = test[0]; - test[1].forEach((test) => { - const actual = relative(test[0], test[1]); - const expected = test[2]; - const os = relative === path.win32.relative ? 'win32' : 'posix'; - const message = `path.${os}.relative(${ - test.slice(0, 2).map(JSON.stringify).join(',')})\n expect=${ - JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; - if (actual !== expected) - failures.push(`\n${message}`); - }); -}); -assert.strictEqual(failures.length, 0, failures.join('')); - - // path.sep tests // windows assert.strictEqual(path.win32.sep, '\\'); @@ -596,43 +46,6 @@ assert.strictEqual(path.win32.delimiter, ';'); // posix assert.strictEqual(path.posix.delimiter, ':'); - -// path._makeLong tests -const emptyObj = {}; -assert.strictEqual(path.posix._makeLong('/foo/bar'), '/foo/bar'); -assert.strictEqual(path.posix._makeLong('foo/bar'), 'foo/bar'); -assert.strictEqual(path.posix._makeLong(null), null); -assert.strictEqual(path.posix._makeLong(true), true); -assert.strictEqual(path.posix._makeLong(1), 1); -assert.strictEqual(path.posix._makeLong(), undefined); -assert.strictEqual(path.posix._makeLong(emptyObj), emptyObj); -if (common.isWindows) { - // These tests cause resolve() to insert the cwd, so we cannot test them from - // non-Windows platforms (easily) - assert.strictEqual(path.win32._makeLong('foo\\bar').toLowerCase(), - `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); - assert.strictEqual(path.win32._makeLong('foo/bar').toLowerCase(), - `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); - const currentDeviceLetter = path.parse(process.cwd()).root.substring(0, 2); - assert.strictEqual(path.win32._makeLong(currentDeviceLetter).toLowerCase(), - `\\\\?\\${process.cwd().toLowerCase()}`); - assert.strictEqual(path.win32._makeLong('C').toLowerCase(), - `\\\\?\\${process.cwd().toLowerCase()}\\c`); -} -assert.strictEqual(path.win32._makeLong('C:\\foo'), '\\\\?\\C:\\foo'); -assert.strictEqual(path.win32._makeLong('C:/foo'), '\\\\?\\C:\\foo'); -assert.strictEqual(path.win32._makeLong('\\\\foo\\bar'), - '\\\\?\\UNC\\foo\\bar\\'); -assert.strictEqual(path.win32._makeLong('//foo//bar'), - '\\\\?\\UNC\\foo\\bar\\'); -assert.strictEqual(path.win32._makeLong('\\\\?\\foo'), '\\\\?\\foo'); -assert.strictEqual(path.win32._makeLong(null), null); -assert.strictEqual(path.win32._makeLong(true), true); -assert.strictEqual(path.win32._makeLong(1), 1); -assert.strictEqual(path.win32._makeLong(), undefined); -assert.strictEqual(path.win32._makeLong(emptyObj), emptyObj); - - if (common.isWindows) assert.deepStrictEqual(path, path.win32, 'should be win32 path module'); else From 5c99fc3fb31507d99f7a03f3517fb364042300c4 Mon Sep 17 00:00:00 2001 From: Gergely Nemeth Date: Thu, 7 Sep 2017 09:21:20 +0200 Subject: [PATCH 031/128] test: backward compatible api for tty PR-URL: https://github.com/nodejs/node/pull/15235 Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Daijiro Wachi --- test/parallel/test-tty-backwards-api.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/parallel/test-tty-backwards-api.js diff --git a/test/parallel/test-tty-backwards-api.js b/test/parallel/test-tty-backwards-api.js new file mode 100644 index 00000000000000..547184728ebaf8 --- /dev/null +++ b/test/parallel/test-tty-backwards-api.js @@ -0,0 +1,25 @@ +'use strict'; +const common = require('../common'); + +const noop = () => {}; +const TTY = process.binding('tty_wrap').TTY = function() {}; + +TTY.prototype = { + setBlocking: noop, + getWindowSize: noop +}; + +const { WriteStream } = require('tty'); + +const methods = [ + 'cursorTo', + 'moveCursor', + 'clearLine', + 'clearScreenDown' +]; + +methods.forEach((method) => { + require('readline')[method] = common.mustCall(); + const writeStream = new WriteStream(1); + writeStream[method](1, 2); +}); From f49feab35f7722a075bd41ba1a72a9a8fb6fc9ea Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Thu, 26 Jan 2017 20:29:39 +0100 Subject: [PATCH 032/128] timers: clarify lib/timer.js comment PR-URL: https://github.com/nodejs/node/pull/11018 Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater Reviewed-By: Lance Ball --- lib/timers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/timers.js b/lib/timers.js index 7c9a721c68cef5..a612f0ea4a1037 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -72,7 +72,7 @@ const TIMEOUT_MAX = 2147483647; // 2^31-1 // timeout later, thus only needing to be appended. // Removal from an object-property linked list is also virtually constant-time // as can be seen in the lib/internal/linkedlist.js implementation. -// Timeouts only need to process any timers due to currently timeout, which will +// Timeouts only need to process any timers currently due to expire, which will // always be at the beginning of the list for reasons stated above. Any timers // after the first one encountered that does not yet need to timeout will also // always be due to timeout at a later time. From 5522bdf8251bd81211b30397dfcbceef03604cec Mon Sep 17 00:00:00 2001 From: Peter Marshall Date: Fri, 30 Jun 2017 13:41:39 +0200 Subject: [PATCH 033/128] benchmark: use smaller n value in some http tests PR-URL: https://github.com/nodejs/node/pull/14002 Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell --- benchmark/http/check_invalid_header_char.js | 2 +- benchmark/http/check_is_http_token.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmark/http/check_invalid_header_char.js b/benchmark/http/check_invalid_header_char.js index bef44e63167078..7b9c08bd17cd97 100644 --- a/benchmark/http/check_invalid_header_char.js +++ b/benchmark/http/check_invalid_header_char.js @@ -27,7 +27,7 @@ const bench = common.createBenchmark(main, { 'foo\nbar', '\x7F' ], - n: [5e8], + n: [1e6], }); function main(conf) { diff --git a/benchmark/http/check_is_http_token.js b/benchmark/http/check_is_http_token.js index a317e05a4a12d2..9e0b8279b58ed0 100644 --- a/benchmark/http/check_is_http_token.js +++ b/benchmark/http/check_is_http_token.js @@ -37,7 +37,7 @@ const bench = common.createBenchmark(main, { ':alternate-protocol', // fast bailout 'alternate-protocol:' // slow bailout ], - n: [5e8], + n: [1e6], }); function main(conf) { From 0b5798b3c33aaec3c4e2f6eeb3b3f06e0a203c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Szczepa=C5=84ski?= Date: Wed, 30 Aug 2017 23:46:26 +0200 Subject: [PATCH 034/128] src: remove outdated todo from node_crypto.cc TODO comment from node_crypto is no longer relevant. Unification of commented code and string_bytes code would bloat the latter. Methods for hex encoding produce different output in both files (crypto adds colon and uses uppercase letters.) Common path between those two is very limited now. PR-URL: https://github.com/nodejs/node/pull/15104 Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell --- src/node_crypto.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 335972bab2a466..5cb6ab8ca18173 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1607,7 +1607,6 @@ static Local X509ToObject(Environment* env, X509* cert) { const char hex[] = "0123456789ABCDEF"; char fingerprint[EVP_MAX_MD_SIZE * 3]; - // TODO(indutny): Unify it with buffer's code for (i = 0; i < md_size; i++) { fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4]; fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)]; From ab014d4056d6c9d5fa9669d252b2590f4bb6a74d Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Thu, 14 Sep 2017 14:26:42 +0200 Subject: [PATCH 035/128] doc: make mkdtemp example work on Windows PR-URL: https://github.com/nodejs/node/pull/15408 Fixes: https://github.com/nodejs/node/issues/14960 Reviewed-By: Colin Ihrig Reviewed-By: Vse Mozhet Byt Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- doc/api/fs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 798fd6c32d3924..e26d25f91df18c 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1133,10 +1133,10 @@ object with an `encoding` property specifying the character encoding to use. Example: ```js -fs.mkdtemp('/tmp/foo-', (err, folder) => { +fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, folder) => { if (err) throw err; console.log(folder); - // Prints: /tmp/foo-itXde2 + // Prints: /tmp/foo-itXde2 or C:\Users\...\AppData\Local\Temp\foo-itXde2 }); ``` @@ -1148,7 +1148,7 @@ the `prefix` *must* end with a trailing platform-specific path separator ```js // The parent directory for the new temporary directory -const tmpDir = '/tmp'; +const tmpDir = os.tmpdir(); // This method is *INCORRECT*: fs.mkdtemp(tmpDir, (err, folder) => { From 48943e92d72cb1498ed3ab7793691c594e781644 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 4 Sep 2017 11:31:32 -0400 Subject: [PATCH 036/128] test: allow adding known-globals through ENV PR-URL: https://github.com/nodejs/node/pull/15187 Refs: https://youtrack.jetbrains.com/issue/WEB-27528 Reviewed-By: Anna Henningsen Reviewed-By: Benjamin Gruenbaum Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Ruben Bridgewater --- test/common/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/common/index.js b/test/common/index.js index 7b4d2014f6bc23..b73b7b7dd6de00 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -362,6 +362,11 @@ if (global.Symbol) { knownGlobals.push(Symbol); } +if (process.env.NODE_TEST_KNOWN_GLOBALS) { + const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(','); + allowGlobals(...knownFromEnv); +} + function allowGlobals(...whitelist) { knownGlobals = knownGlobals.concat(whitelist); } From ae111c266c41c0520f20aa09317f0c4b9b7231b6 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 10 Sep 2017 10:48:40 -0700 Subject: [PATCH 037/128] doc: use consistent terminology in process doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `process.md` uses `POSIX` in most places, but `Unix` (and in one case `Linux`) in a handful of cases where `POSIX` is appropriate. Change those instances to `POSIX`. PR-URL: https://github.com/nodejs/node/pull/15321 Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater --- doc/api/process.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api/process.md b/doc/api/process.md index 885569a4ad48f6..bbcef7002dea95 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1588,10 +1588,10 @@ important ways: 2. They cannot be closed ([`end()`][] will throw). 3. They will never emit the [`'finish'`][] event. 4. Writes may be synchronous depending on the what the stream is connected to - and whether the system is Windows or Unix: - - Files: *synchronous* on Windows and Linux - - TTYs (Terminals): *asynchronous* on Windows, *synchronous* on Unix - - Pipes (and sockets): *synchronous* on Windows, *asynchronous* on Unix + and whether the system is Windows or POSIX: + - Files: *synchronous* on Windows and POSIX + - TTYs (Terminals): *asynchronous* on Windows, *synchronous* on POSIX + - Pipes (and sockets): *synchronous* on Windows, *asynchronous* on POSIX These behaviors are partly for historical reasons, as changing them would create backwards incompatibility, but they are also expected by some users. @@ -1769,7 +1769,7 @@ cases: or unavailable. * `>128` **Signal Exits** - If Node.js receives a fatal signal such as `SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the - value of the signal code. This is a standard Unix practice, since + value of the signal code. This is a standard POSIX practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code. From 6fe61d6d9c6503f849f96407b4561c978c47d75c Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 10 Sep 2017 10:23:38 -0700 Subject: [PATCH 038/128] test: remove invalid test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `test/known_issues/test-stdout-buffer-flush-on-exit.js` is invalid. The behavior seen currently (with the test failing) is in accordance with documentation which indicates that calling `process.exit()` may mean scheduled asynchronous I/O does not happen. The documentation also indicates that `process.stdout` is asynchronous when it is a POSIX pipe. PR-URL: https://github.com/nodejs/node/pull/15320 Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- .../test-stdout-buffer-flush-on-exit.js | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 test/known_issues/test-stdout-buffer-flush-on-exit.js diff --git a/test/known_issues/test-stdout-buffer-flush-on-exit.js b/test/known_issues/test-stdout-buffer-flush-on-exit.js deleted file mode 100644 index 931f1026cfa9c6..00000000000000 --- a/test/known_issues/test-stdout-buffer-flush-on-exit.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; -// Refs: https://github.com/nodejs/node/issues/2148 - -require('../common'); -const assert = require('assert'); -const execSync = require('child_process').execSync; - -const lineSeed = 'foo bar baz quux quuz aaa bbb ccc'; - -if (process.argv[2] === 'child') { - const longLine = lineSeed.repeat(parseInt(process.argv[4], 10)); - process.on('exit', () => { - console.log(longLine); - }); - process.exit(); -} - -[22, 21, 20, 19, 18, 17, 16, 16, 17, 18, 19, 20, 21, 22].forEach((exponent) => { - const bigNum = Math.pow(2, exponent); - const longLine = lineSeed.repeat(bigNum); - const cmd = - `"${process.execPath}" "${__filename}" child ${exponent} ${bigNum}`; - const stdout = execSync(cmd).toString().trim(); - - assert.strictEqual(stdout, longLine, `failed with exponent ${exponent}`); -}); From 0b2d5486c685e4643d9f63d9811fc8098982cd47 Mon Sep 17 00:00:00 2001 From: Tuan Anh Tran Date: Mon, 11 Sep 2017 14:10:09 +0700 Subject: [PATCH 039/128] doc: fix "added in" for Buffer.allocUnsafeSlow() PR-URL: https://github.com/nodejs/node/pull/15330 Fixes: https://github.com/nodejs/node/issues/15279 Reviewed-By: James M Snell Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca --- doc/api/buffer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index eb2447f4cfff04..de92be481d4b16 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -555,7 +555,7 @@ additional performance that [`Buffer.allocUnsafe()`] provides. ### Class Method: Buffer.allocUnsafeSlow(size) * `size` {integer} The desired length of the new `Buffer` From 988eec3a932466bb7b69cdb436c620a9e1a48514 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Wed, 30 Aug 2017 20:05:39 -0400 Subject: [PATCH 040/128] doc: update README with SHASUMS256.txt.sig info It is more secure to verify SHASUMS256.txt files via SHASUMS256.txt.sig than SHASUMS256.txt.asc. This comment does the best job at explaining the issue: https://github.com/nodejs/node/issues/6821#issuecomment-220033176 Refer: https://github.com/nodejs/node/issues/6821 Refer: https://github.com/nodejs/node/issues/9071 PR-URL: https://github.com/nodejs/node/pull/15107 Reviewed-By: Rod Vagg Reviewed-By: Ruben Bridgewater Reviewed-By: James Snell Reviewed-By: Luigi Pinca --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 03c725bdcd13c1..17c8a6a76db75b 100644 --- a/README.md +++ b/README.md @@ -134,12 +134,12 @@ $ grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c - _(Where "node-vx.y.z.tar.gz" is the name of the file you have downloaded)_ -Additionally, Current and LTS releases (not Nightlies) have GPG signed -copies of SHASUMS256.txt files available as SHASUMS256.txt.asc. You can use -`gpg` to verify that the file has not been tampered with. +Additionally, Current and LTS releases (not Nightlies) have the GPG +detached signature of SHASUMS256.txt available as SHASUMS256.txt.sig. +You can use `gpg` to verify that SHASUMS256.txt has not been tampered with. -To verify a SHASUMS256.txt.asc, you will first need to import all of -the GPG keys of individuals authorized to create releases. They are +To verify SHASUMS256.txt has not been altered, you will first need to import +all of the GPG keys of individuals authorized to create releases. They are listed at the bottom of this README under [Release Team](#release-team). Use a command such as this to import the keys: @@ -150,10 +150,17 @@ $ gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C2 _(See the bottom of this README for a full script to import active release keys)_ -You can then use `gpg --verify SHASUMS256.txt.asc` to verify that the -file has been signed by an authorized member of the Node.js team. +Next, download the SHASUMS256.txt.sig for the release: -Once verified, use the SHASUMS256.txt.asc file to get the checksum for +```console +$ curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt.sig +``` + +After downloading the appropriate SHASUMS256.txt and SHASUMS256.txt.sig files, +you can then use `gpg --verify SHASUMS256.txt.sig SHASUMS256.txt` to verify +that the file has been signed by an authorized member of the Node.js team. + +Once verified, use the SHASUMS256.txt file to get the checksum for the binary verification command above. ## Building Node.js From 21dec5573af1cddcd2a3dd910d5c760a8fa4f36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 4 Sep 2017 15:25:30 +0200 Subject: [PATCH 041/128] doc: update AUTHORS list Update AUTHORS list using tools/update-authors.sh. Update .mailmap to handle duplicates. PR-URL: https://github.com/nodejs/node/pull/15181 Reviewed-By: Luigi Pinca Reviewed-By: Timothy Gu Reviewed-By: Michael Dawson Reviewed-By: Khaidi Chu Reviewed-By: Gireesh Punathil Reviewed-By: Benjamin Gruenbaum Reviewed-By: Roman Reiss Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater --- .mailmap | 94 ++++++++++++++++-- AUTHORS | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 361 insertions(+), 31 deletions(-) diff --git a/.mailmap b/.mailmap index a2b1fce896f284..842d610df87b94 100644 --- a/.mailmap +++ b/.mailmap @@ -3,26 +3,36 @@ Aaron Heckmann Abe Fettig Akito Ito Alejandro Oviedo Garcia Alejandro Oviedo -Alex Hultman +Alex Hultman +Alex Jordan AJ Jordan Alex Kocharin Alex Kocharin +Alexander Marchenko axvm Alexey Kupershtokh Alexis Campailla Alexis Sellier Alexis Sellier +Alfred Cepeda ALJCepeda +Amery 子丶言 Andreas Offenhaeuser anoff Andy Bettisworth Angel Stoyanov atstojanov -Anna Henningsen +Anna Henningsen +Anna Magdalena Kedzierska AnnaMag Aria Stewart Arlo Breault +Arnaud Lefebvre BlackYoup Artem Zaytsev +Artur G Vieira Artur Vieira Arnout Kazemier <3rd-Eden@users.noreply.github.com> Asaf David asafdav2 Atsuo Fukaya Ben Lugavere blugavere -Ben Noordhuis +Ben Noordhuis +Ben Noordhuis Ben Taber +Benjamin Fleischer Benjamin Fleischer +Benjamin Gruenbaum Benjamin Waters Bert Belder Bert Belder @@ -30,7 +40,9 @@ Bert Belder Beth Griggs Bethany Griggs Beth Griggs Bethany N Griggs Beth Griggs BethGriggs +Bidisha Pyne Brad Decker brad-decker +Bradley Meck Bradley Farias Brandon Benvie Brandon Kobel kobelb Brendan Ashworth @@ -45,67 +57,88 @@ Charles Rudolph Chris Johnson Claudio Rodriguez Colin Ihrig +Christophe Naud-Dulude Chris911 Christopher Lenz Dan Kaplun Dan Williams Dan.Williams +Daniel Bevenius daniel.bevenius Daniel Berger Daniel Chcouri <333222@gmail.com> Daniel Gröber Daniel Gröber Daniel Pihlström -Daniel Wang +Daniel Wang firedfox +Daniel Wang firedfox Danny Nemer +Danny Nemer Dave Pacheco +David Cai DavidCai +David Mark Clements davidmarkclements +David Mark Clements davidmarkclements David Siegel +DC dcposch@dcpos.ch Domenic Denicola Domenic Denicola +Doug Wade doug.wade Eduard Burtescu Einar Otto Stangvik Elliott Cable Eric Phetteplace +Eugene Obrezkov ghaiklor EungJun Yi Evan Larkin Evan Lucas Evan Lucas FangDun Cai Fangdun Cai (Fundon) +Fangshi He hefangshi Farid Neshat Fedor Indutny Felix Böhm Felix Geisendörfer Felix Geisendörfer +Flandre Scarlet Flandre +Florian Margaine Florian MARGAINE Forrest L Norvell Friedemann Altrock Fuji Goro Gabriel de Perthuis +Gareth Ellis Gibson Fahnestock Gil Pedersen +Graham Fairweather Xotic750 Greg Sabia Tucker Hitesh Kanwathirtha Henry Chin Herbert Vojčík Icer Liang +Igor Savin kibertoad Igor Soarez Igor Zinkovsky -Imran Iqbal +Imran Iqbal Ionică Bizău Isaac Z. Schlueter Isaac Z. Schlueter Italo A. Casas -Jackson Tian +Jackson Tian Jake Verbaten +Jamen Marzonie Jamen Marz James Hartig James M Snell Jan Krems Jenna Vuong +JeongHoon Byun Outsider Jered Schmidt Jeremiah Senkpiel Jerry Chin +Jessica Quynh Tran jessicaquynh Jesús Leganés-Combarro 'piranna Jesús Leganés Combarro "piranna Joe Shaw Johan Bergström Johan Dahlberg Johann Hofmann John Barboza jBarz +John Barboza jBarz +John Gardner Alhadis Johnny Ray Austin Johnny Ray Jon Tippens legalcodes Jonas Pfenniger @@ -114,9 +147,13 @@ Jonathan Persson Jonathan Rentzsch Josh Erickson Joshua S. Weinstein +Joyee Cheung joyeecheung Juan Soto +Julien Klepatch jklepatch +Julien Waechter julien.waechter Junliang Yan Junliang Yan +Junshu Okamoto jun-oka Jérémy Lal Jérémy Lal Kai Sasaki Lewuathe @@ -125,38 +162,56 @@ Kathy Truong k3kathy Kazuyuki Yamada Keith M Wesolowski Kelsey Breseman +Kiyoshi Nomo kysnm Koichi Kobayashi Kris Kowal Kyle Robinson Young +Lakshmi Swetha Gopireddy LAKSHMI SWETHA GOPIREDDY Luke Bayes +Lydia Kats Lydia Katsamberis Maciej Małecki Malte-Thorben Bruns +Malte-Thorben Bruns skenqbx +Marcelo Gobelli decareano Marcin Cieślak Marcin Cieślak Marcin Zielinski marzelin Marti Martz Martial James Jefferson +Matt Lang matt-in-a-hat +Matthias Bastian piepmatz Mathias Buus Mathias Pettersson Matthew Lye Michael Bernstein +Michael Dawson Michael Wilber -Michaël Zasso +Michaël Zasso +Michael-Rainabba Richardson rainabba Micheil Smith Micleusanu Nicu +Miguel Angel Asencio Hurtado maasencioh Mikael Bourges-Sevenier +Minqi Pan P.S.V.R +Minwoo Jung JungMinu Miroslav Bajtoš Mitar Milutinovic Myles Borins Myles Borins Nebu Pookins +Netto Farah nettofarah Nicholas Kinsey Nikolai Vavilov +Noah Rose Ledesma Noah Rose +Noah Rose Ledesma Onne Gorter Paul Querna +Pedro Lima Pedro Victor +Pedro Lima Pedro lima Peter Flannery Phillip Johnsen Ratikesh Misra +Ravindra Barthwal Ravindra barthwal Ray Morgan Ray Solomon Raymond Feng @@ -169,8 +224,12 @@ Rod Machen Roman Klauke Roman Reiss Ron Korving +Ron Korving ronkorving Ryan Dahl Ryan Emery +Ryan Scheel Ryan Scheel +Ryan Scheel Ryan Scheel (Havvy) +Saad Quadri saadq Sakthipriyan Vairamani Sam Mikes Sam P Gallagher-Bishop @@ -180,6 +239,8 @@ Sambasiva Suda Sam Roberts San-Tai Hsu Santiago Gimeno +Sarah Meyer sarahmeyer +Sartrey Lee sartrey Scott Blomquist Segu Riluvan Sergey Kryzhanovsky @@ -188,21 +249,32 @@ Shigeki Ohtsu Shigeki Ohtsu Siddharth Mahendraker Simon Willison +Siobhan O'Donovan justshiv +solebox solebox <5013box@gmail.com> +Sreepurna Jasti +Sreepurna Jasti sreepurnajasti +Sreepurna Jasti sreepurnajasti Stanislav Opichal -Stefan Budeanu +Stefan Budeanu Stefan Bühler Steve Mao Steven R. Loomis Stewart X Addison Stewart Addison Stewart X Addison sxa555 Suramya shah ss22ever +Surya Panikkal surya panikkal +Surya Panikkal suryagh +Taehee Kang hugnosis Tanuja-Sawant +Taylor Woll taylor.woll +Thomas Watson Steen Thomas Watson Toby Stableford toboid Todd Kennedy TJ Holowaychuk TJ Holowaychuk Tadashi SAWADA Takahiro ANDO +Tarun Batra Tarun Ted Young Thomas Lee Thomas Reggi @@ -220,15 +292,21 @@ Viktor Karpov vitkarpov Vincent Voyer Vladimir de Turckheim vsemozhetbyt Vse Mozhet Byt +Wang Xinyong +Weijia Wang <381152119@qq.com> starkwang <381152119@qq.com> Willi Eggeling +xiaoyu <306766053@qq.com> Poker <306766053@qq.com> Yazhong Liu Yazhong Liu Yazhong Liu Yorkie Yazhong Liu Yorkie Yoshihiro KIKUCHI Yosuke Furukawa Yuichiro MASUI +Yuta Hiroto abouthiroppy +Zach Bjornson Zachary Scott Zoran Tomicic +Сковорода Никита Андреевич ChALkeR # These people didn't contribute patches to node directly, # but we've landed their v8 patches in the node repository: diff --git a/AUTHORS b/AUTHORS index ee864d2d8ff8db..977f3b619f4b00 100644 --- a/AUTHORS +++ b/AUTHORS @@ -611,7 +611,7 @@ Patrick Mooney Jicheng Li James Ferguson Julien Fontanet -Steven R. Loomis +Steven R. Loomis gyson Steve Sharp Victor Widell @@ -624,7 +624,6 @@ Ray Donnelly dead-horse Luis Reis sudodoki -Steven Loomis haoxin Artur Cistov MK Safi @@ -707,7 +706,7 @@ Shinnosuke Watanabe Bruno Jouhier René Kooi Petka Antonov -Ryan Scheel +Ryan Scheel Benjamin Gruenbaum Pavel Medvedev Russell Dempsey @@ -785,7 +784,7 @@ Sven Slootweg Dmitry Vasilyev Malcolm Ahoy Imran Iqbal -Stewart Addison +Stewart X Addison Matt Harrison Christopher J. Brody Salman Aljammaz @@ -971,10 +970,9 @@ James Lal Josh Leder Surya Panikkal vsemozhetbyt -Eugene Obrezkov Alex Lamar Ian Kronquist -DavidCai +David Cai Patrick Mueller Ben Page Juan Soto @@ -1088,7 +1086,7 @@ Paul Kiddie scott stern Danny Guo lrlna -matt-in-a-hat +Matt Lang Thomas van Lankveld Tarjei Husøy Wietse Venema @@ -1104,16 +1102,14 @@ Michael-Rainabba Richardson oogz Rene Weber Lauren Spiegel -Lydia Katsamberis +Lydia Kats mpmckenna8 nohmapp -Matt Lang Marc-Aurèle DARCHE fen Christopher Fujino Richard Hong Akito Ito -Lydia Kats Madhav Gharmalkar Mike Woods Daniel Stenberg @@ -1130,7 +1126,7 @@ Alex Jordan Mariusz 'koder' Chwalba Juan Andres Andrango larissayvette -jessicaquynh +Jessica Quynh Tran Ilya Frolov Tanuja-Sawant Bradley T. Hughes @@ -1141,7 +1137,6 @@ Marcin Zielinski Benji Marinacci Indrek Ardel Parambir Singh -maasencioh Niels Nielsen Marc Udoff Oliver Salzburg @@ -1155,7 +1150,7 @@ Gerges Beshay Isobel Redelmeier Brandon Kobel coderaiser -Pedro Victor +Pedro Lima Reza Akhavan Yangyang Liu Zeke Sikelianos @@ -1183,10 +1178,8 @@ Aaron Petcoff Rahat Ahmed monkick Adam Brunner -子丶言 atrioom Dan Koster -Pedro Lima Francis Gulotta Yosuke Saito mkamakura @@ -1202,6 +1195,7 @@ Ashton Kinslow Kevin Zurawel Wes Tyler shiya +Joyee Cheung Greg Valdez Bidur Adhikari Kyle Carter @@ -1226,14 +1220,13 @@ Jonathan Darling JDHarmon bjdelro Hitesh Kanwathirtha -davidmarkclements +David Mark Clements Cesar Hernandez Konstantin Likhter Richard Karmazin Hutson Betts Kent.Fan Jay Brownlee -Outsider Sarah Meyer Andreas Offenhaeuser Sean Villars @@ -1247,7 +1240,6 @@ Ethan Arrowood Dan Villa CodeTheInternet Eric Gonzalez -sxa555 rgoodwin Nigel Kibodeaux fmizzell @@ -1297,7 +1289,6 @@ James Tenenbaum pallxk Amar Zavery Prieto, Marcos -Joyee Cheung hveldstra Siddhartha Sahai Andy Chen @@ -1332,13 +1323,11 @@ René Schünemann Jeremy Yallop malen Kailean Courtney -sarahmeyer Fumiya KARASAWA John Barboza Paul Graham Nate Chris Story -Stewart X Addison Matthew Garrett David Goussev George Adams @@ -1362,7 +1351,6 @@ Josh Hollandsworth Sumit Goel stefan judis Mark -Jessica Quynh Tran Travis Meisenheimer Vinícius do Carmo Birunthan Mohanathas @@ -1384,7 +1372,6 @@ Umair Ishaq Timo Tijhof Sebastian Van Sande Daiki Arai -ALJCepeda Sebastian Roeder Toby Stableford Shubheksha Jalan @@ -1415,5 +1402,270 @@ Bradley Curran chiaki-yokoo Benjamin Fleischer maurice_hayward +Ali BARIN +Nemanja Stojanovic +Jeroen Mandersloot +Michael Cox +Clarence Dimitri CHARLES +Lukas Möller +Juwan Yoo +Matej Krajčovič +Alexander +Gaara +mr-spd +Christian d'Heureuse +Shahar Or +detailyang +liusi +Noj Vek +Ruslan Bekenev +Jyotman Singh +Lucas Lago +TheBeastOfCaerbannog +Morgan Brenner +Nick Peleh +Sorin Baltateanu +Chris Burkhart +Rj Bernaldo +John F. Mercer +Dejon "DJ" Gill +Ahmad Nassri +Tom Atkinson +Tobias Nießen +Joseph Gentle +Zero King +Raphael Okon +JR McEntee +Lovell Fuller +Jason Marsh +Vinay Hiremath +Gabriel Schulhof +alejandro +dave-k +Steven +Uppinder Chugh +Karl Cheng +Taylor Woll +Tarun Batra +Nao YONASHIRO +Christopher Luke +Sampson Gao +John Paul Bamberg +Cody Deckard +Fabio Campinho +Gautam krishna.R +Mateusz Konieczny +Sebastian Plesciuc +MapleUncle +Ahmed Taj elsir +Ivo von Putzer Reibegg +Alex Autem +kumarrishav +morrme +vperezma +Muhsin Abdul-Musawwir +thelady +Neehar Venugopal +WORMSS +Zahidul Islam +RobotMermaid +coreybeaumont +alohaglenn +weewey +Zuzana Svetlikova +Cameron Little +gwer +Walter Huang +Leo +Tony Rice +Olivier Martin +jeyanthinath +Aditya Anand +Oscar Martinez +cool88 +Steven Lehn +Łukasz Szewczak +Madara Uchiha +Gil Tayar +Glenn Schlereth +Artur G Vieira +Flarna +Sreepurna Jasti +Rafael Fragoso +Andrei Cioromila +Frank Lanitz +XadillaX +Akshay Iyer +Rick Bullotta +Rajaram Gaunker +Shadowbeetle +Chris Young +Ebrahim Byagowi +Timur Shemsedinov +Jesus Seijas +mskec +Peter Dave Hello +JongChan Choi +Yihong Wang +Ryan Kelly +Alexander O'Mara +James, please +Josh Ferge +Bidisha Pyne +David D Lowe +rmdm +Dávid Szakállas +JiaLi.Passion +Paul Bininda +Gautam Mittal <200mittalgautam@gmail.com> +Jamen Marzonie +Jacob Jones +Vladimir Trifonov +aniketshukla +realwakka +Gergely Nemeth +Samuel Reed +Anshul Guleria +Justin Beckwith +Scott McKenzie +Julien Klepatch +Dan Homola +Chris Young +cornholio <0@mcornholio.ru> +Tamás Hódi +DuanPengfei <2459714173@qq.com> +Ruben Bridgewater +Lakshmi Swetha Gopireddy +Rob Wu +Steven Winston +sallen450 +OriLev +Zongmin Lei +lena +Azard <330815461@qq.com> +Ezequiel Garcia +Kyle Farnung +Weijia Wang <381152119@qq.com> +Nataly Shrits +Jaime Bernardo +Natanael Log +MoonBall +kuroljov +Matt Sergeant +Eduardo Leggiero +Moogen Tian +Jimmy Thomson +David Drysdale +Roman Shoryn +Peter Czibik +章礼平 +Fraser Xu +Song, Bintao Garfield +Flandre Scarlet +akira.xue +Bang Wu +kadoufall +jiangplus +tobewhatwewant +blade254353074 +weiyuanyue +xinglong.wangwxl +vercent deng +boydfd +Superwoods +shaman +Zhang Weijie +Gunar C. Gessner +SkyAo +Devin Boyer +Helianthus21 <740051540@qq.com> +Oleksandr Kushchak +Nathan Jiang +mac-haojin +jkzing +zzz +Henry +Gautam Arora +Marc Hernández Cabot +Vincent Xue +Bougarfaoui El houcine +ziyun +Lyall Sun +Marcelo Gobelli +Sebastiaan Deckers +nanaya +xeodou +Peter Marshall +笑斌 +atever +vixony +Ching Hsu +rockcoder23 +Anton Paras +Pratik Jain +Shivanth MP +Kunal Pathak +erdun <494251936@qq.com> +Jiajie Hu +Matt Woicik +Franziska Hinkelmann +alexbostock +Matthew Alsup +Greg Alexander +dcharbonnier +Jared Kantrowitz +Guy Margalit +Azard +nishijayaraj +Nick Stanish +Mandeep Singh +Prakash Palaniappan +Keita Akutsu +Michael Albert +Eugene Ostroukhov +Vishal Bisht +Griffith Tchenpan +Oky Antoro +icarter09 +Pini Houri +Runite618 +phisixersai +hsmtkk +Miroslav Bajtoš +Sebastian Murphy +陈刚 +Jon Moss +George Sapkin +Aleh Zasypkin +Anand Suresh +sharababy +Abhishek Raj +Daniel Taveras +RefinedSoftwareLLC +Ankit Parashar +James Kyle +Daniil Shakir +sevenryze +hafiz +Kyle Lamse +Michał Wadas +Mohd Maqbool Alam +Ian Perkins +Jimmy Cann +Dave Olszewski +Anatoli Papirovski +Simon Brewster +creeperyang +Roy Marples +Piotr Mionskowski +Cyril Lakech +Eduard Bondarenko +Adina Shanholtz +Miguel Martins +Yury Popov +George Bezerra +Benjamin Coe +Tim Costa +Rahul Mishra # Generated by tools/update-authors.sh From 713f239900265f026691307e5ff019152eebd3de Mon Sep 17 00:00:00 2001 From: Sebastiaan Deckers Date: Tue, 12 Sep 2017 13:09:02 +0800 Subject: [PATCH 042/128] doc: adding sebdeckers to collaborators PR-URL: https://github.com/nodejs/node/pull/15354 Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 17c8a6a76db75b..f187544e219458 100644 --- a/README.md +++ b/README.md @@ -469,6 +469,8 @@ For more information about the governance of the Node.js project, see **Sam Roberts** <vieuxtech@gmail.com> * [santigimeno](https://github.com/santigimeno) - **Santiago Gimeno** <santiago.gimeno@gmail.com> +* [sebdeckers](https://github.com/sebdeckers) - +**Sebastiaan Deckers** <sebdeckers83@gmail.com> * [seishun](https://github.com/seishun) - **Nikolai Vavilov** <vvnicholas@gmail.com> * [shigeki](https://github.com/shigeki) - From 9cebe8296a905478e0a7bfeb5da29901c4cf7b56 Mon Sep 17 00:00:00 2001 From: Rahul Mishra Date: Fri, 8 Sep 2017 11:08:37 +0530 Subject: [PATCH 043/128] test: check inspect array with empty string key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/15258 Refs: https://github.com/nodejs/node/issues/15159 Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Ruben Bridgewater --- test/parallel/test-util-inspect.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 2f3ef367328f9e..b17b14f65cba99 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -831,6 +831,12 @@ checkAlignment(new Map(big_array.map(function(y) { return [y, null]; }))); assert.strictEqual(util.inspect(x), '{}'); } +{ + const x = []; + x[''] = 1; + assert.strictEqual(util.inspect(x), '[ \'\': 1 ]'); +} + // The following maxArrayLength tests were introduced after v6.0.0 was released. // Do not backport to v5/v4 unless all of // https://github.com/nodejs/node/pull/6334 is backported. From 10a70353b27e0d8c8cfaab4d514284b868e56309 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 9 Sep 2017 18:41:56 -0400 Subject: [PATCH 044/128] crypto: fix Node_SignFinal PR #11705 switched Node away from using using OpenSSL's legacy EVP_Sign* and EVP_Verify* APIs. Instead, it computes a hash normally via EVP_Digest* and then uses EVP_PKEY_sign and EVP_PKEY_verify to verify the hash directly. This change corrects two problems: 1. The documentation still recommends the signature algorithm EVP_MD names of OpenSSL's legacy APIs. OpenSSL has since moved away from thosee, which is why ECDSA was strangely inconsistent. (This is why "ecdsa-with-SHA256" was missing.) 2. Node_SignFinal copied some code from EVP_SignFinal's internals. This is problematic for OpenSSL 1.1.0 and is missing a critical check that prevents pkey->pkey.ptr from being cast to the wrong type. To resolve this, remove the non-EVP_PKEY_sign codepath. This codepath is no longer necessary. PR #11705's verify half was already assuming all EVP_PKEYs supported EVP_PKEY_sign and EVP_PKEY_verify. Also, in the documentation, point users towards using hash function names which are more consisent. This avoids an ECDSA special-case and some strangeness around RSA-PSS ("RSA-SHA256" is the OpenSSL name of the sha256WithRSAEncryption OID which is not used for RSA-PSS). PR-URL: https://github.com/nodejs/node/pull/15024 Reviewed-By: Shigeki Ohtsu Reviewed-By: Ruben Bridgewater --- .../crypto/rsa-sign-verify-throughput.js | 2 +- doc/api/crypto.md | 40 ++++++++-------- src/node_crypto.cc | 47 ++++++++----------- test/fixtures/0-dns/create-cert.js | 4 +- test/parallel/test-crypto-binary-default.js | 24 +++++----- test/parallel/test-crypto-rsa-dsa.js | 46 +++++++++++++----- test/parallel/test-crypto-sign-verify.js | 36 +++++++------- test/parallel/test-crypto-verify-failure.js | 2 +- test/parallel/test-crypto.js | 6 +-- test/parallel/test-dsa-fips-invalid-key.js | 2 +- 10 files changed, 110 insertions(+), 99 deletions(-) diff --git a/benchmark/crypto/rsa-sign-verify-throughput.js b/benchmark/crypto/rsa-sign-verify-throughput.js index c5db94687a1aac..88ee16e16bef42 100644 --- a/benchmark/crypto/rsa-sign-verify-throughput.js +++ b/benchmark/crypto/rsa-sign-verify-throughput.js @@ -18,7 +18,7 @@ keylen_list.forEach(function(key) { var bench = common.createBenchmark(main, { writes: [500], - algo: ['RSA-SHA1', 'RSA-SHA224', 'RSA-SHA256', 'RSA-SHA384', 'RSA-SHA512'], + algo: ['SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512'], keylen: keylen_list, len: [1024, 102400, 2 * 102400, 3 * 102400, 1024 * 1024] }); diff --git a/doc/api/crypto.md b/doc/api/crypto.md index f49d055d820bff..2adaf28ed53504 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -842,28 +842,31 @@ of two ways: - Using the [`sign.update()`][] and [`sign.sign()`][] methods to produce the signature. -The [`crypto.createSign()`][] method is used to create `Sign` instances. `Sign` -objects are not to be created directly using the `new` keyword. +The [`crypto.createSign()`][] method is used to create `Sign` instances. The +argument is the string name of the hash function to use. `Sign` objects are not +to be created directly using the `new` keyword. Example: Using `Sign` objects as streams: ```js const crypto = require('crypto'); -const sign = crypto.createSign('RSA-SHA256'); +const sign = crypto.createSign('SHA256'); sign.write('some data to sign'); sign.end(); const privateKey = getPrivateKeySomehow(); console.log(sign.sign(privateKey, 'hex')); -// Prints: the calculated signature +// Prints: the calculated signature using the specified private key and +// SHA-256. For RSA keys, the algorithm is RSASSA-PKCS1-v1_5 (see padding +// parameter below for RSASSA-PSS). For EC keys, the algorithm is ECDSA. ``` Example: Using the [`sign.update()`][] and [`sign.sign()`][] methods: ```js const crypto = require('crypto'); -const sign = crypto.createSign('RSA-SHA256'); +const sign = crypto.createSign('SHA256'); sign.update('some data to sign'); @@ -872,27 +875,22 @@ console.log(sign.sign(privateKey, 'hex')); // Prints: the calculated signature ``` -A `Sign` instance can also be created by just passing in the digest -algorithm name, in which case OpenSSL will infer the full signature algorithm -from the type of the PEM-formatted private key, including algorithms that -do not have directly exposed name constants, e.g. 'ecdsa-with-SHA256'. +In some cases, a `Sign` instance can also be created by passing in a signature +algorithm name, such as 'RSA-SHA256'. This will use the corresponding digest +algorithm. This does not work for all signature algorithms, such as +'ecdsa-with-SHA256'. Use digest names instead. -Example: signing using ECDSA with SHA256 +Example: signing using legacy signature algorithm name ```js const crypto = require('crypto'); -const sign = crypto.createSign('sha256'); +const sign = crypto.createSign('RSA-SHA256'); sign.update('some data to sign'); -const privateKey = -`-----BEGIN EC PRIVATE KEY----- -MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49 -AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2 -pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng== ------END EC PRIVATE KEY-----`; - -console.log(sign.sign(privateKey).toString('hex')); +const privateKey = getPrivateKeySomehow(); +console.log(sign.sign(privateKey, 'hex')); +// Prints: the calculated signature ``` ### sign.sign(private_key[, output_format]) @@ -965,7 +963,7 @@ Example: Using `Verify` objects as streams: ```js const crypto = require('crypto'); -const verify = crypto.createVerify('RSA-SHA256'); +const verify = crypto.createVerify('SHA256'); verify.write('some data to sign'); verify.end(); @@ -980,7 +978,7 @@ Example: Using the [`verify.update()`][] and [`verify.verify()`][] methods: ```js const crypto = require('crypto'); -const verify = crypto.createVerify('RSA-SHA256'); +const verify = crypto.createVerify('SHA256'); verify.update('some data to sign'); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 5cb6ab8ca18173..573d3b8ed6d1c5 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3993,7 +3993,8 @@ void SignBase::CheckThrow(SignBase::Error error) { static bool ApplyRSAOptions(EVP_PKEY* pkey, EVP_PKEY_CTX* pkctx, int padding, int salt_len) { - if (pkey->type == EVP_PKEY_RSA || pkey->type == EVP_PKEY_RSA2) { + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA || + EVP_PKEY_id(pkey) == EVP_PKEY_RSA2) { if (EVP_PKEY_CTX_set_rsa_padding(pkctx, padding) <= 0) return false; if (padding == RSA_PKCS1_PSS_PADDING) { @@ -4102,33 +4103,23 @@ static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md, if (!EVP_DigestFinal_ex(mdctx, m, &m_len)) return rv; - if (mdctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { - size_t sltmp = static_cast(EVP_PKEY_size(pkey)); - pkctx = EVP_PKEY_CTX_new(pkey, nullptr); - if (pkctx == nullptr) - goto err; - if (EVP_PKEY_sign_init(pkctx) <= 0) - goto err; - if (!ApplyRSAOptions(pkey, pkctx, padding, pss_salt_len)) - goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, mdctx->digest) <= 0) - goto err; - if (EVP_PKEY_sign(pkctx, md, &sltmp, m, m_len) <= 0) - goto err; - *sig_len = sltmp; - rv = 1; - err: - EVP_PKEY_CTX_free(pkctx); - return rv; - } - - if (mdctx->digest->sign == nullptr) { - EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED); - return 0; - } - - return mdctx->digest->sign(mdctx->digest->type, m, m_len, md, sig_len, - pkey->pkey.ptr); + size_t sltmp = static_cast(EVP_PKEY_size(pkey)); + pkctx = EVP_PKEY_CTX_new(pkey, nullptr); + if (pkctx == nullptr) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (!ApplyRSAOptions(pkey, pkctx, padding, pss_salt_len)) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(mdctx)) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, md, &sltmp, m, m_len) <= 0) + goto err; + *sig_len = sltmp; + rv = 1; + err: + EVP_PKEY_CTX_free(pkctx); + return rv; } SignBase::Error Sign::SignFinal(const char* key_pem, diff --git a/test/fixtures/0-dns/create-cert.js b/test/fixtures/0-dns/create-cert.js index 7a353906e4bbec..9a72104887a9d2 100644 --- a/test/fixtures/0-dns/create-cert.js +++ b/test/fixtures/0-dns/create-cert.js @@ -8,7 +8,7 @@ const BN = asn1.bignum; const id_at_commonName = [ 2, 5, 4, 3 ]; const rsaEncryption = [1, 2, 840, 113549, 1, 1, 1]; const sha256WithRSAEncryption = [1, 2, 840, 113549, 1, 1, 11]; -const sigalg = 'RSA-SHA256'; +const digest = 'SHA256'; const private_key = fs.readFileSync('./0-dns-key.pem'); // public key file can be generated from the private key with @@ -59,7 +59,7 @@ const tbs = { const tbs_der = rfc5280.TBSCertificate.encode(tbs, 'der'); -const sign = crypto.createSign(sigalg); +const sign = crypto.createSign(digest); sign.update(tbs_der); const signature = sign.sign(private_key); diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index 4f42c76f0ee7fd..6795bb44a765a7 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -404,28 +404,28 @@ assert.throws(function() { }, /^Error: Digest method not supported$/); // Test signing and verifying -const s1 = crypto.createSign('RSA-SHA1') +const s1 = crypto.createSign('SHA1') .update('Test123') .sign(keyPem, 'base64'); -const s1Verified = crypto.createVerify('RSA-SHA1') +const s1Verified = crypto.createVerify('SHA1') .update('Test') .update('123') .verify(certPem, s1, 'base64'); assert.strictEqual(s1Verified, true, 'sign and verify (base 64)'); -const s2 = crypto.createSign('RSA-SHA256') +const s2 = crypto.createSign('SHA256') .update('Test123') .sign(keyPem); // binary -const s2Verified = crypto.createVerify('RSA-SHA256') +const s2Verified = crypto.createVerify('SHA256') .update('Test') .update('123') .verify(certPem, s2); // binary assert.strictEqual(s2Verified, true, 'sign and verify (binary)'); -const s3 = crypto.createSign('RSA-SHA1') +const s3 = crypto.createSign('SHA1') .update('Test123') .sign(keyPem, 'buffer'); -const s3Verified = crypto.createVerify('RSA-SHA1') +const s3Verified = crypto.createVerify('SHA1') .update('Test') .update('123') .verify(certPem, s3); @@ -569,8 +569,8 @@ const d = crypto.createDiffieHellman(p, 'hex'); assert.strictEqual(d.verifyError, DH_NOT_SUITABLE_GENERATOR); // Test RSA key signing/verification -const rsaSign = crypto.createSign('RSA-SHA1'); -const rsaVerify = crypto.createVerify('RSA-SHA1'); +const rsaSign = crypto.createSign('SHA1'); +const rsaVerify = crypto.createVerify('SHA1'); assert.ok(rsaSign instanceof crypto.Sign); assert.ok(rsaVerify instanceof crypto.Verify); @@ -606,13 +606,13 @@ assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' + '0ddfb299bedeb1ad'; - const sign = crypto.createSign('RSA-SHA256'); + const sign = crypto.createSign('SHA256'); sign.update(input); const output = sign.sign(privateKey, 'hex'); assert.strictEqual(output, signature); - const verify = crypto.createVerify('RSA-SHA256'); + const verify = crypto.createVerify('SHA256'); verify.update(input); assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); @@ -631,11 +631,11 @@ assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); // DSA signatures vary across runs so there is no static string to verify // against - const sign = crypto.createSign('DSS1'); + const sign = crypto.createSign('SHA1'); sign.update(input); const signature = sign.sign(privateKey, 'hex'); - const verify = crypto.createVerify('DSS1'); + const verify = crypto.createVerify('SHA1'); verify.update(input); assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); diff --git a/test/parallel/test-crypto-rsa-dsa.js b/test/parallel/test-crypto-rsa-dsa.js index 96bf9de3b4dc94..f0d06cf6886744 100644 --- a/test/parallel/test-crypto-rsa-dsa.js +++ b/test/parallel/test-crypto-rsa-dsa.js @@ -132,8 +132,8 @@ test_rsa('RSA_PKCS1_PADDING'); test_rsa('RSA_PKCS1_OAEP_PADDING'); // Test RSA key signing/verification -let rsaSign = crypto.createSign('RSA-SHA1'); -let rsaVerify = crypto.createVerify('RSA-SHA1'); +let rsaSign = crypto.createSign('SHA1'); +let rsaVerify = crypto.createVerify('SHA1'); assert.ok(rsaSign); assert.ok(rsaVerify); @@ -152,7 +152,7 @@ rsaVerify.update(rsaPubPem); assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); // Test RSA key signing/verification with encrypted key -rsaSign = crypto.createSign('RSA-SHA1'); +rsaSign = crypto.createSign('SHA1'); rsaSign.update(rsaPubPem); assert.doesNotThrow(() => { const signOptions = { key: rsaKeyPemEncrypted, passphrase: 'password' }; @@ -160,11 +160,11 @@ assert.doesNotThrow(() => { }); assert.strictEqual(rsaSignature, expectedSignature); -rsaVerify = crypto.createVerify('RSA-SHA1'); +rsaVerify = crypto.createVerify('SHA1'); rsaVerify.update(rsaPubPem); assert.strictEqual(rsaVerify.verify(rsaPubPem, rsaSignature, 'hex'), true); -rsaSign = crypto.createSign('RSA-SHA1'); +rsaSign = crypto.createSign('SHA1'); rsaSign.update(rsaPubPem); assert.throws(() => { const signOptions = { key: rsaKeyPemEncrypted, passphrase: 'wrong' }; @@ -188,16 +188,28 @@ assert.throws(() => { '8195e0268da7eda23d9825ac43c724e86ceeee0d0d4465678652ccaf6501' + '0ddfb299bedeb1ad'; - const sign = crypto.createSign('RSA-SHA256'); + const sign = crypto.createSign('SHA256'); sign.update(input); const output = sign.sign(privateKey, 'hex'); assert.strictEqual(signature, output); - const verify = crypto.createVerify('RSA-SHA256'); + const verify = crypto.createVerify('SHA256'); verify.update(input); assert.strictEqual(verify.verify(publicKey, signature, 'hex'), true); + + // Test the legacy signature algorithm name. + const sign2 = crypto.createSign('RSA-SHA256'); + sign2.update(input); + + const output2 = sign2.sign(privateKey, 'hex'); + assert.strictEqual(signature, output2); + + const verify2 = crypto.createVerify('SHA256'); + verify2.update(input); + + assert.strictEqual(verify2.verify(publicKey, signature, 'hex'), true); } @@ -209,14 +221,24 @@ assert.throws(() => { // DSA signatures vary across runs so there is no static string to verify // against - const sign = crypto.createSign('DSS1'); + const sign = crypto.createSign('SHA1'); sign.update(input); const signature = sign.sign(dsaKeyPem, 'hex'); - const verify = crypto.createVerify('DSS1'); + const verify = crypto.createVerify('SHA1'); verify.update(input); assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); + + // Test the legacy 'DSS1' name. + const sign2 = crypto.createSign('DSS1'); + sign2.update(input); + const signature2 = sign2.sign(dsaKeyPem, 'hex'); + + const verify2 = crypto.createVerify('DSS1'); + verify2.update(input); + + assert.strictEqual(verify2.verify(dsaPubPem, signature2, 'hex'), true); } @@ -226,7 +248,7 @@ assert.throws(() => { const input = 'I AM THE WALRUS'; { - const sign = crypto.createSign('DSS1'); + const sign = crypto.createSign('SHA1'); sign.update(input); assert.throws(() => { sign.sign({ key: dsaKeyPemEncrypted, passphrase: 'wrong' }, 'hex'); @@ -236,7 +258,7 @@ const input = 'I AM THE WALRUS'; { // DSA signatures vary across runs so there is no static string to verify // against - const sign = crypto.createSign('DSS1'); + const sign = crypto.createSign('SHA1'); sign.update(input); let signature; @@ -245,7 +267,7 @@ const input = 'I AM THE WALRUS'; signature = sign.sign(signOptions, 'hex'); }); - const verify = crypto.createVerify('DSS1'); + const verify = crypto.createVerify('SHA1'); verify.update(input); assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index bb436c340e312a..f6afb934a4d38b 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -21,15 +21,15 @@ const modSize = 1024; // Test signing and verifying { - const s1 = crypto.createSign('RSA-SHA1') + const s1 = crypto.createSign('SHA1') .update('Test123') .sign(keyPem, 'base64'); - let s1stream = crypto.createSign('RSA-SHA1'); + let s1stream = crypto.createSign('SHA1'); s1stream.end('Test123'); s1stream = s1stream.sign(keyPem, 'base64'); assert.strictEqual(s1, s1stream, 'Stream produces same output'); - const verified = crypto.createVerify('RSA-SHA1') + const verified = crypto.createVerify('SHA1') .update('Test') .update('123') .verify(certPem, s1, 'base64'); @@ -37,21 +37,21 @@ const modSize = 1024; } { - const s2 = crypto.createSign('RSA-SHA256') + const s2 = crypto.createSign('SHA256') .update('Test123') .sign(keyPem, 'latin1'); - let s2stream = crypto.createSign('RSA-SHA256'); + let s2stream = crypto.createSign('SHA256'); s2stream.end('Test123'); s2stream = s2stream.sign(keyPem, 'latin1'); assert.strictEqual(s2, s2stream, 'Stream produces same output'); - let verified = crypto.createVerify('RSA-SHA256') + let verified = crypto.createVerify('SHA256') .update('Test') .update('123') .verify(certPem, s2, 'latin1'); assert.strictEqual(verified, true, 'sign and verify (latin1)'); - const verStream = crypto.createVerify('RSA-SHA256'); + const verStream = crypto.createVerify('SHA256'); verStream.write('Tes'); verStream.write('t12'); verStream.end('3'); @@ -60,16 +60,16 @@ const modSize = 1024; } { - const s3 = crypto.createSign('RSA-SHA1') + const s3 = crypto.createSign('SHA1') .update('Test123') .sign(keyPem, 'buffer'); - let verified = crypto.createVerify('RSA-SHA1') + let verified = crypto.createVerify('SHA1') .update('Test') .update('123') .verify(certPem, s3); assert.strictEqual(verified, true, 'sign and verify (buffer)'); - const verStream = crypto.createVerify('RSA-SHA1'); + const verStream = crypto.createVerify('SHA1'); verStream.write('Tes'); verStream.write('t12'); verStream.end('3'); @@ -170,8 +170,8 @@ const modSize = 1024; }); } - testPSS('RSA-SHA1', 20); - testPSS('RSA-SHA256', 32); + testPSS('SHA1', 20); + testPSS('SHA256', 32); } // Test vectors for RSA_PKCS1_PSS_PADDING provided by the RSA Laboratories: @@ -179,7 +179,7 @@ const modSize = 1024; { // We only test verification as we cannot specify explicit salts when signing function testVerify(cert, vector) { - const verified = crypto.createVerify('RSA-SHA1') + const verified = crypto.createVerify('SHA1') .update(Buffer.from(vector.message, 'hex')) .verify({ key: cert, @@ -206,7 +206,7 @@ const modSize = 1024; [null, undefined, NaN, 'boom', {}, [], true, false] .forEach((invalidValue) => { assert.throws(() => { - crypto.createSign('RSA-SHA256') + crypto.createSign('SHA256') .update('Test123') .sign({ key: keyPem, @@ -215,7 +215,7 @@ const modSize = 1024; }, /^TypeError: padding must be an integer$/); assert.throws(() => { - crypto.createSign('RSA-SHA256') + crypto.createSign('SHA256') .update('Test123') .sign({ key: keyPem, @@ -226,7 +226,7 @@ const modSize = 1024; }); assert.throws(() => { - crypto.createSign('RSA-SHA1') + crypto.createSign('SHA1') .update('Test123') .sign({ key: keyPem, @@ -238,7 +238,7 @@ const modSize = 1024; // Test throws exception when key options is null { assert.throws(() => { - crypto.createSign('RSA-SHA1').update('Test123').sign(null, 'base64'); + crypto.createSign('SHA1').update('Test123').sign(null, 'base64'); }, /^Error: No key provided to sign$/); } @@ -254,7 +254,7 @@ const modSize = 1024; const privkey = fs.readFileSync(privfile); const msg = 'Test123'; - const s5 = crypto.createSign('RSA-SHA256') + const s5 = crypto.createSign('SHA256') .update(msg) .sign({ key: privkey, diff --git a/test/parallel/test-crypto-verify-failure.js b/test/parallel/test-crypto-verify-failure.js index dd7923dce74885..eb799383d5d120 100644 --- a/test/parallel/test-crypto-verify-failure.js +++ b/test/parallel/test-crypto-verify-failure.js @@ -28,7 +28,7 @@ const server = tls.Server(options, (socket) => { }); function verify() { - crypto.createVerify('RSA-SHA1') + crypto.createVerify('SHA1') .update('Test') .verify(certPem, 'asdfasdfas', 'base64'); } diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index f1acae97e1f284..702135a38a0e8a 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -125,11 +125,11 @@ assert.throws(function() { }, /^TypeError: Bad input string$/); assert.throws(function() { - crypto.createSign('RSA-SHA1').update('0', 'hex'); + crypto.createSign('SHA1').update('0', 'hex'); }, /^TypeError: Bad input string$/); assert.throws(function() { - crypto.createVerify('RSA-SHA1').update('0', 'hex'); + crypto.createVerify('SHA1').update('0', 'hex'); }, /^TypeError: Bad input string$/); assert.throws(function() { @@ -142,7 +142,7 @@ assert.throws(function() { '-----END RSA PRIVATE KEY-----', '' ].join('\n'); - crypto.createSign('RSA-SHA256').update('test').sign(priv); + crypto.createSign('SHA256').update('test').sign(priv); }, /digest too big for rsa key$/); assert.throws(function() { diff --git a/test/parallel/test-dsa-fips-invalid-key.js b/test/parallel/test-dsa-fips-invalid-key.js index b88c05a87cbf85..bb12e56ba5879a 100644 --- a/test/parallel/test-dsa-fips-invalid-key.js +++ b/test/parallel/test-dsa-fips-invalid-key.js @@ -11,7 +11,7 @@ const input = 'hello'; const dsapri = fs.readFileSync( `${common.fixturesDir}/keys/dsa_private_1025.pem`); -const sign = crypto.createSign('DSS1'); +const sign = crypto.createSign('SHA1'); sign.update(input); assert.throws(function() { From c4b06b279dad8dbaf8f20ba17477e0bef9eb1bc5 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 1 Sep 2017 13:02:50 -0700 Subject: [PATCH 045/128] test: remove random timer in test-tls-fast-writing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test-tls-fast-writing can fail on a heavily-loaded system due to an arbitrary 1-second timeout. Remove the arbitrary timeout. PR-URL: https://github.com/nodejs/node/pull/15138 Reviewed-By: Anna Henningsen Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: Ruben Bridgewater Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- test/parallel/test-tls-fast-writing.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/parallel/test-tls-fast-writing.js b/test/parallel/test-tls-fast-writing.js index b8605ca00bb4ea..c91c66085102c2 100644 --- a/test/parallel/test-tls-fast-writing.js +++ b/test/parallel/test-tls-fast-writing.js @@ -16,11 +16,6 @@ const server = tls.createServer(options, onconnection); let gotChunk = false; let gotDrain = false; -setTimeout(function() { - console.log('not ok - timed out'); - process.exit(1); -}, common.platformTimeout(1000)); - function onconnection(conn) { conn.on('data', function(c) { if (!gotChunk) { From 514ef7452c38fcf0821b5b2ec3b25ae568e3bb3f Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 4 Sep 2017 18:44:25 -0700 Subject: [PATCH 046/128] test: make test-http-agent-maxsockets robust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a slow/busy machine, `test-http-agent-maxsockets` can fail if the test takes longer than 5 seconds because that is the default value for `server.keepAliveTimeout`. Disable `keepAliveTimeout` to make the test robust. PR-URL: https://github.com/nodejs/node/pull/15192 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Ruben Bridgewater Reviewed-By: Tobias Nießen --- test/parallel/test-http-agent-maxsockets.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/parallel/test-http-agent-maxsockets.js b/test/parallel/test-http-agent-maxsockets.js index 66fffba250513f..4d422f4a90b4f9 100644 --- a/test/parallel/test-http-agent-maxsockets.js +++ b/test/parallel/test-http-agent-maxsockets.js @@ -15,6 +15,8 @@ const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); }, 2)); +server.keepAliveTimeout = 0; + function get(path, callback) { return http.get({ host: 'localhost', From ccdc1943503fb96fc3b4092804c5246435a9ee4c Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Tue, 17 Oct 2017 13:09:38 +0300 Subject: [PATCH 047/128] doc: fix some internal links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/15293 Reviewed-By: Claudio Rodriguez Reviewed-By: Ruben Bridgewater Reviewed-By: Luigi Pinca Reviewed-By: Franziska Hinkelmann Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen --- doc/api/cluster.md | 4 ++-- doc/api/process.md | 8 ++++---- doc/api/stream.md | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/api/cluster.md b/doc/api/cluster.md index a846ef0b55d2a0..c73289d7314b7d 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -838,8 +838,8 @@ socket.on('data', (id) => { ``` [`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options -[`ChildProcess.send()`]: child_process.html#child_process_child_send_message_sendhandle_options_callback -[`disconnect`]: child_process.html#child_process_child_disconnect +[`ChildProcess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback +[`disconnect`]: child_process.html#child_process_subprocess_disconnect [`kill`]: process.html#process_process_kill_pid_signal [`server.close()`]: net.html#net_event_close [`worker.exitedAfterDisconnect`]: #cluster_worker_exitedafterdisconnect diff --git a/doc/api/process.md b/doc/api/process.md index bbcef7002dea95..40b88d574365b2 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -430,7 +430,7 @@ It is important to take note of the following: called asynchronously and therefore unable to correct the underlying problem. *Note*: Windows does not support sending signals, but Node.js offers some -emulation with [`process.kill()`][], and [`ChildProcess.kill()`][]. Sending +emulation with [`process.kill()`][], and [`subprocess.kill()`][]. Sending signal `0` can be used to test for the existence of a process. Sending `SIGINT`, `SIGTERM`, and `SIGKILL` cause the unconditional termination of the target process. @@ -1779,9 +1779,9 @@ cases: [`'message'`]: child_process.html#child_process_event_message [`'rejectionHandled'`]: #process_event_rejectionhandled [`'uncaughtException'`]: #process_event_uncaughtexception -[`ChildProcess.disconnect()`]: child_process.html#child_process_child_disconnect -[`ChildProcess.kill()`]: child_process.html#child_process_child_kill_signal -[`ChildProcess.send()`]: child_process.html#child_process_child_send_message_sendhandle_options_callback +[`ChildProcess.disconnect()`]: child_process.html#child_process_subprocess_disconnect +[`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal +[`ChildProcess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback [`ChildProcess`]: child_process.html#child_process_class_childprocess [`end()`]: stream.html#stream_writable_end_chunk_encoding_callback [`Error`]: errors.html#errors_class_error diff --git a/doc/api/stream.md b/doc/api/stream.md index c4378a2f8ac7af..21194fc10a0090 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -2064,8 +2064,8 @@ contain multi-byte characters. [`writable.uncork()`]: #stream_writable_uncork [API for Stream Consumers]: #stream_api_for_stream_consumers [API for Stream Implementers]: #stream_api_for_stream_implementers -[child process stdin]: child_process.html#child_process_child_stdin -[child process stdout and stderr]: child_process.html#child_process_child_stdout +[child process stdin]: child_process.html#child_process_subprocess_stdin +[child process stdout and stderr]: child_process.html#child_process_subprocess_stdout [Compatibility]: #stream_compatibility_with_older_node_js_versions [crypto]: crypto.html [Duplex]: #stream_class_stream_duplex @@ -2080,7 +2080,7 @@ contain multi-byte characters. [http-incoming-message]: http.html#http_class_http_incomingmessage [Readable]: #stream_class_stream_readable [zlib]: zlib.html -[hwm-gotcha]: #stream_highWaterMark_discrepency_after_calling_readable_setencoding +[hwm-gotcha]: #stream_highwatermark_discrepency_after_calling_readable_setencoding [Readable]: #stream_class_stream_readable [stream-_flush]: #stream_transform_flush_callback [stream-_read]: #stream_readable_read_size_1 From 96a64af7a6b0c9162ec7907ec4c9ec059b489802 Mon Sep 17 00:00:00 2001 From: icarter09 Date: Fri, 11 Aug 2017 23:04:41 -0400 Subject: [PATCH 048/128] test: use reserved invalid hostname for tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14781 Refs: https://tools.ietf.org/html/rfc2606#section-2 Reviewed-By: Rich Trott Reviewed-By: Gibson Fahnestock Reviewed-By: James M Snell Reviewed-By: Tobias Nießen --- .../test-net-better-error-messages-port-hostname.js | 4 ++-- test/parallel/test-net-connect-immediate-finish.js | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-net-better-error-messages-port-hostname.js b/test/parallel/test-net-better-error-messages-port-hostname.js index 04974908c91e87..dac17141677dcb 100644 --- a/test/parallel/test-net-better-error-messages-port-hostname.js +++ b/test/parallel/test-net-better-error-messages-port-hostname.js @@ -4,12 +4,12 @@ const net = require('net'); const assert = require('assert'); // Using port 0 as hostname used is already invalid. -const c = net.createConnection(0, '***'); +const c = net.createConnection(0, 'this.hostname.is.invalid'); c.on('connect', common.mustNotCall()); c.on('error', common.mustCall(function(e) { assert.strictEqual(e.code, 'ENOTFOUND'); assert.strictEqual(e.port, 0); - assert.strictEqual(e.hostname, '***'); + assert.strictEqual(e.hostname, 'this.hostname.is.invalid'); })); diff --git a/test/parallel/test-net-connect-immediate-finish.js b/test/parallel/test-net-connect-immediate-finish.js index 2c0f45f956df16..01b41d3b212b44 100644 --- a/test/parallel/test-net-connect-immediate-finish.js +++ b/test/parallel/test-net-connect-immediate-finish.js @@ -3,14 +3,17 @@ const common = require('../common'); const assert = require('assert'); const net = require('net'); -const client = net.connect({host: '***', port: common.PORT}); +const client = net.connect({ + host: 'this.hostname.is.invalid', + port: common.PORT +}); client.once('error', common.mustCall((err) => { assert(err); assert.strictEqual(err.code, err.errno); assert.strictEqual(err.code, 'ENOTFOUND'); assert.strictEqual(err.host, err.hostname); - assert.strictEqual(err.host, '***'); + assert.strictEqual(err.host, 'this.hostname.is.invalid'); assert.strictEqual(err.syscall, 'getaddrinfo'); })); From 6c9a9ff25ca7d3148ca4b3fe400b64d8bb3dc46c Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Sun, 17 Sep 2017 00:43:54 +0100 Subject: [PATCH 049/128] build: don't fail `make test` on source tarballs Tries to achieve the same effect as https://github.com/nodejs/node/pull/13658 without breaking source tarballs. Presumably if `tools/eslint` wasn't there at all, people would notice in the PR review! PR-URL: https://github.com/nodejs/node/pull/15441 Fixes: https://github.com/nodejs/node/issues/14513 Reviewed-By: Vse Mozhet Byt Reviewed-By: Refael Ackermann Reviewed-By: Michael Dawson Reviewed-By: James M Snell --- Makefile | 3 +-- vcbuild.bat | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 577d0e232aa22d..387be35f178d30 100644 --- a/Makefile +++ b/Makefile @@ -786,7 +786,7 @@ cpplint: @$(PYTHON) tools/cpplint.py $(CPPLINT_FILES) @$(PYTHON) tools/check-imports.py -ifneq ("","$(wildcard tools/eslint/bin/eslint.js)") +ifneq ("","$(wildcard tools/eslint/)") lint: @EXIT_STATUS=0 ; \ $(MAKE) jslint || EXIT_STATUS=$$? ; \ @@ -807,7 +807,6 @@ lint: @echo "Linting is not available through the source tarball." @echo "Use the git repo instead:" \ "$ git clone https://github.com/nodejs/node.git" - exit 1 lint-ci: lint endif diff --git a/vcbuild.bat b/vcbuild.bat index 502f1d0ec2eab2..70f94cf0145dd4 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -396,7 +396,7 @@ goto exit :jslint if defined jslint_ci goto jslint-ci if not defined jslint goto exit -if not exist tools\eslint\bin\eslint.js goto no-lint +if not exist tools\eslint goto no-lint echo running jslint %config%\node tools\eslint\bin\eslint.js --cache --rule "linebreak-style: 0" --rulesdir=tools\eslint-rules --ext=.js,.md benchmark doc lib test tools goto exit @@ -409,7 +409,7 @@ goto exit :no-lint echo Linting is not available through the source tarball. echo Use the git repo instead: $ git clone https://github.com/nodejs/node.git -exit /b 1 +goto exit :create-msvs-files-failed echo Failed to create vc project files. From 377f7b9e9ef12b741bf7f3c6f2af1865875d8e9f Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Tue, 19 Sep 2017 14:23:23 +0200 Subject: [PATCH 050/128] doc: fix 'aborted' event documentation The `'aborted'` event is only emitted on `http.IncomingMessage` instances. PR-URL: https://github.com/nodejs/node/pull/15471 Fixes: https://github.com/nodejs/node/issues/15259 Reviewed-By: Matteo Collina Reviewed-By: Minwoo Jung Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Franziska Hinkelmann Reviewed-By: Ruben Bridgewater --- doc/api/http.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/doc/api/http.md b/doc/api/http.md index 2f087d39b36767..be26d882669a84 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -284,14 +284,6 @@ added: v1.4.1 Emitted when the request has been aborted by the client. This event is only emitted on the first call to `abort()`. -### Event: 'aborted' - - -Emitted when the request has been aborted by the server and the network -socket has closed. - ### Event: 'connect' -Emitted when the request has been aborted by the client and the network -socket has closed. +Emitted when the request has been aborted and the network socket has closed. ### Event: 'close' +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `records` {string[][]} Uses the DNS protocol to resolve text queries (`TXT` records) for the -`hostname`. The `addresses` argument passed to the `callback` function is -is a two-dimensional array of the text records available for `hostname` (e.g., +`hostname`. The `records` argument passed to the `callback` function is a +two-dimensional array of the text records available for `hostname` (e.g., `[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately. From e0c4f0b85a81018d656df0a08875da334d214009 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Sun, 27 Aug 2017 22:31:29 -0400 Subject: [PATCH 116/128] test,process: run 'abort' suite on Windows Backport-PR-URL: https://github.com/nodejs/node/pull/16442 PR-URL: https://github.com/nodejs/node/pull/15056 Fixes: https://github.com/nodejs/node/issues/14012 Refs: https://github.com/nodejs/node/pull/14013 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Rich Trott --- test/abort/test-abort-uncaught-exception.js | 2 +- test/abort/test-http-parser-consume.js | 39 ++++++++++++--------- vcbuild.bat | 4 +-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/test/abort/test-abort-uncaught-exception.js b/test/abort/test-abort-uncaught-exception.js index f9847193769d2d..fb30cfba3cd34a 100644 --- a/test/abort/test-abort-uncaught-exception.js +++ b/test/abort/test-abort-uncaught-exception.js @@ -21,7 +21,7 @@ function run(flags, signals) { child.on('exit', common.mustCall(function(code, sig) { if (common.isWindows) { if (signals) - assert.strictEqual(code, 3); + assert.strictEqual(code, 0xC0000005); else assert.strictEqual(code, 1); } else { diff --git a/test/abort/test-http-parser-consume.js b/test/abort/test-http-parser-consume.js index 4a05a299a8e956..9115aba70dbf17 100644 --- a/test/abort/test-http-parser-consume.js +++ b/test/abort/test-http-parser-consume.js @@ -1,28 +1,33 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); -const http = require('http'); -const spawn = require('child_process').spawn; +const { createServer, get } = require('http'); +const { spawn } = require('child_process'); if (process.argv[2] === 'child') { - const server = http.createServer(common.mustCall((req, res) => { - res.end('hello'); - })); - + // sub-process + const server = createServer(common.mustCall((_, res) => res.end('h'))); server.listen(0, common.mustCall((s) => { - const rr = http.get( - { port: server.address().port }, - common.mustCall((d) => { - // This bad input (0) should abort the parser and the process - rr.parser.consume(0); - server.close(); - })); + const rr = get({ port: server.address().port }, common.mustCall(() => { + // This bad input (0) should abort the parser and the process + rr.parser.consume(0); + // This line should be unreachanble. + assert.fail('this should be unreachable'); + })); })); } else { - const child = spawn(process.execPath, [__filename, 'child'], - { stdio: 'inherit' }); + // super-proces + const child = spawn(process.execPath, [__filename, 'child']); + child.stdout.on('data', common.mustNotCall()); + + let stderr = ''; + child.stderr.on('data', common.mustCallAtLeast((data) => { + assert(Buffer.isBuffer(data)); + stderr += data.toString('utf8'); + }, 1)); child.on('exit', common.mustCall((code, signal) => { - assert(common.nodeProcessAborted(code, signal), - 'process should have aborted, but did not'); + assert(stderr.includes('failed'), `stderr: ${stderr}`); + const didAbort = common.nodeProcessAborted(code, signal); + assert(didAbort, `process did not abort, code:${code} signal:${signal}`); })); } diff --git a/vcbuild.bat b/vcbuild.bat index 08dfc3fd3b3f8e..78f3c242455f3c 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -58,8 +58,8 @@ if /i "%1"=="nosnapshot" set nosnapshot=1&goto arg-ok if /i "%1"=="noetw" set noetw=1&goto arg-ok if /i "%1"=="noperfctr" set noperfctr=1&goto arg-ok if /i "%1"=="licensertf" set licensertf=1&goto arg-ok -if /i "%1"=="test" set test_args=%test_args% doctool known_issues message parallel sequential addons -J&set lint_cpp=1&set lint_js=1&set build_addons=1&goto arg-ok -if /i "%1"=="test-ci" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap doctool inspector known_issues message sequential parallel addons&set cctest_args=%cctest_args% --gtest_output=tap:cctest.tap&set build_addons=1&goto arg-ok +if /i "%1"=="test" set test_args=%test_args% abort doctool known_issues message parallel sequential addons -J&set lint_cpp=1&set lint_js=1&set build_addons=1&goto arg-ok +if /i "%1"=="test-ci" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap abort doctool inspector known_issues message sequential parallel addons&set cctest_args=%cctest_args% --gtest_output=tap:cctest.tap&set build_addons=1&goto arg-ok if /i "%1"=="test-addons" set test_args=%test_args% addons&set build_addons=1&goto arg-ok if /i "%1"=="test-simple" set test_args=%test_args% sequential parallel -J&goto arg-ok if /i "%1"=="test-message" set test_args=%test_args% message&goto arg-ok From b0fadbe54fd3cc50b41255e3064baf7c5b4e45a5 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Wed, 25 Oct 2017 09:53:24 +0200 Subject: [PATCH 117/128] doc: fix typo in zlib.md PR-URL: https://github.com/nodejs/node/pull/16480 Reviewed-By: Gireesh Punathil Reviewed-By: Myles Borins --- doc/api/zlib.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/zlib.md b/doc/api/zlib.md index 6f8254f06272b4..a042379fba42c5 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -419,7 +419,7 @@ Returns a new [DeflateRaw][] object with an [options][]. is set to 8 for raw deflate streams. zlib does not have a working implementation of an 8-bit Window for raw deflate streams and would automatically set windowBit to 9 if initially set to 8. Newer versions of zlib will throw an exception. -This creates a potential DOS vector, and as such the behavior ahs been reverted +This creates a potential DOS vector, and as such the behavior has been reverted in Node.js 8, 6, and 4. Node.js version 9 and higher will throw when windowBits is set to 8. From 8386ce7645f2713c9fdd19d5d8cb68f78d4a36bd Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Fri, 3 Nov 2017 00:22:35 +0900 Subject: [PATCH 118/128] deps: upgrade openssl sources to 1.0.2m MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This replaces all sources of openssl-1.0.2m.tar.gz into deps/openssl/openssl PR-URL: https://github.com/nodejs/node/pull/16691 Reviewed-By: Ben Noordhuis Reviewed-By: Tobias Nießen Reviewed-By: Michael Dawson Reviewed-By: Myles Borins Reviewed-By: Colin Ihrig Reviewed-By: Rod Vagg Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell --- deps/openssl/openssl/CHANGES | 38 + deps/openssl/openssl/INSTALL | 6 +- deps/openssl/openssl/Makefile | 2 +- deps/openssl/openssl/Makefile.bak | 2 +- deps/openssl/openssl/NEWS | 5 + deps/openssl/openssl/README | 2 +- deps/openssl/openssl/apps/app_rand.c | 11 +- deps/openssl/openssl/apps/ca.c | 13 +- deps/openssl/openssl/apps/s_client.c | 33 +- deps/openssl/openssl/apps/s_server.c | 2 +- deps/openssl/openssl/apps/speed.c | 4 +- deps/openssl/openssl/apps/spkac.c | 19 +- deps/openssl/openssl/apps/srp.c | 66 +- deps/openssl/openssl/apps/tsget | 1 - deps/openssl/openssl/crypto/LPdir_win.c | 19 +- deps/openssl/openssl/crypto/asn1/Makefile | 4 +- deps/openssl/openssl/crypto/asn1/a_bitstr.c | 6 + .../openssl/pem2.h => crypto/asn1/asn1_int.h} | 25 +- deps/openssl/openssl/crypto/asn1/tasn_fre.c | 7 +- deps/openssl/openssl/crypto/asn1/tasn_new.c | 5 +- deps/openssl/openssl/crypto/asn1/x_name.c | 18 +- deps/openssl/openssl/crypto/asn1/x_pkey.c | 21 +- .../openssl/crypto/bn/asm/x86_64-mont5.pl | 12 +- deps/openssl/openssl/crypto/bn/bn_exp.c | 22 +- deps/openssl/openssl/crypto/bn/bn_lib.c | 3 + deps/openssl/openssl/crypto/bn/bn_mont.c | 3 + deps/openssl/openssl/crypto/bn/bn_mul.c | 40 - deps/openssl/openssl/crypto/bn/bn_x931p.c | 8 +- deps/openssl/openssl/crypto/cryptlib.c | 7 + deps/openssl/openssl/crypto/dh/Makefile | 2 +- deps/openssl/openssl/crypto/dh/dh.h | 2 + deps/openssl/openssl/crypto/dh/dh_kdf.c | 4 + deps/openssl/openssl/crypto/dh/dh_pmeth.c | 9 +- deps/openssl/openssl/crypto/dsa/dsa_ameth.c | 1 + deps/openssl/openssl/crypto/dsa/dsa_gen.c | 2 + deps/openssl/openssl/crypto/dsa/dsa_ossl.c | 42 +- .../crypto/ec/asm/ecp_nistz256-x86_64.pl | 22 +- deps/openssl/openssl/crypto/ec/ecp_mont.c | 2 + deps/openssl/openssl/crypto/ec/ecp_nistp224.c | 3 +- deps/openssl/openssl/crypto/ec/ecp_nistp256.c | 3 +- deps/openssl/openssl/crypto/ec/ecp_nistp521.c | 3 +- deps/openssl/openssl/crypto/ecdh/ech_lib.c | 9 +- deps/openssl/openssl/crypto/ecdsa/ecs_lib.c | 9 +- deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c | 24 +- deps/openssl/openssl/crypto/err/err.c | 19 +- .../openssl/crypto/evp/e_aes_cbc_hmac_sha1.c | 13 +- .../crypto/evp/e_aes_cbc_hmac_sha256.c | 21 +- deps/openssl/openssl/crypto/evp/evp.h | 92 + deps/openssl/openssl/crypto/evp/evp_key.c | 20 +- deps/openssl/openssl/crypto/evp/pmeth_lib.c | 167 + deps/openssl/openssl/crypto/ex_data.c | 9 +- .../openssl/crypto/include/internal/bn_conf.h | 28 - .../crypto/include/internal/dso_conf.h | 16 - deps/openssl/openssl/crypto/lhash/lhash.c | 77 +- deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c | 2 + deps/openssl/openssl/crypto/opensslconf.h | 266 +- deps/openssl/openssl/crypto/opensslv.h | 6 +- deps/openssl/openssl/crypto/pem/pem_lib.c | 3 +- deps/openssl/openssl/crypto/pem/pem_pk8.c | 1 + deps/openssl/openssl/crypto/pem/pem_pkey.c | 1 + .../openssl/openssl/crypto/perlasm/x86masm.pl | 14 +- deps/openssl/openssl/crypto/pkcs12/p12_kiss.c | 21 +- deps/openssl/openssl/crypto/rand/rand_win.c | 35 +- deps/openssl/openssl/crypto/rsa/rsa_ameth.c | 2 +- deps/openssl/openssl/crypto/rsa/rsa_oaep.c | 8 +- deps/openssl/openssl/crypto/rsa/rsa_pk1.c | 6 +- deps/openssl/openssl/crypto/rsa/rsa_pmeth.c | 75 +- deps/openssl/openssl/crypto/ui/ui_lib.c | 1 + .../openssl/openssl/crypto/whrlpool/wp_dgst.c | 4 +- deps/openssl/openssl/crypto/x509/by_dir.c | 1 + deps/openssl/openssl/crypto/x509/by_file.c | 10 +- deps/openssl/openssl/crypto/x509v3/pcy_tree.c | 14 +- deps/openssl/openssl/crypto/x509v3/v3_addr.c | 10 +- deps/openssl/openssl/crypto/x509v3/v3_genn.c | 1 + deps/openssl/openssl/crypto/x509v3/v3_ncons.c | 51 +- deps/openssl/openssl/crypto/x86_64cpuid.pl | 19 +- deps/openssl/openssl/doc-nits | 0 deps/openssl/openssl/doc/apps/asn1parse.pod | 1 + deps/openssl/openssl/doc/apps/ca.pod | 1 + deps/openssl/openssl/doc/apps/ciphers.pod | 1 + deps/openssl/openssl/doc/apps/cms.pod | 1 + deps/openssl/openssl/doc/apps/crl.pod | 1 + deps/openssl/openssl/doc/apps/crl2pkcs7.pod | 1 + deps/openssl/openssl/doc/apps/dgst.pod | 1 + deps/openssl/openssl/doc/apps/dhparam.pod | 1 + deps/openssl/openssl/doc/apps/dsa.pod | 1 + deps/openssl/openssl/doc/apps/dsaparam.pod | 1 + deps/openssl/openssl/doc/apps/ec.pod | 1 + deps/openssl/openssl/doc/apps/ecparam.pod | 1 + deps/openssl/openssl/doc/apps/enc.pod | 1 + deps/openssl/openssl/doc/apps/errstr.pod | 1 + deps/openssl/openssl/doc/apps/gendsa.pod | 1 + deps/openssl/openssl/doc/apps/genpkey.pod | 1 + deps/openssl/openssl/doc/apps/genrsa.pod | 1 + deps/openssl/openssl/doc/apps/nseq.pod | 1 + deps/openssl/openssl/doc/apps/ocsp.pod | 1 + deps/openssl/openssl/doc/apps/passwd.pod | 1 + deps/openssl/openssl/doc/apps/pkcs12.pod | 1 + deps/openssl/openssl/doc/apps/pkcs7.pod | 1 + deps/openssl/openssl/doc/apps/pkcs8.pod | 1 + deps/openssl/openssl/doc/apps/pkey.pod | 1 + deps/openssl/openssl/doc/apps/pkeyparam.pod | 1 + deps/openssl/openssl/doc/apps/pkeyutl.pod | 1 + deps/openssl/openssl/doc/apps/rand.pod | 1 + deps/openssl/openssl/doc/apps/req.pod | 1 + deps/openssl/openssl/doc/apps/rsa.pod | 1 + deps/openssl/openssl/doc/apps/rsautl.pod | 3 +- deps/openssl/openssl/doc/apps/s_client.pod | 3 + deps/openssl/openssl/doc/apps/s_server.pod | 6 +- deps/openssl/openssl/doc/apps/s_time.pod | 1 + deps/openssl/openssl/doc/apps/sess_id.pod | 1 + deps/openssl/openssl/doc/apps/smime.pod | 1 + deps/openssl/openssl/doc/apps/speed.pod | 1 + deps/openssl/openssl/doc/apps/spkac.pod | 1 + deps/openssl/openssl/doc/apps/ts.pod | 1 + deps/openssl/openssl/doc/apps/tsget.pod | 1 + deps/openssl/openssl/doc/apps/verify.pod | 1 + deps/openssl/openssl/doc/apps/version.pod | 1 + deps/openssl/openssl/doc/apps/x509.pod | 1 + deps/openssl/openssl/doc/crypto/BN_bn2bin.pod | 5 +- deps/openssl/openssl/doc/crypto/BN_new.pod | 4 +- .../openssl/doc/crypto/EVP_EncryptInit.pod | 3 +- .../openssl/doc/crypto/EVP_PKEY_meth_new.pod | 376 ++ .../crypto/RSA_padding_add_PKCS1_type_1.pod | 7 + .../openssl/doc/crypto/RSA_public_encrypt.pod | 7 + .../doc/crypto/X509_check_private_key.pod | 54 + deps/openssl/openssl/doc/crypto/hmac.pod | 3 +- ...SSL_CTX_set_tlsext_servername_callback.pod | 0 .../doc/ssl/SSL_export_keying_material.pod | 61 + .../openssl/doc/ssl/SSL_set_connect_state.pod | 2 +- deps/openssl/openssl/include/openssl/aes.h | 149 - deps/openssl/openssl/include/openssl/asn1.h | 1419 ------ .../openssl/include/openssl/asn1_mac.h | 579 --- deps/openssl/openssl/include/openssl/asn1t.h | 973 ---- deps/openssl/openssl/include/openssl/bio.h | 883 ---- .../openssl/include/openssl/blowfish.h | 130 - deps/openssl/openssl/include/openssl/bn.h | 951 ---- deps/openssl/openssl/include/openssl/buffer.h | 125 - .../openssl/include/openssl/camellia.h | 132 - deps/openssl/openssl/include/openssl/cast.h | 107 - deps/openssl/openssl/include/openssl/cmac.h | 82 - deps/openssl/openssl/include/openssl/cms.h | 555 --- deps/openssl/openssl/include/openssl/comp.h | 83 - deps/openssl/openssl/include/openssl/conf.h | 268 -- .../openssl/include/openssl/conf_api.h | 89 - deps/openssl/openssl/include/openssl/crypto.h | 661 --- deps/openssl/openssl/include/openssl/des.h | 257 - .../openssl/openssl/include/openssl/des_old.h | 497 -- deps/openssl/openssl/include/openssl/dh.h | 410 -- deps/openssl/openssl/include/openssl/dsa.h | 332 -- deps/openssl/openssl/include/openssl/dso.h | 451 -- deps/openssl/openssl/include/openssl/dtls1.h | 272 -- deps/openssl/openssl/include/openssl/e_os2.h | 328 -- deps/openssl/openssl/include/openssl/ebcdic.h | 26 - deps/openssl/openssl/include/openssl/ec.h | 1282 ----- deps/openssl/openssl/include/openssl/ecdh.h | 134 - deps/openssl/openssl/include/openssl/ecdsa.h | 335 -- deps/openssl/openssl/include/openssl/engine.h | 960 ---- deps/openssl/openssl/include/openssl/err.h | 390 -- deps/openssl/openssl/include/openssl/evp.h | 1536 ------ deps/openssl/openssl/include/openssl/hmac.h | 109 - deps/openssl/openssl/include/openssl/idea.h | 105 - .../openssl/include/openssl/krb5_asn.h | 240 - deps/openssl/openssl/include/openssl/kssl.h | 197 - deps/openssl/openssl/include/openssl/lhash.h | 240 - deps/openssl/openssl/include/openssl/md4.h | 119 - deps/openssl/openssl/include/openssl/md5.h | 119 - deps/openssl/openssl/include/openssl/mdc2.h | 94 - deps/openssl/openssl/include/openssl/modes.h | 163 - .../openssl/openssl/include/openssl/obj_mac.h | 4194 ----------------- .../openssl/openssl/include/openssl/objects.h | 1143 ----- deps/openssl/openssl/include/openssl/ocsp.h | 637 --- .../openssl/include/openssl/opensslconf.h | 1 - .../openssl/include/openssl/opensslv.h | 97 - .../openssl/include/openssl/ossl_typ.h | 213 - deps/openssl/openssl/include/openssl/pem.h | 617 --- deps/openssl/openssl/include/openssl/pkcs12.h | 342 -- deps/openssl/openssl/include/openssl/pkcs7.h | 481 -- deps/openssl/openssl/include/openssl/pqueue.h | 99 - deps/openssl/openssl/include/openssl/rand.h | 150 - deps/openssl/openssl/include/openssl/rc2.h | 103 - deps/openssl/openssl/include/openssl/rc4.h | 88 - deps/openssl/openssl/include/openssl/ripemd.h | 105 - deps/openssl/openssl/include/openssl/rsa.h | 664 --- .../openssl/include/openssl/safestack.h | 2672 ----------- deps/openssl/openssl/include/openssl/seed.h | 149 - deps/openssl/openssl/include/openssl/sha.h | 214 - deps/openssl/openssl/include/openssl/srp.h | 179 - deps/openssl/openssl/include/openssl/srtp.h | 147 - deps/openssl/openssl/include/openssl/ssl.h | 3163 ------------- deps/openssl/openssl/include/openssl/ssl2.h | 265 -- deps/openssl/openssl/include/openssl/ssl23.h | 84 - deps/openssl/openssl/include/openssl/ssl3.h | 774 --- deps/openssl/openssl/include/openssl/stack.h | 107 - .../openssl/include/openssl/symhacks.h | 516 -- deps/openssl/openssl/include/openssl/tls1.h | 810 ---- deps/openssl/openssl/include/openssl/ts.h | 865 ---- deps/openssl/openssl/include/openssl/txt_db.h | 112 - deps/openssl/openssl/include/openssl/ui.h | 415 -- .../openssl/include/openssl/ui_compat.h | 88 - .../openssl/include/openssl/whrlpool.h | 41 - deps/openssl/openssl/include/openssl/x509.h | 1330 ------ .../openssl/include/openssl/x509_vfy.h | 652 --- deps/openssl/openssl/include/openssl/x509v3.h | 1055 ----- deps/openssl/openssl/openssl.spec | 2 +- deps/openssl/openssl/ssl/s23_clnt.c | 28 + deps/openssl/openssl/ssl/s3_pkt.c | 2 +- deps/openssl/openssl/ssl/s3_srvr.c | 36 +- deps/openssl/openssl/ssl/ssl_ciph.c | 2 +- deps/openssl/openssl/ssl/ssl_lib.c | 10 +- deps/openssl/openssl/ssl/ssl_sess.c | 6 +- deps/openssl/openssl/ssl/ssltest.c | 71 +- deps/openssl/openssl/ssl/tls1.h | 2 +- deps/openssl/openssl/test/testssl | 9 + .../openssl/openssl/util/copy-if-different.pl | 2 +- deps/openssl/openssl/util/copy.pl | 2 +- deps/openssl/openssl/util/libeay.num | 16 +- deps/openssl/openssl/util/mk1mf.pl | 4 +- 218 files changed, 1846 insertions(+), 38827 deletions(-) rename deps/openssl/openssl/{include/openssl/pem2.h => crypto/asn1/asn1_int.h} (87%) delete mode 100644 deps/openssl/openssl/crypto/include/internal/bn_conf.h delete mode 100644 deps/openssl/openssl/crypto/include/internal/dso_conf.h delete mode 100644 deps/openssl/openssl/doc-nits create mode 100644 deps/openssl/openssl/doc/crypto/EVP_PKEY_meth_new.pod create mode 100644 deps/openssl/openssl/doc/crypto/X509_check_private_key.pod rename deps/openssl/openssl/doc/{man3 => ssl}/SSL_CTX_set_tlsext_servername_callback.pod (100%) create mode 100644 deps/openssl/openssl/doc/ssl/SSL_export_keying_material.pod delete mode 100644 deps/openssl/openssl/include/openssl/aes.h delete mode 100644 deps/openssl/openssl/include/openssl/asn1.h delete mode 100644 deps/openssl/openssl/include/openssl/asn1_mac.h delete mode 100644 deps/openssl/openssl/include/openssl/asn1t.h delete mode 100644 deps/openssl/openssl/include/openssl/bio.h delete mode 100644 deps/openssl/openssl/include/openssl/blowfish.h delete mode 100644 deps/openssl/openssl/include/openssl/bn.h delete mode 100644 deps/openssl/openssl/include/openssl/buffer.h delete mode 100644 deps/openssl/openssl/include/openssl/camellia.h delete mode 100644 deps/openssl/openssl/include/openssl/cast.h delete mode 100644 deps/openssl/openssl/include/openssl/cmac.h delete mode 100644 deps/openssl/openssl/include/openssl/cms.h delete mode 100644 deps/openssl/openssl/include/openssl/comp.h delete mode 100644 deps/openssl/openssl/include/openssl/conf.h delete mode 100644 deps/openssl/openssl/include/openssl/conf_api.h delete mode 100644 deps/openssl/openssl/include/openssl/crypto.h delete mode 100644 deps/openssl/openssl/include/openssl/des.h delete mode 100644 deps/openssl/openssl/include/openssl/des_old.h delete mode 100644 deps/openssl/openssl/include/openssl/dh.h delete mode 100644 deps/openssl/openssl/include/openssl/dsa.h delete mode 100644 deps/openssl/openssl/include/openssl/dso.h delete mode 100644 deps/openssl/openssl/include/openssl/dtls1.h delete mode 100644 deps/openssl/openssl/include/openssl/e_os2.h delete mode 100644 deps/openssl/openssl/include/openssl/ebcdic.h delete mode 100644 deps/openssl/openssl/include/openssl/ec.h delete mode 100644 deps/openssl/openssl/include/openssl/ecdh.h delete mode 100644 deps/openssl/openssl/include/openssl/ecdsa.h delete mode 100644 deps/openssl/openssl/include/openssl/engine.h delete mode 100644 deps/openssl/openssl/include/openssl/err.h delete mode 100644 deps/openssl/openssl/include/openssl/evp.h delete mode 100644 deps/openssl/openssl/include/openssl/hmac.h delete mode 100644 deps/openssl/openssl/include/openssl/idea.h delete mode 100644 deps/openssl/openssl/include/openssl/krb5_asn.h delete mode 100644 deps/openssl/openssl/include/openssl/kssl.h delete mode 100644 deps/openssl/openssl/include/openssl/lhash.h delete mode 100644 deps/openssl/openssl/include/openssl/md4.h delete mode 100644 deps/openssl/openssl/include/openssl/md5.h delete mode 100644 deps/openssl/openssl/include/openssl/mdc2.h delete mode 100644 deps/openssl/openssl/include/openssl/modes.h delete mode 100644 deps/openssl/openssl/include/openssl/obj_mac.h delete mode 100644 deps/openssl/openssl/include/openssl/objects.h delete mode 100644 deps/openssl/openssl/include/openssl/ocsp.h delete mode 100644 deps/openssl/openssl/include/openssl/opensslconf.h delete mode 100644 deps/openssl/openssl/include/openssl/opensslv.h delete mode 100644 deps/openssl/openssl/include/openssl/ossl_typ.h delete mode 100644 deps/openssl/openssl/include/openssl/pem.h delete mode 100644 deps/openssl/openssl/include/openssl/pkcs12.h delete mode 100644 deps/openssl/openssl/include/openssl/pkcs7.h delete mode 100644 deps/openssl/openssl/include/openssl/pqueue.h delete mode 100644 deps/openssl/openssl/include/openssl/rand.h delete mode 100644 deps/openssl/openssl/include/openssl/rc2.h delete mode 100644 deps/openssl/openssl/include/openssl/rc4.h delete mode 100644 deps/openssl/openssl/include/openssl/ripemd.h delete mode 100644 deps/openssl/openssl/include/openssl/rsa.h delete mode 100644 deps/openssl/openssl/include/openssl/safestack.h delete mode 100644 deps/openssl/openssl/include/openssl/seed.h delete mode 100644 deps/openssl/openssl/include/openssl/sha.h delete mode 100644 deps/openssl/openssl/include/openssl/srp.h delete mode 100644 deps/openssl/openssl/include/openssl/srtp.h delete mode 100644 deps/openssl/openssl/include/openssl/ssl.h delete mode 100644 deps/openssl/openssl/include/openssl/ssl2.h delete mode 100644 deps/openssl/openssl/include/openssl/ssl23.h delete mode 100644 deps/openssl/openssl/include/openssl/ssl3.h delete mode 100644 deps/openssl/openssl/include/openssl/stack.h delete mode 100644 deps/openssl/openssl/include/openssl/symhacks.h delete mode 100644 deps/openssl/openssl/include/openssl/tls1.h delete mode 100644 deps/openssl/openssl/include/openssl/ts.h delete mode 100644 deps/openssl/openssl/include/openssl/txt_db.h delete mode 100644 deps/openssl/openssl/include/openssl/ui.h delete mode 100644 deps/openssl/openssl/include/openssl/ui_compat.h delete mode 100644 deps/openssl/openssl/include/openssl/whrlpool.h delete mode 100644 deps/openssl/openssl/include/openssl/x509.h delete mode 100644 deps/openssl/openssl/include/openssl/x509_vfy.h delete mode 100644 deps/openssl/openssl/include/openssl/x509v3.h diff --git a/deps/openssl/openssl/CHANGES b/deps/openssl/openssl/CHANGES index 307b2ed5e31287..e3d57b328c58e3 100644 --- a/deps/openssl/openssl/CHANGES +++ b/deps/openssl/openssl/CHANGES @@ -2,6 +2,44 @@ OpenSSL CHANGES _______________ + This is a high-level summary of the most important changes. + For a full list of changes, see the git commit log; for example, + https://github.com/openssl/openssl/commits/ and pick the appropriate + release branch. + + Changes between 1.0.2l and 1.0.2m [2 Nov 2017] + + *) bn_sqrx8x_internal carry bug on x86_64 + + There is a carry propagating bug in the x86_64 Montgomery squaring + procedure. No EC algorithms are affected. Analysis suggests that attacks + against RSA and DSA as a result of this defect would be very difficult to + perform and are not believed likely. Attacks against DH are considered just + feasible (although very difficult) because most of the work necessary to + deduce information about a private key may be performed offline. The amount + of resources required for such an attack would be very significant and + likely only accessible to a limited number of attackers. An attacker would + additionally need online access to an unpatched system using the target + private key in a scenario with persistent DH parameters and a private + key that is shared between multiple clients. + + This only affects processors that support the BMI1, BMI2 and ADX extensions + like Intel Broadwell (5th generation) and later or AMD Ryzen. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + (CVE-2017-3736) + [Andy Polyakov] + + *) Malformed X.509 IPAddressFamily could cause OOB read + + If an X.509 certificate has a malformed IPAddressFamily extension, + OpenSSL could do a one-byte buffer overread. The most likely result + would be an erroneous display of the certificate in text format. + + This issue was reported to OpenSSL by the OSS-Fuzz project. + (CVE-2017-3735) + [Rich Salz] + Changes between 1.0.2k and 1.0.2l [25 May 2017] *) Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target diff --git a/deps/openssl/openssl/INSTALL b/deps/openssl/openssl/INSTALL index aa7e35fa79fea0..fcdbfc0a6ee00b 100644 --- a/deps/openssl/openssl/INSTALL +++ b/deps/openssl/openssl/INSTALL @@ -190,10 +190,8 @@ the failure that isn't a problem in OpenSSL itself (like a missing or malfunctioning bc). If it is a problem with OpenSSL itself, try removing any compiler optimization flags from the CFLAG line - in Makefile.ssl and run "make clean; make". Please send a bug - report to , including the output of - "make report" in order to be added to the request tracker at - http://www.openssl.org/support/rt.html. + in Makefile.ssl and run "make clean; make". To report a bug please open an + issue on GitHub, at https://github.com/openssl/openssl/issues. 4. If everything tests ok, install OpenSSL with diff --git a/deps/openssl/openssl/Makefile b/deps/openssl/openssl/Makefile index a3d30318f9178d..484f2f45f77667 100644 --- a/deps/openssl/openssl/Makefile +++ b/deps/openssl/openssl/Makefile @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2l +VERSION=1.0.2m MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 diff --git a/deps/openssl/openssl/Makefile.bak b/deps/openssl/openssl/Makefile.bak index ea0d92e4d7db50..b545261eaeee19 100644 --- a/deps/openssl/openssl/Makefile.bak +++ b/deps/openssl/openssl/Makefile.bak @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2l +VERSION=1.0.2m MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 diff --git a/deps/openssl/openssl/NEWS b/deps/openssl/openssl/NEWS index fd49cedeba4c5c..1b72013ad18624 100644 --- a/deps/openssl/openssl/NEWS +++ b/deps/openssl/openssl/NEWS @@ -5,6 +5,11 @@ 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.0.2l and OpenSSL 1.0.2m [2 Nov 2017] + + o bn_sqrx8x_internal carry bug on x86_64 (CVE-2017-3736) + o Malformed X.509 IPAddressFamily could cause OOB read (CVE-2017-3735) + Major changes between OpenSSL 1.0.2k and OpenSSL 1.0.2l [25 May 2017] o config now recognises 64-bit mingw and chooses mingw64 instead of mingw diff --git a/deps/openssl/openssl/README b/deps/openssl/openssl/README index 4c357d9a836d08..b5aae6260ce889 100644 --- a/deps/openssl/openssl/README +++ b/deps/openssl/openssl/README @@ -1,5 +1,5 @@ - OpenSSL 1.0.2l 25 May 2017 + OpenSSL 1.0.2m 2 Nov 2017 Copyright (c) 1998-2015 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/deps/openssl/openssl/apps/app_rand.c b/deps/openssl/openssl/apps/app_rand.c index b6fe294a682711..7f40bba7646882 100644 --- a/deps/openssl/openssl/apps/app_rand.c +++ b/deps/openssl/openssl/apps/app_rand.c @@ -124,16 +124,7 @@ int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn) char buffer[200]; #ifdef OPENSSL_SYS_WINDOWS - /* - * allocate 2 to dont_warn not to use RAND_screen() via - * -no_rand_screen option in s_client - */ - if (dont_warn != 2) { - BIO_printf(bio_e, "Loading 'screen' into random state -"); - BIO_flush(bio_e); - RAND_screen(); - BIO_printf(bio_e, " done\n"); - } + RAND_screen(); #endif if (file == NULL) diff --git a/deps/openssl/openssl/apps/ca.c b/deps/openssl/openssl/apps/ca.c index f90f033baed375..9a839969a204bb 100644 --- a/deps/openssl/openssl/apps/ca.c +++ b/deps/openssl/openssl/apps/ca.c @@ -1985,10 +1985,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* Lets add the extensions, if there are any */ if (ext_sect) { X509V3_CTX ctx; - if (ci->version == NULL) - if ((ci->version = ASN1_INTEGER_new()) == NULL) - goto err; - ASN1_INTEGER_set(ci->version, 2); /* version 3 certificate */ /* * Free the current entries if any, there should not be any I believe @@ -2051,6 +2047,15 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, goto err; } + { + STACK_OF(X509_EXTENSION) *exts = ci->extensions; + + if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0) + /* Make it an X509 v3 certificate. */ + if (!X509_set_version(ret, 2)) + goto err; + } + /* Set the right value for the noemailDN option */ if (email_dn == 0) { if (!X509_set_subject_name(ret, dn_subject)) diff --git a/deps/openssl/openssl/apps/s_client.c b/deps/openssl/openssl/apps/s_client.c index ffb8ffc5af20c7..dc467994f8e242 100644 --- a/deps/openssl/openssl/apps/s_client.c +++ b/deps/openssl/openssl/apps/s_client.c @@ -180,13 +180,6 @@ typedef unsigned int u_int; # include #endif -/* Use Windows API with STD_INPUT_HANDLE when checking for input? - Don't look at OPENSSL_SYS_MSDOS for this, since it is always defined if - OPENSSL_SYS_WINDOWS is defined */ -#if defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WINCE) && defined(STD_INPUT_HANDLE) -#define OPENSSL_USE_STD_INPUT_HANDLE -#endif - #undef PROG #define PROG s_client_main @@ -236,7 +229,6 @@ static BIO *bio_c_msg = NULL; static int c_quiet = 0; static int c_ign_eof = 0; static int c_brief = 0; -static int c_no_rand_screen = 0; #ifndef OPENSSL_NO_PSK /* Default PSK identity and key */ @@ -452,10 +444,6 @@ static void sc_usage(void) " -keymatexport label - Export keying material using label\n"); BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); -#ifdef OPENSSL_SYS_WINDOWS - BIO_printf(bio_err, - " -no_rand_screen - Do not use RAND_screen() to initialize random state\n"); -#endif } #ifndef OPENSSL_NO_TLSEXT @@ -1148,10 +1136,6 @@ int MAIN(int argc, char **argv) keymatexportlen = atoi(*(++argv)); if (keymatexportlen == 0) goto bad; -#ifdef OPENSSL_SYS_WINDOWS - } else if (strcmp(*argv, "-no_rand_screen") == 0) { - c_no_rand_screen = 1; -#endif } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badop = 1; @@ -1268,7 +1252,7 @@ int MAIN(int argc, char **argv) if (!load_excert(&exc, bio_err)) goto end; - if (!app_RAND_load_file(NULL, bio_err, ++c_no_rand_screen) && inrand == NULL + if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); @@ -1683,6 +1667,8 @@ int MAIN(int argc, char **argv) if (strstr(mbuf, "/stream:features>")) goto shut; seen = BIO_read(sbio, mbuf, BUFSIZZ); + if (seen <= 0) + goto shut; mbuf[seen] = 0; } BIO_printf(sbio, @@ -1806,7 +1792,10 @@ int MAIN(int argc, char **argv) tv.tv_usec = 0; i = select(width, (void *)&readfds, (void *)&writefds, NULL, &tv); -#if defined(OPENSSL_USE_STD_INPUT_HANDLE) +# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) + if (!i && (!_kbhit() || !read_tty)) + continue; +# else if (!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle @@ -1814,8 +1803,6 @@ int MAIN(int argc, char **argv) 0))) || !read_tty)) continue; -#else - if(!i && (!_kbhit() || !read_tty) ) continue; # endif } else i = select(width, (void *)&readfds, (void *)&writefds, @@ -2017,12 +2004,12 @@ int MAIN(int argc, char **argv) } } #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -#if defined(OPENSSL_USE_STD_INPUT_HANDLE) +# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) + else if (_kbhit()) +# else else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) -#else - else if (_kbhit()) # endif #elif defined (OPENSSL_SYS_NETWARE) else if (_kbhit()) diff --git a/deps/openssl/openssl/apps/s_server.c b/deps/openssl/openssl/apps/s_server.c index d75871386928f5..98ffc09314a302 100644 --- a/deps/openssl/openssl/apps/s_server.c +++ b/deps/openssl/openssl/apps/s_server.c @@ -3017,7 +3017,7 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context) PEM_write_bio_X509(io, peer); } else BIO_puts(io, "no client certificate available\n"); - BIO_puts(io, "\r\n\r\n"); + BIO_puts(io, "\r\n\r\n"); break; } else if ((www == 2 || www == 3) && (strncmp("GET /", buf, 5) == 0)) { diff --git a/deps/openssl/openssl/apps/speed.c b/deps/openssl/openssl/apps/speed.c index 6cd1021525046c..5259c16f1218a3 100644 --- a/deps/openssl/openssl/apps/speed.c +++ b/deps/openssl/openssl/apps/speed.c @@ -307,7 +307,8 @@ static SIGRETTYPE sig_done(int sig) # if !defined(SIGALRM) # define SIGALRM # endif -static unsigned int lapse, schlock; +static volatile unsigned int lapse; +static volatile unsigned int schlock; static void alarm_win32(unsigned int secs) { lapse = secs * 1000; @@ -725,6 +726,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "no EVP given\n"); goto end; } + evp_md = NULL; evp_cipher = EVP_get_cipherbyname(*argv); if (!evp_cipher) { evp_md = EVP_get_digestbyname(*argv); diff --git a/deps/openssl/openssl/apps/spkac.c b/deps/openssl/openssl/apps/spkac.c index 7f5333fe832e99..4b4106d03b998c 100644 --- a/deps/openssl/openssl/apps/spkac.c +++ b/deps/openssl/openssl/apps/spkac.c @@ -5,7 +5,7 @@ * 1999. Based on an original idea by Massimiliano Pala (madwolf@openca.org). */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2017 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -185,20 +185,23 @@ int MAIN(int argc, char **argv) } e = setup_engine(bio_err, engine, 0); - if (keyfile) { + if (keyfile != NULL) { pkey = load_key(bio_err, strcmp(keyfile, "-") ? keyfile : NULL, FORMAT_PEM, 1, passin, e, "private key"); - if (!pkey) { + if (pkey == NULL) goto end; - } spki = NETSCAPE_SPKI_new(); - if (challenge) + if (spki == NULL) + goto end; + if (challenge != NULL) ASN1_STRING_set(spki->spkac->challenge, challenge, (int)strlen(challenge)); NETSCAPE_SPKI_set_pubkey(spki, pkey); NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); + if (spkstr == NULL) + goto end; if (outfile) out = BIO_new_file(outfile, "w"); @@ -253,7 +256,7 @@ int MAIN(int argc, char **argv) spki = NETSCAPE_SPKI_b64_decode(spkstr, -1); - if (!spki) { + if (spki == NULL) { BIO_printf(bio_err, "Error loading SPKAC\n"); ERR_print_errors(bio_err); goto end; @@ -282,9 +285,9 @@ int MAIN(int argc, char **argv) pkey = NETSCAPE_SPKI_get_pubkey(spki); if (verify) { i = NETSCAPE_SPKI_verify(spki, pkey); - if (i > 0) + if (i > 0) { BIO_printf(bio_err, "Signature OK\n"); - else { + } else { BIO_printf(bio_err, "Signature Failure\n"); ERR_print_errors(bio_err); goto end; diff --git a/deps/openssl/openssl/apps/srp.c b/deps/openssl/openssl/apps/srp.c index ce01a24f2a78c4..491445df60b00e 100644 --- a/deps/openssl/openssl/apps/srp.c +++ b/deps/openssl/openssl/apps/srp.c @@ -123,13 +123,14 @@ static int get_index(CA_DB *db, char *id, char type) int i; if (id == NULL) return -1; - if (type == DB_SRP_INDEX) + if (type == DB_SRP_INDEX) { for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id, pp[DB_srpid])) return i; - } else + } + } else { for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); @@ -137,6 +138,7 @@ static int get_index(CA_DB *db, char *id, char type) && !strcmp(id, pp[DB_srpid])) return i; } + } return -1; } @@ -177,8 +179,8 @@ static int update_index(CA_DB *db, BIO *bio, char **row) char **irow; int i; - if ((irow = - (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1))) == NULL) { + irow = (char **)OPENSSL_malloc(sizeof(char *) * (DB_NUMBER + 1)); + if (irow == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); return 0; } @@ -205,30 +207,32 @@ static char *srp_verify_user(const char *user, const char *srp_verifier, char *srp_usersalt, const char *g, const char *N, const char *passin, BIO *bio, int verbose) { - char password[1024]; + char password[1025]; PW_CB_DATA cb_tmp; char *verifier = NULL; char *gNid = NULL; + int len; cb_tmp.prompt_info = user; cb_tmp.password = passin; - if (password_callback(password, 1024, 0, &cb_tmp) > 0) { + len = password_callback(password, sizeof(password)-1, 0, &cb_tmp); + if (len > 0) { + password[len] = 0; VERBOSE BIO_printf(bio, "Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", user, srp_verifier, srp_usersalt, g, N); - BIO_printf(bio, "Pass %s\n", password); + VVERBOSE BIO_printf(bio, "Pass %s\n", password); - if (! - (gNid = - SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, - g))) { + if (!(gNid = SRP_create_verifier(user, password, &srp_usersalt, + &verifier, N, g))) { BIO_printf(bio, "Internal error validating SRP verifier\n"); } else { if (strcmp(verifier, srp_verifier)) gNid = NULL; OPENSSL_free(verifier); } + OPENSSL_cleanse(password, len); } return gNid; } @@ -237,24 +241,27 @@ static char *srp_create_user(char *user, char **srp_verifier, char **srp_usersalt, char *g, char *N, char *passout, BIO *bio, int verbose) { - char password[1024]; + char password[1025]; PW_CB_DATA cb_tmp; char *gNid = NULL; char *salt = NULL; + int len; cb_tmp.prompt_info = user; cb_tmp.password = passout; - if (password_callback(password, 1024, 1, &cb_tmp) > 0) { + len = password_callback(password, sizeof(password)-1, 1, &cb_tmp); + if (len > 0) { + password[len] = 0; VERBOSE BIO_printf(bio, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n", user, g, N); - if (! - (gNid = - SRP_create_verifier(user, password, &salt, srp_verifier, N, - g))) { + if (!(gNid = SRP_create_verifier(user, password, &salt, + srp_verifier, N, g))) { BIO_printf(bio, "Internal error creating SRP verifier\n"); - } else + } else { *srp_usersalt = salt; + } + OPENSSL_cleanse(password, len); VVERBOSE BIO_printf(bio, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid, salt, *srp_verifier); @@ -314,9 +321,9 @@ int MAIN(int argc, char **argv) argc--; argv++; while (argc >= 1 && badops == 0) { - if (strcmp(*argv, "-verbose") == 0) + if (strcmp(*argv, "-verbose") == 0) { verbose++; - else if (strcmp(*argv, "-config") == 0) { + } else if (strcmp(*argv, "-config") == 0) { if (--argc < 1) goto bad; configfile = *(++argv); @@ -328,15 +335,15 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; dbfile = *(++argv); - } else if (strcmp(*argv, "-add") == 0) + } else if (strcmp(*argv, "-add") == 0) { add_user = 1; - else if (strcmp(*argv, "-delete") == 0) + } else if (strcmp(*argv, "-delete") == 0) { delete_user = 1; - else if (strcmp(*argv, "-modify") == 0) + } else if (strcmp(*argv, "-modify") == 0) { modify_user = 1; - else if (strcmp(*argv, "-list") == 0) + } else if (strcmp(*argv, "-list") == 0) { list_user = 1; - else if (strcmp(*argv, "-gn") == 0) { + } else if (strcmp(*argv, "-gn") == 0) { if (--argc < 1) goto bad; gN = *(++argv); @@ -366,8 +373,9 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; - } else + } else { break; + } argc--; argv++; @@ -388,7 +396,7 @@ int MAIN(int argc, char **argv) "Need at least one user for options -add, -delete, -modify. \n"); badops = 1; } - if ((passin || passout) && argc != 1) { + if ((passargin || passargout) && argc != 1) { BIO_printf(bio_err, "-passin, -passout arguments only valid with one user.\n"); badops = 1; @@ -706,9 +714,9 @@ int MAIN(int argc, char **argv) doupdatedb = 1; } } - if (--argc > 0) + if (--argc > 0) { user = *(argv++); - else { + } else { user = NULL; list_user = 0; } diff --git a/deps/openssl/openssl/apps/tsget b/deps/openssl/openssl/apps/tsget index 0d54e9fc9a76fd..0fca99f4385a79 100644 --- a/deps/openssl/openssl/apps/tsget +++ b/deps/openssl/openssl/apps/tsget @@ -193,4 +193,3 @@ REQUEST: foreach (@ARGV) { STDERR->printflush(", $output written.\n") if $options{v}; } $curl->cleanup(); -WWW::Curl::Easy::global_cleanup(); diff --git a/deps/openssl/openssl/crypto/LPdir_win.c b/deps/openssl/openssl/crypto/LPdir_win.c index 07e63fb4244ee8..4961254d9a3192 100644 --- a/deps/openssl/openssl/crypto/LPdir_win.c +++ b/deps/openssl/openssl/crypto/LPdir_win.c @@ -94,8 +94,23 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) TCHAR *wdir = NULL; /* len_0 denotes string length *with* trailing 0 */ size_t index = 0, len_0 = strlen(extdir) + 1; - - wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR)); + size_t amount; + + /* + * Size check + * The reasoning is that absolutely worst case, each byte in + * extdir will take up one TCHAR each, so the maximum size in + * bytes that we can tolerate is MAX_PATH TCHARs... not counting + * the ending NUL. + */ + if ((len_0 - 1) > MAX_PATH * sizeof(TCHAR)) { + free(*ctx); + *ctx = NULL; + errno = EINVAL; + return 0; + } + amount = len_0 * sizeof(TCHAR); + wdir = (TCHAR *)malloc(amount); if (wdir == NULL) { if (extdirbuf != NULL) { free(extdirbuf); diff --git a/deps/openssl/openssl/crypto/asn1/Makefile b/deps/openssl/openssl/crypto/asn1/Makefile index 330fe81b740c55..fb3140c1d3024f 100644 --- a/deps/openssl/openssl/crypto/asn1/Makefile +++ b/deps/openssl/openssl/crypto/asn1/Makefile @@ -680,7 +680,7 @@ tasn_fre.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h tasn_fre.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h tasn_fre.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h tasn_fre.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -tasn_fre.o: ../../include/openssl/symhacks.h tasn_fre.c +tasn_fre.o: ../../include/openssl/symhacks.h asn1_int.h tasn_fre.c tasn_new.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h tasn_new.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h tasn_new.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h @@ -688,7 +688,7 @@ tasn_new.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h tasn_new.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h tasn_new.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h tasn_new.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -tasn_new.o: ../../include/openssl/symhacks.h tasn_new.c +tasn_new.o: ../../include/openssl/symhacks.h asn1_int.h tasn_new.c tasn_prn.o: ../../e_os.h ../../include/openssl/asn1.h tasn_prn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h tasn_prn.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h diff --git a/deps/openssl/openssl/crypto/asn1/a_bitstr.c b/deps/openssl/openssl/crypto/asn1/a_bitstr.c index c429342e03d42a..0c8bb144a099b4 100644 --- a/deps/openssl/openssl/crypto/asn1/a_bitstr.c +++ b/deps/openssl/openssl/crypto/asn1/a_bitstr.c @@ -56,6 +56,7 @@ * [including the GNU Public Licence.] */ +#include #include #include "cryptlib.h" #include @@ -136,6 +137,11 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, goto err; } + if (len > INT_MAX) { + i = ASN1_R_STRING_TOO_LONG; + goto err; + } + if ((a == NULL) || ((*a) == NULL)) { if ((ret = M_ASN1_BIT_STRING_new()) == NULL) return (NULL); diff --git a/deps/openssl/openssl/include/openssl/pem2.h b/deps/openssl/openssl/crypto/asn1/asn1_int.h similarity index 87% rename from deps/openssl/openssl/include/openssl/pem2.h rename to deps/openssl/openssl/crypto/asn1/asn1_int.h index 84897d5ec35b6a..c9fd8b12ae1731 100644 --- a/deps/openssl/openssl/include/openssl/pem2.h +++ b/deps/openssl/openssl/crypto/asn1/asn1_int.h @@ -1,5 +1,10 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,19 +57,7 @@ * */ -/* - * This header only exists to break a circular dependency between pem and err - * Ben 30 Jan 1999. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef HEADER_PEM_H -void ERR_load_PEM_strings(void); -#endif +/* Internal ASN1 template structures and functions: not for application use */ -#ifdef __cplusplus -} -#endif +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); diff --git a/deps/openssl/openssl/crypto/asn1/tasn_fre.c b/deps/openssl/openssl/crypto/asn1/tasn_fre.c index aeea4eff7ab84e..0cf7510ff038f6 100644 --- a/deps/openssl/openssl/crypto/asn1/tasn_fre.c +++ b/deps/openssl/openssl/crypto/asn1/tasn_fre.c @@ -61,9 +61,7 @@ #include #include #include - -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); +#include "asn1_int.h" /* Free up an ASN1 structure */ @@ -77,8 +75,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) asn1_item_combine_free(pval, it, 0); } -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; diff --git a/deps/openssl/openssl/crypto/asn1/tasn_new.c b/deps/openssl/openssl/crypto/asn1/tasn_new.c index 54f459d1ed9cbf..6ba90260dab3b9 100644 --- a/deps/openssl/openssl/crypto/asn1/tasn_new.c +++ b/deps/openssl/openssl/crypto/asn1/tasn_new.c @@ -63,6 +63,7 @@ #include #include #include +#include "asn1_int.h" static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); @@ -199,7 +200,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; memerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); memerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); #ifdef CRYPTO_MDEBUG @@ -209,7 +210,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; auxerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); auxerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); #ifdef CRYPTO_MDEBUG diff --git a/deps/openssl/openssl/crypto/asn1/x_name.c b/deps/openssl/openssl/crypto/asn1/x_name.c index 1fb7ad1cbf88af..aea0c2763c28fa 100644 --- a/deps/openssl/openssl/crypto/asn1/x_name.c +++ b/deps/openssl/openssl/crypto/asn1/x_name.c @@ -523,19 +523,11 @@ static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { - X509_NAME *in; - - if (!xn || !name) - return (0); - - if (*xn != name) { - in = X509_NAME_dup(name); - if (in != NULL) { - X509_NAME_free(*xn); - *xn = in; - } - } - return (*xn != NULL); + if ((name = X509_NAME_dup(name)) == NULL) + return 0; + X509_NAME_free(*xn); + *xn = name; + return 1; } IMPLEMENT_STACK_OF(X509_NAME_ENTRY) diff --git a/deps/openssl/openssl/crypto/asn1/x_pkey.c b/deps/openssl/openssl/crypto/asn1/x_pkey.c index 2da23e4756b4eb..59f85539284010 100644 --- a/deps/openssl/openssl/crypto/asn1/x_pkey.c +++ b/deps/openssl/openssl/crypto/asn1/x_pkey.c @@ -106,10 +106,14 @@ X509_PKEY *X509_PKEY_new(void) X509_PKEY *ret = NULL; ASN1_CTX c; - M_ASN1_New_Malloc(ret, X509_PKEY); + ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + c.line = __LINE__; + goto err; + } ret->version = 0; - M_ASN1_New(ret->enc_algor, X509_ALGOR_new); - M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new); + ret->enc_algor = X509_ALGOR_new(); + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); ret->dec_pkey = NULL; ret->key_length = 0; ret->key_data = NULL; @@ -117,8 +121,15 @@ X509_PKEY *X509_PKEY_new(void) ret->cipher.cipher = NULL; memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); ret->references = 1; - return (ret); - M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW); + if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { + c.line = __LINE__; + goto err; + } + return ret; +err: + X509_PKEY_free(ret); + ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE, c.line); + return NULL; } void X509_PKEY_free(X509_PKEY *x) diff --git a/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl index 3bb0cdf5bd391a..42178e455a981d 100755 --- a/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl +++ b/deps/openssl/openssl/crypto/bn/asm/x86_64-mont5.pl @@ -3090,11 +3090,19 @@ .align 32 .Lsqrx8x_break: - sub 16+8(%rsp),%r8 # consume last carry + xor $zero,$zero + sub 16+8(%rsp),%rbx # mov 16(%rsp),%cf + adcx $zero,%r8 mov 24+8(%rsp),$carry # initial $tptr, borrow $carry + adcx $zero,%r9 mov 0*8($aptr),%rdx # a[8], modulo-scheduled - xor %ebp,%ebp # xor $zero,$zero + adc \$0,%r10 mov %r8,0*8($tptr) + adc \$0,%r11 + adc \$0,%r12 + adc \$0,%r13 + adc \$0,%r14 + adc \$0,%r15 cmp $carry,$tptr # cf=0, of=0 je .Lsqrx8x_outer_loop diff --git a/deps/openssl/openssl/crypto/bn/bn_exp.c b/deps/openssl/openssl/crypto/bn/bn_exp.c index 195a7867a46bff..35facd213a253d 100644 --- a/deps/openssl/openssl/crypto/bn/bn_exp.c +++ b/deps/openssl/openssl/crypto/bn/bn_exp.c @@ -145,7 +145,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int i, bits, ret = 0; BIGNUM *v, *rr; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -245,7 +246,9 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { # ifdef MONT_EXP_WORD if (a->top == 1 && !a->neg - && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { BN_ULONG A = a->d[0]; ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); } else @@ -277,7 +280,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -411,7 +416,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_MONT_CTX *mont = NULL; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); } @@ -1217,7 +1224,8 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -1348,7 +1356,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* Table of variables obtained from 'ctx' */ BIGNUM *val[TABLE_SIZE]; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; diff --git a/deps/openssl/openssl/crypto/bn/bn_lib.c b/deps/openssl/openssl/crypto/bn/bn_lib.c index 10b78f5126076f..f9c65f9f948a91 100644 --- a/deps/openssl/openssl/crypto/bn/bn_lib.c +++ b/deps/openssl/openssl/crypto/bn/bn_lib.c @@ -524,6 +524,9 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); #endif + if (BN_get_flags(b, BN_FLG_CONSTTIME) != 0) + BN_set_flags(a, BN_FLG_CONSTTIME); + a->top = b->top; a->neg = b->neg; bn_check_top(a); diff --git a/deps/openssl/openssl/crypto/bn/bn_mont.c b/deps/openssl/openssl/crypto/bn/bn_mont.c index be95bd55d02064..3af9db870bcbe6 100644 --- a/deps/openssl/openssl/crypto/bn/bn_mont.c +++ b/deps/openssl/openssl/crypto/bn/bn_mont.c @@ -394,6 +394,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) tmod.dmax = 2; tmod.neg = 0; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(&tmod, BN_FLG_CONSTTIME); + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) diff --git a/deps/openssl/openssl/crypto/bn/bn_mul.c b/deps/openssl/openssl/crypto/bn/bn_mul.c index 3c618dc3070890..6b455a755f714b 100644 --- a/deps/openssl/openssl/crypto/bn/bn_mul.c +++ b/deps/openssl/openssl/crypto/bn/bn_mul.c @@ -1032,46 +1032,6 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) rr->top = top; goto end; } -# if 0 - if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)b; - if (bn_wexpand(tmp_bn, al) == NULL) - goto err; - tmp_bn->d[bl] = 0; - bl++; - i--; - } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)a; - if (bn_wexpand(tmp_bn, bl) == NULL) - goto err; - tmp_bn->d[al] = 0; - al++; - i++; - } - if (i == 0) { - /* symmetric and > 4 */ - /* 16 or larger */ - j = BN_num_bits_word((BN_ULONG)al); - j = 1 << (j - 1); - k = j + j; - t = BN_CTX_get(ctx); - if (al == j) { /* exact multiple */ - if (bn_wexpand(t, k * 2) == NULL) - goto err; - if (bn_wexpand(rr, k * 2) == NULL) - goto err; - bn_mul_recursive(rr->d, a->d, b->d, al, t->d); - } else { - if (bn_wexpand(t, k * 4) == NULL) - goto err; - if (bn_wexpand(rr, k * 4) == NULL) - goto err; - bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); - } - rr->top = top; - goto end; - } -# endif } #endif /* BN_RECURSION */ if (bn_wexpand(rr, top) == NULL) diff --git a/deps/openssl/openssl/crypto/bn/bn_x931p.c b/deps/openssl/openssl/crypto/bn/bn_x931p.c index efa48bdf87724a..f444af3feabd91 100644 --- a/deps/openssl/openssl/crypto/bn/bn_x931p.c +++ b/deps/openssl/openssl/crypto/bn/bn_x931p.c @@ -217,6 +217,8 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) BN_CTX_start(ctx); t = BN_CTX_get(ctx); + if (t == NULL) + goto err; for (i = 0; i < 1000; i++) { if (!BN_rand(Xq, nbits, 1, 0)) @@ -255,10 +257,12 @@ int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, int ret = 0; BN_CTX_start(ctx); - if (!Xp1) + if (Xp1 == NULL) Xp1 = BN_CTX_get(ctx); - if (!Xp2) + if (Xp2 == NULL) Xp2 = BN_CTX_get(ctx); + if (Xp1 == NULL || Xp2 == NULL) + goto error; if (!BN_rand(Xp1, 101, 0, 0)) goto error; diff --git a/deps/openssl/openssl/crypto/cryptlib.c b/deps/openssl/openssl/crypto/cryptlib.c index 1925428f5ec532..5fab45b2ec85be 100644 --- a/deps/openssl/openssl/crypto/cryptlib.c +++ b/deps/openssl/openssl/crypto/cryptlib.c @@ -469,11 +469,18 @@ void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) } } +#ifdef OPENSSL_FIPS +extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *)); +#endif + int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) { if (threadid_callback) return 0; threadid_callback = func; +#ifdef OPENSSL_FIPS + FIPS_crypto_threadid_set_callback(func); +#endif return 1; } diff --git a/deps/openssl/openssl/crypto/dh/Makefile b/deps/openssl/openssl/crypto/dh/Makefile index 46fa5ac57b4747..cc366ec6fa38be 100644 --- a/deps/openssl/openssl/crypto/dh/Makefile +++ b/deps/openssl/openssl/crypto/dh/Makefile @@ -134,7 +134,7 @@ dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h dh_gen.o: ../cryptlib.h dh_gen.c -dh_kdf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +dh_kdf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h dh_kdf.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h dh_kdf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h dh_kdf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h diff --git a/deps/openssl/openssl/crypto/dh/dh.h b/deps/openssl/openssl/crypto/dh/dh.h index a228c7a7a4c3a1..80b28fb39dc82d 100644 --- a/deps/openssl/openssl/crypto/dh/dh.h +++ b/deps/openssl/openssl/crypto/dh/dh.h @@ -257,11 +257,13 @@ DH *DH_get_1024_160(void); DH *DH_get_2048_224(void); DH *DH_get_2048_256(void); +# ifndef OPENSSL_NO_CMS /* RFC2631 KDF */ int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif # define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ diff --git a/deps/openssl/openssl/crypto/dh/dh_kdf.c b/deps/openssl/openssl/crypto/dh/dh_kdf.c index a882cb286e0eae..8947a087315202 100644 --- a/deps/openssl/openssl/crypto/dh/dh_kdf.c +++ b/deps/openssl/openssl/crypto/dh/dh_kdf.c @@ -51,6 +51,9 @@ * ==================================================================== */ +#include + +#ifndef OPENSSL_NO_CMS #include #include #include @@ -185,3 +188,4 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, EVP_MD_CTX_cleanup(&mctx); return rv; } +#endif diff --git a/deps/openssl/openssl/crypto/dh/dh_pmeth.c b/deps/openssl/openssl/crypto/dh/dh_pmeth.c index b58e3fa86fad0c..6452482c87d2f9 100644 --- a/deps/openssl/openssl/crypto/dh/dh_pmeth.c +++ b/deps/openssl/openssl/crypto/dh/dh_pmeth.c @@ -207,7 +207,11 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; +#ifdef OPENSSL_NO_CMS + if (p1 != EVP_PKEY_DH_KDF_NONE) +#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) +#endif return -2; dctx->kdf_type = p1; return 1; @@ -448,7 +452,9 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, return ret; *keylen = ret; return 1; - } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { + } +#ifndef OPENSSL_NO_CMS + else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; size_t Zlen = 0; if (!dctx->kdf_outlen || !dctx->kdf_oid) @@ -479,6 +485,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, } return ret; } +#endif return 1; } diff --git a/deps/openssl/openssl/crypto/dsa/dsa_ameth.c b/deps/openssl/openssl/crypto/dsa/dsa_ameth.c index c4fa105747feb7..aac253095141a3 100644 --- a/deps/openssl/openssl/crypto/dsa/dsa_ameth.c +++ b/deps/openssl/openssl/crypto/dsa/dsa_ameth.c @@ -258,6 +258,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) goto dsaerr; } + BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); goto dsaerr; diff --git a/deps/openssl/openssl/crypto/dsa/dsa_gen.c b/deps/openssl/openssl/crypto/dsa/dsa_gen.c index 1fce0f81c24242..21af2e159fb26a 100644 --- a/deps/openssl/openssl/crypto/dsa/dsa_gen.c +++ b/deps/openssl/openssl/crypto/dsa/dsa_gen.c @@ -482,6 +482,8 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, } else { p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); + if (q == NULL) + goto err; } if (!BN_lshift(test, BN_value_one(), L - 1)) diff --git a/deps/openssl/openssl/crypto/dsa/dsa_ossl.c b/deps/openssl/openssl/crypto/dsa/dsa_ossl.c index 58013a4a13b57a..aa10dd12f6f8c5 100644 --- a/deps/openssl/openssl/crypto/dsa/dsa_ossl.c +++ b/deps/openssl/openssl/crypto/dsa/dsa_ossl.c @@ -224,7 +224,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, { BN_CTX *ctx; BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; + BIGNUM l, m; int ret = 0; + int q_bits; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); @@ -233,6 +235,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_init(&k); BN_init(&kq); + BN_init(&l); + BN_init(&m); if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) @@ -243,6 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if ((r = BN_new()) == NULL) goto err; + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q); + if (!BN_set_bit(&k, q_bits) + || !BN_set_bit(&l, q_bits) + || !BN_set_bit(&m, q_bits)) + goto err; + /* Get random k */ do if (!BN_rand_range(&k, dsa->q)) @@ -263,24 +274,23 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, /* Compute r = (g^k mod p) mod q */ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - if (!BN_copy(&kq, &k)) - goto err; - - BN_set_flags(&kq, BN_FLG_CONSTTIME); - /* * We do not want timing information to leak the length of k, so we - * compute g^k using an equivalent exponent of fixed length. (This - * is a kludge that we need because the BN_mod_exp_mont() does not - * let us specify the desired timing behaviour.) + * compute G^k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(&kq, &kq, dsa->q)) + if (!BN_add(&l, &k, dsa->q) + || !BN_add(&m, &l, dsa->q) + || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) goto err; - if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { - if (!BN_add(&kq, &kq, dsa->q)) - goto err; - } + + BN_set_flags(&kq, BN_FLG_CONSTTIME); K = &kq; } else { @@ -314,7 +324,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_CTX_free(ctx); BN_clear_free(&k); BN_clear_free(&kq); - return (ret); + BN_clear_free(&l); + BN_clear_free(&m); + return ret; } static int dsa_do_verify(const unsigned char *dgst, int dgst_len, diff --git a/deps/openssl/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl b/deps/openssl/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl index 7948bf71b51e2c..35d2b6d146c1a1 100755 --- a/deps/openssl/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/deps/openssl/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -1178,19 +1178,18 @@ adox $t1, $acc5 .byte 0x67,0x67 mulx %rdx, $t0, $t4 - mov $acc0, %rdx + mov .Lpoly+8*3(%rip), %rdx adox $t0, $acc6 shlx $a_ptr, $acc0, $t0 adox $t4, $acc7 shrx $a_ptr, $acc0, $t4 - mov .Lpoly+8*3(%rip), $t1 + mov %rdx,$t1 # reduction step 1 add $t0, $acc1 adc $t4, $acc2 - mulx $t1, $t0, $acc0 - mov $acc1, %rdx + mulx $acc0, $t0, $acc0 adc $t0, $acc3 shlx $a_ptr, $acc1, $t0 adc \$0, $acc0 @@ -1200,8 +1199,7 @@ add $t0, $acc2 adc $t4, $acc3 - mulx $t1, $t0, $acc1 - mov $acc2, %rdx + mulx $acc1, $t0, $acc1 adc $t0, $acc0 shlx $a_ptr, $acc2, $t0 adc \$0, $acc1 @@ -1211,8 +1209,7 @@ add $t0, $acc3 adc $t4, $acc0 - mulx $t1, $t0, $acc2 - mov $acc3, %rdx + mulx $acc2, $t0, $acc2 adc $t0, $acc1 shlx $a_ptr, $acc3, $t0 adc \$0, $acc2 @@ -1222,12 +1219,12 @@ add $t0, $acc0 adc $t4, $acc1 - mulx $t1, $t0, $acc3 + mulx $acc3, $t0, $acc3 adc $t0, $acc2 adc \$0, $acc3 - xor $t3, $t3 # cf=0 - adc $acc0, $acc4 # accumulate upper half + xor $t3, $t3 + add $acc0, $acc4 # accumulate upper half mov .Lpoly+8*1(%rip), $a_ptr adc $acc1, $acc5 mov $acc4, $acc0 @@ -1236,8 +1233,7 @@ mov $acc5, $acc1 adc \$0, $t3 - xor %eax, %eax # cf=0 - sbb \$-1, $acc4 # .Lpoly[0] + sub \$-1, $acc4 # .Lpoly[0] mov $acc6, $acc2 sbb $a_ptr, $acc5 # .Lpoly[1] sbb \$0, $acc6 # .Lpoly[2] diff --git a/deps/openssl/openssl/crypto/ec/ecp_mont.c b/deps/openssl/openssl/crypto/ec/ecp_mont.c index b2de7faea75e9d..43c4330cb0b7c8 100644 --- a/deps/openssl/openssl/crypto/ec/ecp_mont.c +++ b/deps/openssl/openssl/crypto/ec/ecp_mont.c @@ -247,6 +247,8 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX_free(new_ctx); if (mont != NULL) BN_MONT_CTX_free(mont); + if (one != NULL) + BN_free(one); return ret; } diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp224.c b/deps/openssl/openssl/crypto/ec/ecp_nistp224.c index d81cc9ce6b1a0d..fcd754e448816d 100644 --- a/deps/openssl/openssl/crypto/ec/ecp_nistp224.c +++ b/deps/openssl/openssl/crypto/ec/ecp_nistp224.c @@ -716,7 +716,7 @@ static limb felem_is_zero(const felem in) return (zero | two224m96p1 | two225m97p2); } -static limb felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1391,7 +1391,6 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp256.c b/deps/openssl/openssl/crypto/ec/ecp_nistp256.c index 78d191aac7afbb..1272966fff84ca 100644 --- a/deps/openssl/openssl/crypto/ec/ecp_nistp256.c +++ b/deps/openssl/openssl/crypto/ec/ecp_nistp256.c @@ -977,7 +977,7 @@ static limb smallfelem_is_zero(const smallfelem small) return result; } -static int smallfelem_is_zero_int(const smallfelem small) +static int smallfelem_is_zero_int(const void *small) { return (int)(smallfelem_is_zero(small) & ((limb) 1)); } @@ -1979,7 +1979,6 @@ static void make_points_affine(size_t num, smallfelem points[][3], sizeof(smallfelem), tmp_smallfelems, (void (*)(void *))smallfelem_one, - (int (*)(const void *)) smallfelem_is_zero_int, (void (*)(void *, const void *)) smallfelem_assign, diff --git a/deps/openssl/openssl/crypto/ec/ecp_nistp521.c b/deps/openssl/openssl/crypto/ec/ecp_nistp521.c index c53a61bbfb697d..a1dc9946fd17c8 100644 --- a/deps/openssl/openssl/crypto/ec/ecp_nistp521.c +++ b/deps/openssl/openssl/crypto/ec/ecp_nistp521.c @@ -871,7 +871,7 @@ static limb felem_is_zero(const felem in) return is_zero; } -static int felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1787,7 +1787,6 @@ static void make_points_affine(size_t num, felem points[][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/deps/openssl/openssl/crypto/ecdh/ech_lib.c b/deps/openssl/openssl/crypto/ecdh/ech_lib.c index cbc21d1a276ef4..9cc22582e4ad89 100644 --- a/deps/openssl/openssl/crypto/ecdh/ech_lib.c +++ b/deps/openssl/openssl/crypto/ecdh/ech_lib.c @@ -225,9 +225,16 @@ ECDH_DATA *ecdh_check(EC_KEY *key) */ ecdh_data_free(ecdh_data); ecdh_data = (ECDH_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, + ecdh_data_free) != ecdh_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdh_data_free(ecdh_data); + return NULL; } - } else + } else { ecdh_data = (ECDH_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c b/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c index 8dc1dda462598a..f1dd47231793dc 100644 --- a/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c +++ b/deps/openssl/openssl/crypto/ecdsa/ecs_lib.c @@ -203,9 +203,16 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key) */ ecdsa_data_free(ecdsa_data); ecdsa_data = (ECDSA_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, + ecdsa_data_free) != ecdsa_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdsa_data_free(ecdsa_data); + return NULL; } - } else + } else { ecdsa_data = (ECDSA_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c b/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c index dd769609be4c08..16d4f59b9ba97c 100644 --- a/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c +++ b/deps/openssl/openssl/crypto/ecdsa/ecs_ossl.c @@ -95,6 +95,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; + int order_bits; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); @@ -126,6 +127,13 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, goto err; } + /* Preallocate space */ + order_bits = BN_num_bits(order); + if (!BN_set_bit(k, order_bits) + || !BN_set_bit(r, order_bits) + || !BN_set_bit(X, order_bits)) + goto err; + do { /* get random k */ do @@ -139,13 +147,19 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, /* * We do not want timing information to leak the length of k, so we * compute G*k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the order. This guarantees the code + * path used in the constant time implementations elsewhere. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(k, k, order)) + if (!BN_add(r, k, order) + || !BN_add(X, r, order) + || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) goto err; - if (BN_num_bits(k) <= BN_num_bits(order)) - if (!BN_add(k, k, order)) - goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { diff --git a/deps/openssl/openssl/crypto/err/err.c b/deps/openssl/openssl/crypto/err/err.c index 0b1fcfc1f1a5de..cfe0e8083f39ba 100644 --- a/deps/openssl/openssl/crypto/err/err.c +++ b/deps/openssl/openssl/crypto/err/err.c @@ -725,6 +725,8 @@ void ERR_put_error(int lib, int func, int reason, const char *file, int line) } #endif es = ERR_get_state(); + if (es == NULL) + return; es->top = (es->top + 1) % ERR_NUM_ERRORS; if (es->top == es->bottom) @@ -742,6 +744,8 @@ void ERR_clear_error(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return; for (i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(es, i); @@ -806,6 +810,8 @@ static unsigned long get_error_values(int inc, int top, const char **file, unsigned long ret; es = ERR_get_state(); + if (es == NULL) + return 0; if (inc && top) { if (file) @@ -1016,7 +1022,6 @@ void ERR_remove_state(unsigned long pid) ERR_STATE *ERR_get_state(void) { - static ERR_STATE fallback; ERR_STATE *ret, tmp, *tmpp = NULL; int i; CRYPTO_THREADID tid; @@ -1030,7 +1035,7 @@ ERR_STATE *ERR_get_state(void) if (ret == NULL) { ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); if (ret == NULL) - return (&fallback); + return NULL; CRYPTO_THREADID_cpy(&ret->tid, &tid); ret->top = 0; ret->bottom = 0; @@ -1042,7 +1047,7 @@ ERR_STATE *ERR_get_state(void) /* To check if insertion failed, do a get. */ if (ERRFN(thread_get_item) (ret) != ret) { ERR_STATE_free(ret); /* could not insert it */ - return (&fallback); + return NULL; } /* * If a race occured in this function and we came second, tmpp is the @@ -1066,10 +1071,10 @@ void ERR_set_error_data(char *data, int flags) int i; es = ERR_get_state(); + if (es == NULL) + return; i = es->top; - if (i == 0) - i = ERR_NUM_ERRORS - 1; err_clear_data(es, i); es->err_data[i] = data; @@ -1121,6 +1126,8 @@ int ERR_set_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; if (es->bottom == es->top) return 0; @@ -1133,6 +1140,8 @@ int ERR_pop_to_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; while (es->bottom != es->top && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { diff --git a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c index d114710e98ec4e..b25fc6d541d420 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -579,12 +579,17 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c index 917ae0751dee3f..9a8a2ad7787ca3 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -507,10 +507,12 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, * to identify it and avoid stitch invocation. So that after we * establish that current CPU supports AVX, we even see if it's * either even XOP-capable Bulldozer-based or GenuineIntel one. + * But SHAEXT-capable go ahead... */ - if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */ - ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ - | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */ + if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */ + ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */ + ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ + | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */ plen > (sha_off + iv) && (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) { SHA256_Update(&key->md, in + iv, sha_off); @@ -590,12 +592,17 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/deps/openssl/openssl/crypto/evp/evp.h b/deps/openssl/openssl/crypto/evp/evp.h index d258ef870a3604..cf1de15e6d03ce 100644 --- a/deps/openssl/openssl/crypto/evp/evp.h +++ b/deps/openssl/openssl/crypto/evp/evp.h @@ -1363,6 +1363,98 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, const char *type, const char *value)); +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + void EVP_add_alg_module(void); /* BEGIN ERROR CODES */ diff --git a/deps/openssl/openssl/crypto/evp/evp_key.c b/deps/openssl/openssl/crypto/evp/evp_key.c index 5be9e336f9e717..cdffe1c8c428e8 100644 --- a/deps/openssl/openssl/crypto/evp/evp_key.c +++ b/deps/openssl/openssl/crypto/evp/evp_key.c @@ -97,7 +97,7 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify) { - int ret; + int ret = -1; char buff[BUFSIZ]; UI *ui; @@ -105,16 +105,18 @@ int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, prompt = prompt_string; ui = UI_new(); if (ui == NULL) - return -1; - UI_add_input_string(ui, prompt, 0, buf, min, - (len >= BUFSIZ) ? BUFSIZ - 1 : len); - if (verify) - UI_add_verify_string(ui, prompt, 0, - buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len, - buf); + return ret; + if (UI_add_input_string(ui, prompt, 0, buf, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 + || (verify + && UI_add_verify_string(ui, prompt, 0, buff, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len, + buf) < 0)) + goto end; ret = UI_process(ui); - UI_free(ui); OPENSSL_cleanse(buff, BUFSIZ); + end: + UI_free(ui); return ret; } diff --git a/deps/openssl/openssl/crypto/evp/pmeth_lib.c b/deps/openssl/openssl/crypto/evp/pmeth_lib.c index b7b7bdcd0290e6..e50826b568d884 100644 --- a/deps/openssl/openssl/crypto/evp/pmeth_lib.c +++ b/deps/openssl/openssl/crypto/evp/pmeth_lib.c @@ -589,3 +589,170 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl = ctrl; pmeth->ctrl_str = ctrl_str; } + +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)) +{ + *pinit = pmeth->init; +} + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + *pcopy = pmeth->copy; +} + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)) +{ + *pcleanup = pmeth->cleanup; +} + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pparamgen_init) + *pparamgen_init = pmeth->paramgen_init; + if (pparamgen) + *pparamgen = pmeth->paramgen; +} + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pkeygen_init) + *pkeygen_init = pmeth->keygen_init; + if (pkeygen) + *pkeygen = pmeth->keygen; +} + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (psign_init) + *psign_init = pmeth->sign_init; + if (psign) + *psign = pmeth->sign; +} + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (pverify_init) + *pverify_init = pmeth->verify_init; + if (pverify) + *pverify = pmeth->verify; +} + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + if (pverify_recover_init) + *pverify_recover_init = pmeth->verify_recover_init; + if (pverify_recover) + *pverify_recover = pmeth->verify_recover; +} + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + if (psignctx_init) + *psignctx_init = pmeth->signctx_init; + if (psignctx) + *psignctx = pmeth->signctx; +} + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + if (pverifyctx_init) + *pverifyctx_init = pmeth->verifyctx_init; + if (pverifyctx) + *pverifyctx = pmeth->verifyctx; +} + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pencrypt_init) + *pencrypt_init = pmeth->encrypt_init; + if (pencryptfn) + *pencryptfn = pmeth->encrypt; +} + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pdecrypt_init) + *pdecrypt_init = pmeth->decrypt_init; + if (pdecrypt) + *pdecrypt = pmeth->decrypt; +} + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + if (pderive_init) + *pderive_init = pmeth->derive_init; + if (pderive) + *pderive = pmeth->derive; +} + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + if (pctrl) + *pctrl = pmeth->ctrl; + if (pctrl_str) + *pctrl_str = pmeth->ctrl_str; +} diff --git a/deps/openssl/openssl/crypto/ex_data.c b/deps/openssl/openssl/crypto/ex_data.c index 108a1959eacfc2..723b21b3d28181 100644 --- a/deps/openssl/openssl/crypto/ex_data.c +++ b/deps/openssl/openssl/crypto/ex_data.c @@ -473,7 +473,14 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (j < mx) mx = j; if (mx > 0) { - if (!CRYPTO_set_ex_data(to, mx - 1, NULL)) + /* + * Make sure the ex_data stack is at least |mx| elements long to avoid + * issues in the for loop that follows; so go get the |mx|'th element + * (if it does not exist CRYPTO_get_ex_data() returns NULL), and assign + * to itself. This is normally a no-op; but ensures the stack is the + * proper size + */ + if (!CRYPTO_set_ex_data(to, mx - 1, CRYPTO_get_ex_data(to, mx - 1))) goto skip; storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); if (!storage) diff --git a/deps/openssl/openssl/crypto/include/internal/bn_conf.h b/deps/openssl/openssl/crypto/include/internal/bn_conf.h deleted file mode 100644 index 34bd8b78b4f90f..00000000000000 --- a/deps/openssl/openssl/crypto/include/internal/bn_conf.h +++ /dev/null @@ -1,28 +0,0 @@ -/* WARNING: do not edit! */ -/* Generated by Makefile from crypto/include/internal/bn_conf.h.in */ -/* - * Copyright 2016 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef HEADER_BN_CONF_H -# define HEADER_BN_CONF_H - -/* - * The contents of this file are not used in the UEFI build, as - * both 32-bit and 64-bit builds are supported from a single run - * of the Configure script. - */ - -/* Should we define BN_DIV2W here? */ - -/* Only one for the following should be defined */ -#define SIXTY_FOUR_BIT_LONG -#undef SIXTY_FOUR_BIT -#undef THIRTY_TWO_BIT - -#endif diff --git a/deps/openssl/openssl/crypto/include/internal/dso_conf.h b/deps/openssl/openssl/crypto/include/internal/dso_conf.h deleted file mode 100644 index 7a52dd1f1a1159..00000000000000 --- a/deps/openssl/openssl/crypto/include/internal/dso_conf.h +++ /dev/null @@ -1,16 +0,0 @@ -/* WARNING: do not edit! */ -/* Generated by Makefile from crypto/include/internal/dso_conf.h.in */ -/* - * Copyright 2016 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef HEADER_DSO_CONF_H -# define HEADER_DSO_CONF_H - -# define DSO_EXTENSION ".so" -#endif diff --git a/deps/openssl/openssl/crypto/lhash/lhash.c b/deps/openssl/openssl/crypto/lhash/lhash.c index f20353aea33f4f..f3798872598a44 100644 --- a/deps/openssl/openssl/crypto/lhash/lhash.c +++ b/deps/openssl/openssl/crypto/lhash/lhash.c @@ -101,6 +101,24 @@ #include #include +/* + * A hashing implementation that appears to be based on the linear hashing + * alogrithm: + * https://en.wikipedia.org/wiki/Linear_hashing + * + * Litwin, Witold (1980), "Linear hashing: A new tool for file and table + * addressing", Proc. 6th Conference on Very Large Databases: 212–223 + * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf + * + * From the wikipedia article "Linear hashing is used in the BDB Berkeley + * database system, which in turn is used by many software systems such as + * OpenLDAP, using a C implementation derived from the CACM article and first + * published on the Usenet in 1988 by Esmond Pitt." + * + * The CACM paper is available here: + * https://pdfs.semanticscholar.org/ff4d/1c5deca6269cc316bfd952172284dbf610ee.pdf + */ + const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #undef MIN_NODES @@ -108,7 +126,7 @@ const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ -static void expand(_LHASH *lh); +static int expand(_LHASH *lh); static void contract(_LHASH *lh); static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); @@ -182,8 +200,9 @@ void *lh_insert(_LHASH *lh, void *data) void *ret; lh->error = 0; - if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) - expand(lh); + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes) + && !expand(lh)) + return NULL; rn = getrn(lh, data, &hash); @@ -300,19 +319,37 @@ void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); } -static void expand(_LHASH *lh) +static int expand(_LHASH *lh) { LHASH_NODE **n, **n1, **n2, *np; - unsigned int p, i, j; - unsigned long hash, nni; + unsigned int p, pmax, nni, j; + unsigned long hash; + + nni = lh->num_alloc_nodes; + p = lh->p; + pmax = lh->pmax; + if (p + 1 >= pmax) { + j = nni * 2; + n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); + if (n == NULL) { + lh->error++; + return 0; + } + lh->b = n; + memset(n + nni, 0, sizeof(*n) * (j - nni)); + lh->pmax = nni; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + } else { + lh->p++; + } lh->num_nodes++; lh->num_expands++; - p = (int)lh->p++; n1 = &(lh->b[p]); - n2 = &(lh->b[p + (int)lh->pmax]); - *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ - nni = lh->num_alloc_nodes; + n2 = &(lh->b[p + pmax]); + *n2 = NULL; for (np = *n1; np != NULL;) { #ifndef OPENSSL_NO_HASH_COMP @@ -330,25 +367,7 @@ static void expand(_LHASH *lh) np = *n1; } - if ((lh->p) >= lh->pmax) { - j = (int)lh->num_alloc_nodes * 2; - n = (LHASH_NODE **)OPENSSL_realloc(lh->b, - (int)(sizeof(LHASH_NODE *) * j)); - if (n == NULL) { - lh->error++; - lh->num_nodes--; - lh->p = 0; - return; - } - /* else */ - for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */ - n[i] = NULL; /* 02/03/92 eay */ - lh->pmax = lh->num_alloc_nodes; - lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; - lh->p = 0; - lh->b = n; - } + return 1; } static void contract(_LHASH *lh) diff --git a/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c b/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c index d4a257c33bb593..7a7d06094edfe4 100644 --- a/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c +++ b/deps/openssl/openssl/crypto/ocsp/ocsp_vfy.c @@ -118,6 +118,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, goto end; } } + } else if (certs != NULL) { + untrusted = certs; } else { untrusted = bs->certs; } diff --git a/deps/openssl/openssl/crypto/opensslconf.h b/deps/openssl/openssl/crypto/opensslconf.h index 76c99d433ab886..f533508b152c29 100644 --- a/deps/openssl/openssl/crypto/opensslconf.h +++ b/deps/openssl/openssl/crypto/opensslconf.h @@ -1 +1,265 @@ -#include "../../config/opensslconf.h" +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_LIBUNBOUND +# define OPENSSL_NO_LIBUNBOUND +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) +# define NO_LIBUNBOUND +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# define NO_RFC3779 +# endif +# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP) +# define NO_SCTP +# endif +# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE) +# define NO_SSL_TRACE +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/usr/local/ssl/lib/engines" +#define OPENSSLDIR "/usr/local/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/deps/openssl/openssl/crypto/opensslv.h b/deps/openssl/openssl/crypto/opensslv.h index 825a330abc8825..c944d562dae0a9 100644 --- a/deps/openssl/openssl/crypto/opensslv.h +++ b/deps/openssl/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ 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 0x100020cfL +# define OPENSSL_VERSION_NUMBER 0x100020dfL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-fips 2 Nov 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m 2 Nov 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/deps/openssl/openssl/crypto/pem/pem_lib.c b/deps/openssl/openssl/crypto/pem/pem_lib.c index c82b3c0ae263d0..865976bf8cce9a 100644 --- a/deps/openssl/openssl/crypto/pem/pem_lib.c +++ b/deps/openssl/openssl/crypto/pem/pem_lib.c @@ -536,7 +536,8 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) ((c >= '0') && (c <= '9')))) break; #else - if (!(isupper(c) || (c == '-') || isdigit(c))) + if (!(isupper((unsigned char)c) || (c == '-') + || isdigit((unsigned char)c))) break; #endif header++; diff --git a/deps/openssl/openssl/crypto/pem/pem_pk8.c b/deps/openssl/openssl/crypto/pem/pem_pk8.c index 5747c7366e3d0a..daf210fde0f946 100644 --- a/deps/openssl/openssl/crypto/pem/pem_pk8.c +++ b/deps/openssl/openssl/crypto/pem/pem_pk8.c @@ -178,6 +178,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) return NULL; ret = EVP_PKCS82PKEY(p8inf); diff --git a/deps/openssl/openssl/crypto/pem/pem_pkey.c b/deps/openssl/openssl/crypto/pem/pem_pkey.c index 04d6319a225be0..e8b3a1b92c8d51 100644 --- a/deps/openssl/openssl/crypto/pem/pem_pkey.c +++ b/deps/openssl/openssl/crypto/pem/pem_pkey.c @@ -120,6 +120,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); diff --git a/deps/openssl/openssl/crypto/perlasm/x86masm.pl b/deps/openssl/openssl/crypto/perlasm/x86masm.pl index b7f49d1c41dc16..1741342c3af354 100644 --- a/deps/openssl/openssl/crypto/perlasm/x86masm.pl +++ b/deps/openssl/openssl/crypto/perlasm/x86masm.pl @@ -18,10 +18,10 @@ sub ::generic if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+(\(.*\))$/OFFSET $1/) # no [] { $opcode="mov"; } - elsif ($opcode !~ /mov[dq]$/) + elsif ($opcode !~ /movq/) { # fix xmm references - $arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[-1]=~/\bxmm[0-7]\b/i); - $arg[-1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i); + $arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i); + $arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i); } &::emit($opcode,@arg); @@ -82,7 +82,7 @@ sub ::file IF \@Version LT 800 ECHO MASM version 8.00 or later is strongly recommended. ENDIF -.686 +.486 .MODEL FLAT OPTION DOTNAME IF \@Version LT 800 @@ -160,13 +160,13 @@ sub ::public_label { push(@out,"PUBLIC\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); } sub ::data_byte -{ push(@out,("DB\t").join(',',splice(@_,0,16))."\n") while(@_); } +{ push(@out,("DB\t").join(',',@_)."\n"); } sub ::data_short -{ push(@out,("DW\t").join(',',splice(@_,0,8))."\n") while(@_); } +{ push(@out,("DW\t").join(',',@_)."\n"); } sub ::data_word -{ push(@out,("DD\t").join(',',splice(@_,0,4))."\n") while(@_); } +{ push(@out,("DD\t").join(',',@_)."\n"); } sub ::align { push(@out,"ALIGN\t$_[0]\n"); } diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c b/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c index 9aa3c90c4e5726..1841f78f691500 100644 --- a/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c +++ b/deps/openssl/openssl/crypto/pkcs12/p12_kiss.c @@ -84,6 +84,12 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, { STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; + + if (pkey) + *pkey = NULL; + if (cert) + *cert = NULL; + /* Check for NULL PKCS12 structure */ if (!p12) { @@ -92,11 +98,6 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, return 0; } - if (pkey) - *pkey = NULL; - if (cert) - *cert = NULL; - /* Check the mac */ /* @@ -125,7 +126,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, if (!ocerts) { PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { @@ -163,10 +164,14 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, err: - if (pkey && *pkey) + if (pkey) { EVP_PKEY_free(*pkey); - if (cert && *cert) + *pkey = NULL; + } + if (cert) { X509_free(*cert); + *cert = NULL; + } if (x) X509_free(x); if (ocerts) diff --git a/deps/openssl/openssl/crypto/rand/rand_win.c b/deps/openssl/openssl/crypto/rand/rand_win.c index 06670ae017ad84..b4be3097e9fabd 100644 --- a/deps/openssl/openssl/crypto/rand/rand_win.c +++ b/deps/openssl/openssl/crypto/rand/rand_win.c @@ -196,6 +196,8 @@ typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE); # endif /* 1 */ # endif /* !OPENSSL_SYS_WINCE */ +#define NOTTOOLONG(start) ((GetTickCount() - (start)) < MAXDELAY) + int RAND_poll(void) { MEMORYSTATUS m; @@ -466,9 +468,7 @@ int RAND_poll(void) do RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) - && (!good - || (GetTickCount() - starttime) < - MAXDELAY) + && (!good || NOTTOOLONG(starttime)) && --entrycnt > 0); } } @@ -480,8 +480,7 @@ int RAND_poll(void) ex_cnt_limit--; } } while (heaplist_next(handle, &hlist) - && (!good - || (GetTickCount() - starttime) < MAXDELAY) + && (!good || NOTTOOLONG(starttime)) && ex_cnt_limit > 0); } # else @@ -496,11 +495,11 @@ int RAND_poll(void) do RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) + && (!good || NOTTOOLONG(starttime)) && --entrycnt > 0); } } while (heaplist_next(handle, &hlist) - && (!good - || (GetTickCount() - starttime) < MAXDELAY)); + && (!good || NOTTOOLONG(starttime))); } # endif @@ -518,8 +517,7 @@ int RAND_poll(void) do RAND_add(&p, p.dwSize, 9); while (process_next(handle, &p) - && (!good - || (GetTickCount() - starttime) < MAXDELAY)); + && (!good || NOTTOOLONG(starttime))); /* thread walking */ /* @@ -533,8 +531,7 @@ int RAND_poll(void) do RAND_add(&t, t.dwSize, 6); while (thread_next(handle, &t) - && (!good - || (GetTickCount() - starttime) < MAXDELAY)); + && (!good || NOTTOOLONG(starttime))); /* module walking */ /* @@ -548,8 +545,7 @@ int RAND_poll(void) do RAND_add(&m, m.dwSize, 9); while (module_next(handle, &m) - && (!good - || (GetTickCount() - starttime) < MAXDELAY)); + && (!good || NOTTOOLONG(starttime))); if (close_snap) close_snap(handle); else @@ -708,14 +704,13 @@ static void readscreen(void) hBitmap = CreateCompatibleBitmap(hScrDC, w, n); /* Get bitmap properties */ - GetObject(hBitmap, sizeof(BITMAP), (LPSTR) & bm); - size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes; - - bi.biSize = sizeof(BITMAPINFOHEADER); + GetObject(hBitmap, sizeof(bm), (LPSTR)&bm); + size = (unsigned int)4 * bm.bmHeight * bm.bmWidth; + bi.biSize = sizeof(bi); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; - bi.biPlanes = bm.bmPlanes; - bi.biBitCount = bm.bmBitsPixel; + bi.biPlanes = 1; + bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; @@ -731,7 +726,7 @@ static void readscreen(void) /* Copy the bits of the current line range into the buffer */ GetDIBits(hScrDC, hBitmap, y, n, - bmbits, (BITMAPINFO *) & bi, DIB_RGB_COLORS); + bmbits, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); /* Get the hash of the bitmap */ MD(bmbits, size, md); diff --git a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c index 951e1d5ca32b98..ddead3d7445570 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c @@ -768,6 +768,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } +#ifndef OPENSSL_NO_CMS static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash) { @@ -791,7 +792,6 @@ static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, return pss; } -#ifndef OPENSSL_NO_CMS static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; diff --git a/deps/openssl/openssl/crypto/rsa/rsa_oaep.c b/deps/openssl/openssl/crypto/rsa/rsa_oaep.c index 19d28c6f0e6012..9a01b4afc11fb4 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_oaep.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_oaep.c @@ -237,10 +237,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR); cleanup: - if (db != NULL) + if (db != NULL) { + OPENSSL_cleanse(db, dblen); OPENSSL_free(db); - if (em != NULL) + } + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } return mlen; } diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pk1.c b/deps/openssl/openssl/crypto/rsa/rsa_pk1.c index efa1fd3e993f02..50397c335a5a56 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_pk1.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_pk1.c @@ -255,8 +255,6 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, * We can't continue in constant-time because we need to copy the result * and we cannot fake its length. This unavoidably leaks timing * information at the API boundary. - * TODO(emilia): this could be addressed at the call site, - * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. */ if (!good) { mlen = -1; @@ -266,8 +264,10 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, memcpy(to, em + msg_index, mlen); err: - if (em != NULL) + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } if (mlen == -1) RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c index 8896e2e977149b..00e730ffa95887 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c @@ -180,27 +180,25 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) * FIPS mode. */ -static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) +static int pkey_fips_check_rsa(const RSA *rsa, const EVP_MD **pmd, + const EVP_MD **pmgf1md) { - RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; int rv = -1; + if (!FIPS_mode()) return 0; if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) rv = 0; if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) return -1; - if (rctx->md) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmd != NULL) { + *pmd = FIPS_get_digestbynid(EVP_MD_type(*pmd)); + if (*pmd == NULL || !((*pmd)->flags & EVP_MD_FLAG_FIPS)) return rv; } - if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmgf1md != NULL) { + *pmgf1md = FIPS_get_digestbynid(EVP_MD_type(*pmgf1md)); + if (*pmgf1md == NULL || !((*pmgf1md)->flags & EVP_MD_FLAG_FIPS)) return rv; } return 1; @@ -214,27 +212,27 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; #ifdef OPENSSL_FIPS - ret = pkey_fips_check_ctx(ctx); + ret = pkey_fips_check_rsa(rsa, &md, &mgf1md); if (ret < 0) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (md != NULL) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } #ifdef OPENSSL_FIPS if (ret > 0) { unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, &slen); + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, &slen); if (ret > 0) *siglen = slen; else @@ -243,12 +241,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, } #endif - if (EVP_MD_type(rctx->md) == NID_mdc2) { + if (EVP_MD_type(md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; - ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, + rsa); if (ret <= 0) return ret; @@ -263,23 +261,20 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, return -1; } memcpy(rctx->tbuf, tbs, tbslen); - rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; - ret = RSA_sign(EVP_MD_type(rctx->md), - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign(EVP_MD_type(md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; - if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, - rctx->tbuf, tbs, - rctx->md, rctx->mgf1md, - rctx->saltlen)) + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, + md, mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); @@ -348,32 +343,31 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; size_t rslen; + #ifdef OPENSSL_FIPS - int rv; - rv = pkey_fips_check_ctx(ctx); + int rv = pkey_fips_check_rsa(rsa, &md, &mgf1md); + if (rv < 0) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { + if (md != NULL) { #ifdef OPENSSL_FIPS if (rv > 0) { - return FIPS_rsa_verify_digest(rsa, - tbs, tbslen, - rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, siglen); + return FIPS_rsa_verify_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, siglen); } #endif if (rctx->pad_mode == RSA_PKCS1_PADDING) - return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + return RSA_verify(EVP_MD_type(md), tbs, tbslen, sig, siglen, rsa); - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); return -1; } @@ -388,8 +382,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, rsa, RSA_NO_PADDING); if (ret <= 0) return 0; - ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, - rctx->md, rctx->mgf1md, + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, md, mgf1md, rctx->tbuf, rctx->saltlen); if (ret <= 0) return 0; diff --git a/deps/openssl/openssl/crypto/ui/ui_lib.c b/deps/openssl/openssl/crypto/ui/ui_lib.c index 643ae593439aeb..03ef981cf91224 100644 --- a/deps/openssl/openssl/crypto/ui/ui_lib.c +++ b/deps/openssl/openssl/crypto/ui/ui_lib.c @@ -520,6 +520,7 @@ int UI_process(UI *ui) } } } + err: if (ui->meth->ui_close_session != NULL && ui->meth->ui_close_session(ui) <= 0) diff --git a/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c b/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c index 807d1c49b2d3b7..96d042f5859e94 100644 --- a/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c +++ b/deps/openssl/openssl/crypto/whrlpool/wp_dgst.c @@ -166,7 +166,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) goto reconsider; } else #endif - if (bits >= 8) { + if (bits > 8) { b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); b &= 0xff; if (bitrem) @@ -183,7 +183,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) } if (bitrem) c->data[byteoff] = b << (8 - bitrem); - } else { /* remaining less than 8 bits */ + } else { /* remaining less than or equal to 8 bits */ b = (inp[0] << inpgap) & 0xff; if (bitrem) diff --git a/deps/openssl/openssl/crypto/x509/by_dir.c b/deps/openssl/openssl/crypto/x509/by_dir.c index bbc3189381e55e..6f0209a275ef33 100644 --- a/deps/openssl/openssl/crypto/x509/by_dir.c +++ b/deps/openssl/openssl/crypto/x509/by_dir.c @@ -402,6 +402,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, if (!hent) { hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); if (hent == NULL) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); goto finish; } diff --git a/deps/openssl/openssl/crypto/x509/by_file.c b/deps/openssl/openssl/crypto/x509/by_file.c index 43a073003d8bf6..82ce4e8d87c31d 100644 --- a/deps/openssl/openssl/crypto/x509/by_file.c +++ b/deps/openssl/openssl/crypto/x509/by_file.c @@ -92,12 +92,12 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) { int ok = 0; - char *file; + const char *file; switch (cmd) { case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = (char *)getenv(X509_get_default_cert_file_env()); + file = getenv(X509_get_default_cert_file_env()); if (file) ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); @@ -140,7 +140,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -199,7 +199,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -253,7 +253,7 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); BIO_free(in); if (!inf) { X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); diff --git a/deps/openssl/openssl/crypto/x509v3/pcy_tree.c b/deps/openssl/openssl/crypto/x509v3/pcy_tree.c index 09b8691c8694e1..03c9533bcca90e 100644 --- a/deps/openssl/openssl/crypto/x509v3/pcy_tree.c +++ b/deps/openssl/openssl/crypto/x509v3/pcy_tree.c @@ -732,6 +732,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) { int ret; + int calc_ret; X509_POLICY_TREE *tree = NULL; STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; *ptree = NULL; @@ -800,17 +801,20 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, /* Tree is not empty: continue */ - ret = tree_calculate_authority_set(tree, &auth_nodes); + calc_ret = tree_calculate_authority_set(tree, &auth_nodes); - if (!ret) + if (!calc_ret) goto error; - if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) - goto error; + ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); - if (ret == 2) + if (calc_ret == 2) sk_X509_POLICY_NODE_free(auth_nodes); + if (!ret) + goto error; + + if (tree) *ptree = tree; diff --git a/deps/openssl/openssl/crypto/x509v3/v3_addr.c b/deps/openssl/openssl/crypto/x509v3/v3_addr.c index 1290dec9bb8c0c..af080a04f2ba20 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_addr.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_addr.c @@ -130,10 +130,12 @@ static int length_from_afi(const unsigned afi) */ unsigned int v3_addr_get_afi(const IPAddressFamily *f) { - return ((f != NULL && - f->addressFamily != NULL && f->addressFamily->data != NULL) - ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) - : 0); + if (f == NULL + || f->addressFamily == NULL + || f->addressFamily->data == NULL + || f->addressFamily->length < 2) + return 0; + return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; } /* diff --git a/deps/openssl/openssl/crypto/x509v3/v3_genn.c b/deps/openssl/openssl/crypto/x509v3/v3_genn.c index 7f40bfabe0507a..9bb01ee38e6304 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_genn.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_genn.c @@ -231,6 +231,7 @@ int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, oth = OTHERNAME_new(); if (!oth) return 0; + ASN1_TYPE_free(oth->value); oth->type_id = oid; oth->value = value; GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); diff --git a/deps/openssl/openssl/crypto/x509v3/v3_ncons.c b/deps/openssl/openssl/crypto/x509v3/v3_ncons.c index 2855269668bee8..1184091ccf30dd 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_ncons.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_ncons.c @@ -107,6 +107,47 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) +/* + * We cannot use strncasecmp here because that applies locale specific rules. + * For example in Turkish 'I' is not the uppercase character for 'i'. We need to + * do a simple ASCII case comparison ignoring the locale (that is why we use + * numeric constants below). + */ +static int ia5ncasecmp(const char *s1, const char *s2, size_t n) +{ + for (; n > 0; n--, s1++, s2++) { + if (*s1 != *s2) { + unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2; + + /* Convert to lower case */ + if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */) + c1 += 0x20; + if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */) + c2 += 0x20; + + if (c1 == c2) + continue; + + if (c1 < c2) + return -1; + + /* c1 > c2 */ + return 1; + } else if (*s1 == 0) { + /* If we get here we know that *s2 == 0 too */ + return 0; + } + } + + return 0; +} + +static int ia5casecmp(const char *s1, const char *s2) +{ + /* No portable definition of SIZE_MAX, so we use (size_t)(-1) instead */ + return ia5ncasecmp(s1, s2, (size_t)(-1)); +} + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { @@ -384,7 +425,7 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) return X509_V_ERR_PERMITTED_VIOLATION; } - if (strcasecmp(baseptr, dnsptr)) + if (ia5casecmp(baseptr, dnsptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -404,7 +445,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) if (!baseat && (*baseptr == '.')) { if (eml->length > base->length) { emlptr += eml->length - base->length; - if (!strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; @@ -425,7 +466,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) } emlptr = emlat + 1; /* Just have hostname left to match: case insensitive */ - if (strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -464,14 +505,14 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) if (*baseptr == '.') { if (hostlen > base->length) { p = hostptr + hostlen - base->length; - if (!strncasecmp(p, baseptr, base->length)) + if (ia5ncasecmp(p, baseptr, base->length) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; } if ((base->length != (int)hostlen) - || strncasecmp(hostptr, baseptr, hostlen)) + || ia5ncasecmp(hostptr, baseptr, hostlen)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; diff --git a/deps/openssl/openssl/crypto/x86_64cpuid.pl b/deps/openssl/openssl/crypto/x86_64cpuid.pl index a3d6f438f91e7b..ef3608b13495e0 100644 --- a/deps/openssl/openssl/crypto/x86_64cpuid.pl +++ b/deps/openssl/openssl/crypto/x86_64cpuid.pl @@ -136,8 +136,19 @@ or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs and \$15,%ah cmp \$15,%ah # examine Family ID - jne .Lnotintel + jne .LnotP4 or \$0x00100000,%edx # set reserved bit#20 to engage RC4_CHAR +.LnotP4: + cmp \$6,%ah + jne .Lnotintel + and \$0x0fff0ff0,%eax + cmp \$0x00050670,%eax # Knights Landing + je .Lknights + cmp \$0x00080650,%eax # Knights Mill (according to sde) + jne .Lnotintel +.Lknights: + and \$0xfbffffff,%ecx # clear XSAVE flag to mimic Silvermont + .Lnotintel: bt \$28,%edx # test hyper-threading bit jnc .Lgeneric @@ -162,6 +173,10 @@ mov \$7,%eax xor %ecx,%ecx cpuid + bt \$26,%r9d # check XSAVE bit, cleared on Knights + jc .Lnotknights + and \$0xfff7ffff,%ebx # clear ADCX/ADOX flag +.Lnotknights: mov %ebx,8(%rdi) # save extended feature flags .Lno_extended_info: @@ -175,7 +190,7 @@ .Lclear_avx: mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11) and %eax,%r9d # clear AVX, FMA and AMD XOP bits - andl \$0xffffffdf,8(%rdi) # cleax AVX2, ~(1<<5) + andl \$0xffffffdf,8(%rdi) # clear AVX2, ~(1<<5) .Ldone: shl \$32,%r9 mov %r10d,%eax diff --git a/deps/openssl/openssl/doc-nits b/deps/openssl/openssl/doc-nits deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/deps/openssl/openssl/doc/apps/asn1parse.pod b/deps/openssl/openssl/doc/apps/asn1parse.pod index 76a765daf95b81..a84dbc37dc893e 100644 --- a/deps/openssl/openssl/doc/apps/asn1parse.pod +++ b/deps/openssl/openssl/doc/apps/asn1parse.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-asn1parse, asn1parse - ASN.1 parsing tool =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ca.pod b/deps/openssl/openssl/doc/apps/ca.pod index c90e6482e584cd..cc26bf48a3a74f 100644 --- a/deps/openssl/openssl/doc/apps/ca.pod +++ b/deps/openssl/openssl/doc/apps/ca.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-ca, ca - sample minimal CA application =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ciphers.pod b/deps/openssl/openssl/doc/apps/ciphers.pod index 35d40bbf27aeff..fa16124d08b87d 100644 --- a/deps/openssl/openssl/doc/apps/ciphers.pod +++ b/deps/openssl/openssl/doc/apps/ciphers.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ciphers, ciphers - SSL cipher display and cipher list tool. =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/cms.pod b/deps/openssl/openssl/doc/apps/cms.pod index ac69804228ccda..4a7783d47a4ea1 100644 --- a/deps/openssl/openssl/doc/apps/cms.pod +++ b/deps/openssl/openssl/doc/apps/cms.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-cms, cms - CMS utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/crl.pod b/deps/openssl/openssl/doc/apps/crl.pod index 044a9da91545ae..cdced1c742c02c 100644 --- a/deps/openssl/openssl/doc/apps/crl.pod +++ b/deps/openssl/openssl/doc/apps/crl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-crl, crl - CRL utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/crl2pkcs7.pod b/deps/openssl/openssl/doc/apps/crl2pkcs7.pod index 3797bc0df4ef33..18654c5afa0e66 100644 --- a/deps/openssl/openssl/doc/apps/crl2pkcs7.pod +++ b/deps/openssl/openssl/doc/apps/crl2pkcs7.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-crl2pkcs7, crl2pkcs7 - Create a PKCS#7 structure from a CRL and certificates. =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/dgst.pod b/deps/openssl/openssl/doc/apps/dgst.pod index b27bb946b1b2e3..72d6c87fabca5e 100644 --- a/deps/openssl/openssl/doc/apps/dgst.pod +++ b/deps/openssl/openssl/doc/apps/dgst.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dgst, dgst, sha, sha1, mdc2, ripemd160, sha224, sha256, sha384, sha512, md2, md4, md5, dss1 - message digests =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/dhparam.pod b/deps/openssl/openssl/doc/apps/dhparam.pod index 1cd4c76663c5b3..018d9935085a3e 100644 --- a/deps/openssl/openssl/doc/apps/dhparam.pod +++ b/deps/openssl/openssl/doc/apps/dhparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dhparam, dhparam - DH parameter manipulation and generation =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/dsa.pod b/deps/openssl/openssl/doc/apps/dsa.pod index 8bf6cc9dcad63b..77d66089beacd0 100644 --- a/deps/openssl/openssl/doc/apps/dsa.pod +++ b/deps/openssl/openssl/doc/apps/dsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dsa, dsa - DSA key processing =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/dsaparam.pod b/deps/openssl/openssl/doc/apps/dsaparam.pod index ba5ec4d72cdf8e..446903491357e2 100644 --- a/deps/openssl/openssl/doc/apps/dsaparam.pod +++ b/deps/openssl/openssl/doc/apps/dsaparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-dsaparam, dsaparam - DSA parameter manipulation and generation =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ec.pod b/deps/openssl/openssl/doc/apps/ec.pod index 5c7b45d4e75ee8..658eac5d509f16 100644 --- a/deps/openssl/openssl/doc/apps/ec.pod +++ b/deps/openssl/openssl/doc/apps/ec.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ec, ec - EC key processing =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ecparam.pod b/deps/openssl/openssl/doc/apps/ecparam.pod index 88e9d1e83d02b4..ba2f3b9ae274f5 100644 --- a/deps/openssl/openssl/doc/apps/ecparam.pod +++ b/deps/openssl/openssl/doc/apps/ecparam.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ecparam, ecparam - EC parameter manipulation and generation =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/enc.pod b/deps/openssl/openssl/doc/apps/enc.pod index 41791ad6713c4b..aceafcd4d557a1 100644 --- a/deps/openssl/openssl/doc/apps/enc.pod +++ b/deps/openssl/openssl/doc/apps/enc.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-enc, enc - symmetric cipher routines =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/errstr.pod b/deps/openssl/openssl/doc/apps/errstr.pod index b3c6ccfc9cbd70..0dee51c844ef30 100644 --- a/deps/openssl/openssl/doc/apps/errstr.pod +++ b/deps/openssl/openssl/doc/apps/errstr.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-errstr, errstr - lookup error codes =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/gendsa.pod b/deps/openssl/openssl/doc/apps/gendsa.pod index d9f56be890f883..2c8e5c86f208c1 100644 --- a/deps/openssl/openssl/doc/apps/gendsa.pod +++ b/deps/openssl/openssl/doc/apps/gendsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-gendsa, gendsa - generate a DSA private key from a set of parameters =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/genpkey.pod b/deps/openssl/openssl/doc/apps/genpkey.pod index 929edcd26ff00f..4d09fc0937c577 100644 --- a/deps/openssl/openssl/doc/apps/genpkey.pod +++ b/deps/openssl/openssl/doc/apps/genpkey.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-genpkey, genpkey - generate a private key =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/genrsa.pod b/deps/openssl/openssl/doc/apps/genrsa.pod index f4ed9593ae2695..8be06834f5079f 100644 --- a/deps/openssl/openssl/doc/apps/genrsa.pod +++ b/deps/openssl/openssl/doc/apps/genrsa.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-genrsa, genrsa - generate an RSA private key =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/nseq.pod b/deps/openssl/openssl/doc/apps/nseq.pod index 989c3108fb8364..de441fa87a4d40 100644 --- a/deps/openssl/openssl/doc/apps/nseq.pod +++ b/deps/openssl/openssl/doc/apps/nseq.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-nseq, nseq - create or examine a netscape certificate sequence =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ocsp.pod b/deps/openssl/openssl/doc/apps/ocsp.pod index 1bb7958d20e5a6..9e2716f00820b0 100644 --- a/deps/openssl/openssl/doc/apps/ocsp.pod +++ b/deps/openssl/openssl/doc/apps/ocsp.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ocsp, ocsp - Online Certificate Status Protocol utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/passwd.pod b/deps/openssl/openssl/doc/apps/passwd.pod index f44982549bf1a2..7f74ce016d92c6 100644 --- a/deps/openssl/openssl/doc/apps/passwd.pod +++ b/deps/openssl/openssl/doc/apps/passwd.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-passwd, passwd - compute password hashes =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkcs12.pod b/deps/openssl/openssl/doc/apps/pkcs12.pod index 744984838dc7c2..debc9ea27a27a5 100644 --- a/deps/openssl/openssl/doc/apps/pkcs12.pod +++ b/deps/openssl/openssl/doc/apps/pkcs12.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkcs12, pkcs12 - PKCS#12 file utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkcs7.pod b/deps/openssl/openssl/doc/apps/pkcs7.pod index acfb8100f0786f..651e9371c10587 100644 --- a/deps/openssl/openssl/doc/apps/pkcs7.pod +++ b/deps/openssl/openssl/doc/apps/pkcs7.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkcs7, pkcs7 - PKCS#7 utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkcs8.pod b/deps/openssl/openssl/doc/apps/pkcs8.pod index 6901f1f3f2112e..f741741e5ad2c9 100644 --- a/deps/openssl/openssl/doc/apps/pkcs8.pod +++ b/deps/openssl/openssl/doc/apps/pkcs8.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkcs8, pkcs8 - PKCS#8 format private key conversion tool =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkey.pod b/deps/openssl/openssl/doc/apps/pkey.pod index 4851223f3fcdc3..6db8a623839332 100644 --- a/deps/openssl/openssl/doc/apps/pkey.pod +++ b/deps/openssl/openssl/doc/apps/pkey.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkey, pkey - public or private key processing tool =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkeyparam.pod b/deps/openssl/openssl/doc/apps/pkeyparam.pod index 154f6721af4ab1..27c10a6a745c58 100644 --- a/deps/openssl/openssl/doc/apps/pkeyparam.pod +++ b/deps/openssl/openssl/doc/apps/pkeyparam.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-pkeyparam, pkeyparam - public key algorithm parameter processing tool =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/pkeyutl.pod b/deps/openssl/openssl/doc/apps/pkeyutl.pod index 5da347c97d327c..78b3b02a7d9662 100644 --- a/deps/openssl/openssl/doc/apps/pkeyutl.pod +++ b/deps/openssl/openssl/doc/apps/pkeyutl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-pkeyutl, pkeyutl - public key algorithm utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/rand.pod b/deps/openssl/openssl/doc/apps/rand.pod index d1d213ef43cbd0..94df10d939e00c 100644 --- a/deps/openssl/openssl/doc/apps/rand.pod +++ b/deps/openssl/openssl/doc/apps/rand.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-rand, rand - generate pseudo-random bytes =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/req.pod b/deps/openssl/openssl/doc/apps/req.pod index 1682ba5143dd02..20b2f39e90f2bd 100644 --- a/deps/openssl/openssl/doc/apps/req.pod +++ b/deps/openssl/openssl/doc/apps/req.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-req, req - PKCS#10 certificate request and certificate generating utility. =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/rsa.pod b/deps/openssl/openssl/doc/apps/rsa.pod index 21cbf8ee009b05..7e43e0f3d062ec 100644 --- a/deps/openssl/openssl/doc/apps/rsa.pod +++ b/deps/openssl/openssl/doc/apps/rsa.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-rsa, rsa - RSA key processing tool =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/rsautl.pod b/deps/openssl/openssl/doc/apps/rsautl.pod index 1a498c2f62e0e5..e16ce29cf6099f 100644 --- a/deps/openssl/openssl/doc/apps/rsautl.pod +++ b/deps/openssl/openssl/doc/apps/rsautl.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-rsautl, rsautl - RSA utility =head1 SYNOPSIS @@ -105,7 +106,7 @@ Recover the signed data Examine the raw signed data: - openssl rsautl -verify -in file -inkey key.pem -raw -hexdump + openssl rsautl -verify -in sig -inkey key.pem -raw -hexdump 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ diff --git a/deps/openssl/openssl/doc/apps/s_client.pod b/deps/openssl/openssl/doc/apps/s_client.pod index b45acbc5e3e42f..d9413a0cf211e5 100644 --- a/deps/openssl/openssl/doc/apps/s_client.pod +++ b/deps/openssl/openssl/doc/apps/s_client.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_client, s_client - SSL/TLS client program =head1 SYNOPSIS @@ -197,12 +198,14 @@ Can be used to override the implicit B<-ign_eof> after B<-quiet>. =item B<-psk_identity identity> Use the PSK identity B when using a PSK cipher suite. +The default value is "Client_identity" (without the quotes). =item B<-psk key> Use the PSK key B when using a PSK cipher suite. The key is given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. +This option must be provided in order to use a PSK cipher. =item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> diff --git a/deps/openssl/openssl/doc/apps/s_server.pod b/deps/openssl/openssl/doc/apps/s_server.pod index 1fe93ddfbebb0b..9916fc3ef6a311 100644 --- a/deps/openssl/openssl/doc/apps/s_server.pod +++ b/deps/openssl/openssl/doc/apps/s_server.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_server, s_server - SSL/TLS server program =head1 SYNOPSIS @@ -219,6 +220,7 @@ Use the PSK identity hint B when using a PSK cipher suite. Use the PSK key B when using a PSK cipher suite. The key is given as a hexadecimal number without leading 0x, for example -psk 1a2b3c4d. +This option must be provided in order to use a PSK cipher. =item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> @@ -403,10 +405,6 @@ a web browser the command: can be used for example. -Most web browsers (in particular Netscape and MSIE) only support RSA cipher -suites, so they cannot connect to servers which don't use a certificate -carrying an RSA key or a version of OpenSSL with RSA disabled. - Although specifying an empty list of CAs when requesting a client certificate is strictly speaking a protocol violation, some SSL clients interpret this to mean any CA is acceptable. This is useful for debugging purposes. diff --git a/deps/openssl/openssl/doc/apps/s_time.pod b/deps/openssl/openssl/doc/apps/s_time.pod index 9082d876feeb0e..1fa02800a4192c 100644 --- a/deps/openssl/openssl/doc/apps/s_time.pod +++ b/deps/openssl/openssl/doc/apps/s_time.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-s_time, s_time - SSL/TLS performance timing program =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/sess_id.pod b/deps/openssl/openssl/doc/apps/sess_id.pod index 9988d2cd3d5d05..0771baef117369 100644 --- a/deps/openssl/openssl/doc/apps/sess_id.pod +++ b/deps/openssl/openssl/doc/apps/sess_id.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-sess_id, sess_id - SSL/TLS session handling utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/smime.pod b/deps/openssl/openssl/doc/apps/smime.pod index 04a83ca8e427ba..fbf60da27faf36 100644 --- a/deps/openssl/openssl/doc/apps/smime.pod +++ b/deps/openssl/openssl/doc/apps/smime.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-smime, smime - S/MIME utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/speed.pod b/deps/openssl/openssl/doc/apps/speed.pod index 1cd1998d16759b..2bfe91e371cbb2 100644 --- a/deps/openssl/openssl/doc/apps/speed.pod +++ b/deps/openssl/openssl/doc/apps/speed.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-speed, speed - test library performance =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/spkac.pod b/deps/openssl/openssl/doc/apps/spkac.pod index 97fb80e4016b8a..b8a5477a063eb1 100644 --- a/deps/openssl/openssl/doc/apps/spkac.pod +++ b/deps/openssl/openssl/doc/apps/spkac.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-spkac, spkac - SPKAC printing and generating utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/ts.pod b/deps/openssl/openssl/doc/apps/ts.pod index d6aa47d3144d27..5da019b2eb2f27 100644 --- a/deps/openssl/openssl/doc/apps/ts.pod +++ b/deps/openssl/openssl/doc/apps/ts.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-ts, ts - Time Stamping Authority tool (client/server) =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/tsget.pod b/deps/openssl/openssl/doc/apps/tsget.pod index 56db985c4bb175..4856c850d8e100 100644 --- a/deps/openssl/openssl/doc/apps/tsget.pod +++ b/deps/openssl/openssl/doc/apps/tsget.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-tsget, tsget - Time Stamping HTTP/HTTPS client =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/verify.pod b/deps/openssl/openssl/doc/apps/verify.pod index b3767325ae075a..321d5ac7e126f4 100644 --- a/deps/openssl/openssl/doc/apps/verify.pod +++ b/deps/openssl/openssl/doc/apps/verify.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-verify, verify - Utility to verify certificates. =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/version.pod b/deps/openssl/openssl/doc/apps/version.pod index 58f543bc3e6456..675b0f84d6a7ca 100644 --- a/deps/openssl/openssl/doc/apps/version.pod +++ b/deps/openssl/openssl/doc/apps/version.pod @@ -2,6 +2,7 @@ =head1 NAME +openssl-version, version - print OpenSSL version information =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/apps/x509.pod b/deps/openssl/openssl/doc/apps/x509.pod index 1479a749571677..d50625862ac3a0 100644 --- a/deps/openssl/openssl/doc/apps/x509.pod +++ b/deps/openssl/openssl/doc/apps/x509.pod @@ -3,6 +3,7 @@ =head1 NAME +openssl-x509, x509 - Certificate display and signing utility =head1 SYNOPSIS diff --git a/deps/openssl/openssl/doc/crypto/BN_bn2bin.pod b/deps/openssl/openssl/doc/crypto/BN_bn2bin.pod index 3bed47f8f1d553..f6bb484f902ff8 100644 --- a/deps/openssl/openssl/doc/crypto/BN_bn2bin.pod +++ b/deps/openssl/openssl/doc/crypto/BN_bn2bin.pod @@ -70,8 +70,9 @@ BN_bn2bin() returns the length of the big-endian number placed at B. BN_bin2bn() returns the B, NULL on error. BN_bn2hex() and BN_bn2dec() return a null-terminated string, or NULL -on error. BN_hex2bn() and BN_dec2bn() return the number's length in -hexadecimal or decimal digits, and 0 on error. +on error. BN_hex2bn() and BN_dec2bn() return the number of characters +used in parsing, or 0 on error, in which +case no new B will be created. BN_print_fp() and BN_print() return 1 on success, 0 on write errors. diff --git a/deps/openssl/openssl/doc/crypto/BN_new.pod b/deps/openssl/openssl/doc/crypto/BN_new.pod index ab7a105e3ad7e9..d446603191af41 100644 --- a/deps/openssl/openssl/doc/crypto/BN_new.pod +++ b/deps/openssl/openssl/doc/crypto/BN_new.pod @@ -30,10 +30,12 @@ to the value 0. BN_free() frees the components of the B, and if it was created by BN_new(), also the structure itself. BN_clear_free() additionally overwrites the data before the memory is returned to the system. +If B is NULL, nothing is done. =head1 RETURN VALUES -BN_new() returns a pointer to the B. If the allocation fails, +BN_new() returns a pointer to the B initialised to the value 0. +If the allocation fails, it returns B and sets an error code that can be obtained by L. diff --git a/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod b/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod index 0c0a30c1ffa048..dc9a2d76c5f60c 100644 --- a/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod +++ b/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod @@ -395,8 +395,7 @@ processed (e.g. after an EVP_EncryptFinal() call). EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag); Sets the expected tag to B bytes from B. This call is only legal -when decrypting data and must be made B any data is processed (e.g. -before any EVP_DecryptUpdate() call). +when decrypting data. =head1 CCM Mode diff --git a/deps/openssl/openssl/doc/crypto/EVP_PKEY_meth_new.pod b/deps/openssl/openssl/doc/crypto/EVP_PKEY_meth_new.pod new file mode 100644 index 00000000000000..041492a8f0fbf1 --- /dev/null +++ b/deps/openssl/openssl/doc/crypto/EVP_PKEY_meth_new.pod @@ -0,0 +1,376 @@ +=pod + +=head1 NAME + +EVP_PKEY_meth_new, EVP_PKEY_meth_free, EVP_PKEY_meth_copy, EVP_PKEY_meth_find, +EVP_PKEY_meth_add0, EVP_PKEY_METHOD, +EVP_PKEY_meth_set_init, EVP_PKEY_meth_set_copy, EVP_PKEY_meth_set_cleanup, +EVP_PKEY_meth_set_paramgen, EVP_PKEY_meth_set_keygen, EVP_PKEY_meth_set_sign, +EVP_PKEY_meth_set_verify, EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_signctx, +EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt, EVP_PKEY_meth_set_decrypt, +EVP_PKEY_meth_set_derive, EVP_PKEY_meth_set_ctrl, +EVP_PKEY_meth_get_init, EVP_PKEY_meth_get_copy, EVP_PKEY_meth_get_cleanup, +EVP_PKEY_meth_get_paramgen, EVP_PKEY_meth_get_keygen, EVP_PKEY_meth_get_sign, +EVP_PKEY_meth_get_verify, EVP_PKEY_meth_get_verify_recover, EVP_PKEY_meth_get_signctx, +EVP_PKEY_meth_get_verifyctx, EVP_PKEY_meth_get_encrypt, EVP_PKEY_meth_get_decrypt, +EVP_PKEY_meth_get_derive, EVP_PKEY_meth_get_ctrl +- manipulating EVP_PKEY_METHOD structure + +=head1 SYNOPSIS + + #include + + typedef struct evp_pkey_method_st EVP_PKEY_METHOD; + + EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); + void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); + void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); + const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); + int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + + void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + + void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +=head1 DESCRIPTION + +B is a structure which holds a set of methods for a +specific public key cryptographic algorithm. Those methods are usually +used to perform different jobs, such as generating a key, signing or +verifying, encrypting or decrypting, etc. + +There are two places where the B objects are stored: one +is a built-in static array representing the standard methods for different +algorithms, and the other one is a stack of user-defined application-specific +methods, which can be manipulated by using L. + +The B objects are usually referenced by B +objects. + +=head2 Methods + +The methods are the underlying implementations of a particular public key +algorithm present by the B object. + + int (*init) (EVP_PKEY_CTX *ctx); + int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup) (EVP_PKEY_CTX *ctx); + +The init() method is called to initialize algorithm-specific data when a new +B is created. As opposed to init(), the cleanup() method is called +when an B is freed. The copy() method is called when an B +is being duplicated. Refer to L, L, +L and L. + + int (*paramgen_init) (EVP_PKEY_CTX *ctx); + int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + +The paramgen_init() and paramgen() methods deal with key parameter generation. +They are called by L and L to +handle the parameter generation process. + + int (*keygen_init) (EVP_PKEY_CTX *ctx); + int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + +The keygen_init() and keygen() methods are used to generate the actual key for +the specified algorithm. They are called by L and +L. + + int (*sign_init) (EVP_PKEY_CTX *ctx); + int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + +The sign_init() and sign() methods are used to generate the signature of a +piece of data using a private key. They are called by L +and L. + + int (*verify_init) (EVP_PKEY_CTX *ctx); + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + +The verify_init() and verify() methods are used to verify whether a signature is +valid. They are called by L and L. + + int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + int (*verify_recover) (EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + +The verify_recover_init() and verify_recover() methods are used to verify a +signature and then recover the digest from the signature (for instance, a +signature that was generated by RSA signing algorithm). They are called by +L and L. + + int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + +The signctx_init() and signctx() methods are used to sign a digest present by +a B object. They are called by the EVP_DigestSign functions. See +L for detail. + + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); + +The verifyctx_init() and verifyctx() methods are used to verify a signature +against the data in a B object. They are called by the various +EVP_DigestVerify functions. See L for detail. + + int (*encrypt_init) (EVP_PKEY_CTX *ctx); + int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +The encrypt_init() and encrypt() methods are used to encrypt a piece of data. +They are called by L and L. + + int (*decrypt_init) (EVP_PKEY_CTX *ctx); + int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +The decrypt_init() and decrypt() methods are used to decrypt a piece of data. +They are called by L and L. + + int (*derive_init) (EVP_PKEY_CTX *ctx); + int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +The derive_init() and derive() methods are used to derive the shared secret +from a public key algorithm (for instance, the DH algorithm). They are called by +L and L. + + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); + +The ctrl() and ctrl_str() methods are used to adjust algorithm-specific +settings. See L and related functions for detail. + + int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + +The digestsign() and digestverify() methods are used to generate or verify +a signature in a one-shot mode. They could be called by L +and L. + +=head2 Functions + +EVP_PKEY_meth_new() creates and returns a new B object, +and associates the given B and B. The following flags are +supported: + + EVP_PKEY_FLAG_AUTOARGLEN + EVP_PKEY_FLAG_SIGCTX_CUSTOM + +If an B is set with the B flag, the +maximum size of the output buffer will be automatically calculated or checked +in corresponding EVP methods by the EVP framework. Thus the implementations of +these methods don't need to care about handling the case of returning output +buffer size by themselves. For details on the output buffer size, refer to +L. + +The B is used to indicate the signctx() method +of an B is always called by the EVP framework while doing a +digest signing operation by calling L. + +EVP_PKEY_meth_free() frees an existing B pointed by +B. + +EVP_PKEY_meth_copy() copies an B object from B +to B. + +EVP_PKEY_meth_find() finds an B object with the B. +This function first searches through the user-defined method objects and +then the built-in objects. + +EVP_PKEY_meth_add0() adds B to the user defined stack of methods. + +The EVP_PKEY_meth_set functions set the corresponding fields of +B structure with the arguments passed. + +The EVP_PKEY_meth_get functions get the corresponding fields of +B structure to the arguments provided. + +=head1 RETURN VALUES + +EVP_PKEY_meth_new() returns a pointer to a new B +object or returns NULL on error. + +EVP_PKEY_meth_free() and EVP_PKEY_meth_copy() do not return values. + +EVP_PKEY_meth_find() returns a pointer to the found B +object or returns NULL if not found. + +EVP_PKEY_meth_add0() returns 1 if method is added successfully or 0 +if an error occurred. + +All EVP_PKEY_meth_set and EVP_PKEY_meth_get functions have no return +values. For the 'get' functions, function pointers are returned by +arguments. + +=head1 COPYRIGHT + +Copyright 2017 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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/deps/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod b/deps/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod index b8f678fe729d71..f20f815d478642 100644 --- a/deps/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod +++ b/deps/openssl/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod @@ -104,6 +104,13 @@ The RSA_padding_check_xxx() functions return the length of the recovered data, -1 on error. Error codes can be obtained by calling L. +=head1 WARNING + +The RSA_padding_check_PKCS1_type_2() padding check leaks timing +information which can potentially be used to mount a Bleichenbacher +padding oracle attack. This is an inherent weakness in the PKCS #1 +v1.5 padding design. Prefer PKCS1_OAEP padding. + =head1 SEE ALSO L, diff --git a/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod b/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod index 0541f348b3e20c..4d7c1f2cac7a27 100644 --- a/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod +++ b/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod @@ -67,6 +67,13 @@ recovered plaintext. On error, -1 is returned; the error codes can be obtained by L. +=head1 WARNING + +Decryption failures in the RSA_PKCS1_PADDING mode leak information +which can potentially be used to mount a Bleichenbacher padding oracle +attack. This is an inherent weakness in the PKCS #1 v1.5 padding +design. Prefer RSA_PKCS1_OAEP_PADDING. + =head1 CONFORMING TO SSL, PKCS #1 v2.0 diff --git a/deps/openssl/openssl/doc/crypto/X509_check_private_key.pod b/deps/openssl/openssl/doc/crypto/X509_check_private_key.pod new file mode 100644 index 00000000000000..a1fb07b1097e50 --- /dev/null +++ b/deps/openssl/openssl/doc/crypto/X509_check_private_key.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +X509_check_private_key, X509_REQ_check_private_key - check the consistency +of a private key with the public key in an X509 certificate or certificate +request + +=head1 SYNOPSIS + + #include + + int X509_check_private_key(X509 *x, EVP_PKEY *k); + + int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k); + +=head1 DESCRIPTION + +X509_check_private_key() function checks the consistency of private +key B with the public key in B. + +X509_REQ_check_private_key() is equivalent to X509_check_private_key() +except that B represents a certificate request of structure B. + +=head1 RETURN VALUE + +X509_check_private_key() and X509_REQ_check_private_key() return 1 if +the keys match each other, and 0 if not. + +If the key is invalid or an error occurred, the reason code can be +obtained using L. + +=head1 BUGS + +The B functions don't check if B itself is indeed +a private key or not. It merely compares the public materials (e.g. exponent +and modulus of an RSA key) and/or key parameters (e.g. EC params of an EC key) +of a key pair. So if you pass a public key to these functions in B, it will +return success. + +=head1 SEE ALSO + +L + +=head1 COPYRIGHT + +Copyright 2017 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 +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/deps/openssl/openssl/doc/crypto/hmac.pod b/deps/openssl/openssl/doc/crypto/hmac.pod index 2c8f20a2018869..ca9798af62c3fc 100644 --- a/deps/openssl/openssl/doc/crypto/hmac.pod +++ b/deps/openssl/openssl/doc/crypto/hmac.pod @@ -38,7 +38,8 @@ B bytes long. It places the result in B (which must have space for the output of the hash function, which is no more than B bytes). If B is NULL, the digest is placed in a static array. The size of -the output is placed in B, unless it is B. +the output is placed in B, unless it is B. Note: passing a NULL +value for B to use the static array is not thread safe. B can be EVP_sha1(), EVP_ripemd160() etc. diff --git a/deps/openssl/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod b/deps/openssl/openssl/doc/ssl/SSL_CTX_set_tlsext_servername_callback.pod similarity index 100% rename from deps/openssl/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod rename to deps/openssl/openssl/doc/ssl/SSL_CTX_set_tlsext_servername_callback.pod diff --git a/deps/openssl/openssl/doc/ssl/SSL_export_keying_material.pod b/deps/openssl/openssl/doc/ssl/SSL_export_keying_material.pod new file mode 100644 index 00000000000000..ccb99ec9a8e0b2 --- /dev/null +++ b/deps/openssl/openssl/doc/ssl/SSL_export_keying_material.pod @@ -0,0 +1,61 @@ +=pod + +=head1 NAME + +SSL_export_keying_material - obtain keying material for application use + +=head1 SYNOPSIS + + #include + + int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context); + +=head1 DESCRIPTION + +During the creation of a TLS or DTLS connection shared keying material is +established between the two endpoints. The function SSL_export_keying_material() +enables an application to use some of this keying material for its own purposes +in accordance with RFC5705. + +An application may need to securely establish the context within which this +keying material will be used. For example this may include identifiers for the +application session, application algorithms or parameters, or the lifetime of +the context. The context value is left to the application but must be the same +on both sides of the communication. + +For a given SSL connection B, B bytes of data will be written to +B. The application specific context should be supplied in the location +pointed to by B and should be B bytes long. Provision of +a context is optional. If the context should be omitted entirely then +B should be set to 0. Otherwise it should be any other value. If +B is 0 then the values of B and B are ignored. +Note that a zero length context is treated differently to no context at all, and +will result in different keying material being returned. + +An application specific label should be provided in the location pointed to by +B6.11.5
+6.12.0
+6.11.5
6.11.4
6.11.3
6.11.2
diff --git a/doc/api/cli.md b/doc/api/cli.md index 19d9844e03de89..41c747c1c3da75 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -128,7 +128,7 @@ Print stack traces for process warnings (including deprecations). ### `--redirect-warnings=file` Write process warnings to the given file instead of printing to stderr. The @@ -338,7 +338,7 @@ When set to `1`, process warnings are silenced. ### `NODE_OPTIONS=options...` `options...` are interpreted as if they had been specified on the command line @@ -438,7 +438,7 @@ OpenSSL, it may cause them to trust the same CAs as node. ### `NODE_REDIRECT_WARNINGS=file` When set, process warnings will be emitted to the given file instead of diff --git a/doc/api/crypto.md b/doc/api/crypto.md index e8d9a94462b5e0..4fe8ab95ed5e17 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -897,7 +897,7 @@ console.log(sign.sign(privateKey, 'hex')); @@ -1005,7 +1005,7 @@ This can be called many times with new data as it is streamed. diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 688e171639d77a..19c1c8de35dc2a 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -7,6 +7,7 @@ +6.12.0
6.11.5
6.11.4
6.11.3
@@ -54,6 +55,170 @@ [Node.js Long Term Support Plan](https://github.com/nodejs/LTS) and will be supported actively until April 2018 and maintained until April 2019. + +## 2017-11-07, Version 6.12.0 'Boron' (LTS), @MylesBorins + +This LTS release comes with 127 commits. This includes 45 which are test related, +33 which are doc related, 13 which are updates to dependencies and 7 commits which are related to build / tools. + +This release includes a security update to openssl that has been deemed low severity for the Node.js project. + +### Notable Changes + +* **assert**: + - assert.fail() can now take one or two arguments (Rich Trott) [#12293](https://github.com/nodejs/node/pull/12293) +* **crypto**: + - add sign/verify support for RSASSA-PSS (Tobias Nießen) [#11705](https://github.com/nodejs/node/pull/11705) +* **deps**: + - upgrade openssl sources to 1.0.2m (Shigeki Ohtsu) [#16691](https://github.com/nodejs/node/pull/16691) + - upgrade libuv to 1.15.0 (cjihrig) [#15745](https://github.com/nodejs/node/pull/15745) + - upgrade libuv to 1.14.1 (cjihrig) [#14866](https://github.com/nodejs/node/pull/14866) + - upgrade libuv to 1.13.1 (cjihrig) [#14117](https://github.com/nodejs/node/pull/14117) + - upgrade libuv to 1.12.0 (cjihrig) [#13306](https://github.com/nodejs/node/pull/13306) +* **fs**: + - Add support for fs.write/fs.writeSync(fd, buffer, cb) and fs.write/fs.writeSync(fd, buffer, offset, cb) as documented (Andreas Lind) [#7856](https://github.com/nodejs/node/pull/7856) +* **inspector**: + - enable --inspect-brk (Refael Ackermann) [#12615](https://github.com/nodejs/node/pull/12615) +* **process**: + - add --redirect-warnings command line argument (James M Snell) [#10116](https://github.com/nodejs/node/pull/10116) +* **src**: + - allow CLI args in env with NODE_OPTIONS (Sam Roberts) [#12028](https://github.com/nodejs/node/pull/12028) + - --abort-on-uncaught-exception in NODE_OPTIONS (Sam Roberts) [#13932](https://github.com/nodejs/node/pull/13932) + - allow --tls-cipher-list in NODE_OPTIONS (Sam Roberts) [#13172](https://github.com/nodejs/node/pull/13172) + - use SafeGetenv() for NODE_REDIRECT_WARNINGS (Sam Roberts) [#12677](https://github.com/nodejs/node/pull/12677) +* **test**: + - remove common.fail() (Rich Trott) [#12293](https://github.com/nodejs/node/pull/12293) + +### Commits + +* [[`4917d8cfef`](https://github.com/nodejs/node/commit/4917d8cfef)] - **(SEMVER-MINOR)** **assert**: improve assert.fail() API (Rich Trott) [#12293](https://github.com/nodejs/node/pull/12293) +* [[`5522bdf825`](https://github.com/nodejs/node/commit/5522bdf825)] - **benchmark**: use smaller n value in some http tests (Peter Marshall) [#14002](https://github.com/nodejs/node/pull/14002) +* [[`252d08ab77`](https://github.com/nodejs/node/commit/252d08ab77)] - **build**: use generic names for linting tasks (Nikolai Vavilov) [#15272](https://github.com/nodejs/node/pull/15272) +* [[`78dc92860f`](https://github.com/nodejs/node/commit/78dc92860f)] - **build**: fix shared installing target (Yorkie Liu) [#15148](https://github.com/nodejs/node/pull/15148) +* [[`6c9a9ff25c`](https://github.com/nodejs/node/commit/6c9a9ff25c)] - **build**: don't fail `make test` on source tarballs (Gibson Fahnestock) [#15441](https://github.com/nodejs/node/pull/15441) +* [[`af63b38142`](https://github.com/nodejs/node/commit/af63b38142)] - **crypto**: use X509V3_EXT_d2i (David Benjamin) [#15348](https://github.com/nodejs/node/pull/15348) +* [[`6b0812860d`](https://github.com/nodejs/node/commit/6b0812860d)] - **crypto**: use SSL_SESSION_get_id (David Benjamin) [#15348](https://github.com/nodejs/node/pull/15348) +* [[`46695703b6`](https://github.com/nodejs/node/commit/46695703b6)] - **crypto**: only try to set FIPS mode if different (Gibson Fahnestock) [#12210](https://github.com/nodejs/node/pull/12210) +* [[`10a70353b2`](https://github.com/nodejs/node/commit/10a70353b2)] - **crypto**: fix Node_SignFinal (David Benjamin) [#15024](https://github.com/nodejs/node/pull/15024) +* [[`a7d4cade46`](https://github.com/nodejs/node/commit/a7d4cade46)] - **(SEMVER-MINOR)** **crypto**: add sign/verify support for RSASSA-PSS (Tobias Nießen) [#11705](https://github.com/nodejs/node/pull/11705) +* [[`b98fa82de6`](https://github.com/nodejs/node/commit/b98fa82de6)] - **deps**: cherry-pick e7f4e9e from upstream libuv (Bartosz Sosnowski) [#16724](https://github.com/nodejs/node/pull/16724) +* [[`748d3e5d04`](https://github.com/nodejs/node/commit/748d3e5d04)] - **deps**: update openssl asm and asm_obsolete files (Shigeki Ohtsu) [#16691](https://github.com/nodejs/node/pull/16691) +* [[`5da4ceba86`](https://github.com/nodejs/node/commit/5da4ceba86)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [nodejs/io.js#1836](https://github.com/nodejs/io.js/pull/1836) +* [[`ef57db81ac`](https://github.com/nodejs/node/commit/ef57db81ac)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`7b93a2fd63`](https://github.com/nodejs/node/commit/7b93a2fd63)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`265d948b30`](https://github.com/nodejs/node/commit/265d948b30)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#16691](https://github.com/nodejs/node/pull/16691) +* [[`8386ce7645`](https://github.com/nodejs/node/commit/8386ce7645)] - **deps**: upgrade openssl sources to 1.0.2m (Shigeki Ohtsu) [#16691](https://github.com/nodejs/node/pull/16691) +* [[`02e4303c13`](https://github.com/nodejs/node/commit/02e4303c13)] - **(SEMVER-MINOR)** **deps**: upgrade libuv to 1.15.0 (cjihrig) [#15745](https://github.com/nodejs/node/pull/15745) +* [[`f22132e8f7`](https://github.com/nodejs/node/commit/f22132e8f7)] - **deps**: v8: fix potential segfault in profiler (Ali Ijaz Sheikh) [#15498](https://github.com/nodejs/node/pull/15498) +* [[`08d683053f`](https://github.com/nodejs/node/commit/08d683053f)] - **deps**: upgrade libuv to 1.14.1 (cjihrig) [#14866](https://github.com/nodejs/node/pull/14866) +* [[`a38755d0a4`](https://github.com/nodejs/node/commit/a38755d0a4)] - **deps**: upgrade libuv to 1.13.1 (cjihrig) [#14117](https://github.com/nodejs/node/pull/14117) +* [[`3265840504`](https://github.com/nodejs/node/commit/3265840504)] - **(SEMVER-MINOR)** **deps**: upgrade libuv to 1.12.0 (cjihrig) [#13306](https://github.com/nodejs/node/pull/13306) +* [[`2d3e735783`](https://github.com/nodejs/node/commit/2d3e735783)] - **deps**: V8: backport e560815 from upstream (Ali Ijaz Sheikh) [#16133](https://github.com/nodejs/node/pull/16133) +* [[`a776639987`](https://github.com/nodejs/node/commit/a776639987)] - **doc**: add 9.x to version picker and mark 8.x as LTS (Chris Young) [#16672](https://github.com/nodejs/node/pull/16672) +* [[`0f3901a905`](https://github.com/nodejs/node/commit/0f3901a905)] - **doc**: standardize function param/object prop style (Gibson Fahnestock) [#13769](https://github.com/nodejs/node/pull/13769) +* [[`b0fadbe54f`](https://github.com/nodejs/node/commit/b0fadbe54f)] - **doc**: fix typo in zlib.md (Luigi Pinca) [#16480](https://github.com/nodejs/node/pull/16480) +* [[`37b93724ff`](https://github.com/nodejs/node/commit/37b93724ff)] - **doc**: fix types and description for dns.resolveTxt (Tobias Nießen) [#15472](https://github.com/nodejs/node/pull/15472) +* [[`6e06d0e1b5`](https://github.com/nodejs/node/commit/6e06d0e1b5)] - **doc**: add callback function signatures in fs.md (Matej Krajčovič) [#13424](https://github.com/nodejs/node/pull/13424) +* [[`f1eda4a391`](https://github.com/nodejs/node/commit/f1eda4a391)] - **doc**: fix external links with 404 status (Vse Mozhet Byt) [#15463](https://github.com/nodejs/node/pull/15463) +* [[`c64603fbb5`](https://github.com/nodejs/node/commit/c64603fbb5)] - **doc**: add kfarnung to collaborators (Kyle Farnung) [#16108](https://github.com/nodejs/node/pull/16108) +* [[`da160cfda0`](https://github.com/nodejs/node/commit/da160cfda0)] - **doc**: mention collaboration summit in onboarding.md (Joyee Cheung) [#16079](https://github.com/nodejs/node/pull/16079) +* [[`699cfa1ee0`](https://github.com/nodejs/node/commit/699cfa1ee0)] - **doc**: fix macosx-firewall suggestion BUILDING (suraiyah) [#15829](https://github.com/nodejs/node/pull/15829) +* [[`547217346c`](https://github.com/nodejs/node/commit/547217346c)] - **doc**: add clearer setup description (Emily Platzer) [#15962](https://github.com/nodejs/node/pull/15962) +* [[`291b9c55cb`](https://github.com/nodejs/node/commit/291b9c55cb)] - **doc**: update style guide for markdown extension (Rich Trott) [#15786](https://github.com/nodejs/node/pull/15786) +* [[`eaec35db9f`](https://github.com/nodejs/node/commit/eaec35db9f)] - **doc**: fix incorrect vm.createContext usage (tshemsedinov) [#16059](https://github.com/nodejs/node/pull/16059) +* [[`ddee71afff`](https://github.com/nodejs/node/commit/ddee71afff)] - **doc**: fix typo in tls.md (kohta ito) [#15738](https://github.com/nodejs/node/pull/15738) +* [[`62ea82b73e`](https://github.com/nodejs/node/commit/62ea82b73e)] - **doc**: add 'git clean -xfd' to backport guide (Lance Ball) [#15715](https://github.com/nodejs/node/pull/15715) +* [[`6d41c850b2`](https://github.com/nodejs/node/commit/6d41c850b2)] - **doc**: alphabetize TSC Emeriti in README.md (Rich Trott) [#15722](https://github.com/nodejs/node/pull/15722) +* [[`6b1ce97196`](https://github.com/nodejs/node/commit/6b1ce97196)] - **doc**: fix dead link in doc/releases.md (Luigi Pinca) [#15733](https://github.com/nodejs/node/pull/15733) +* [[`e865fcbb07`](https://github.com/nodejs/node/commit/e865fcbb07)] - **doc**: edit COLLABORATORS_GUIDE.md for readability (Rich Trott) [#15629](https://github.com/nodejs/node/pull/15629) +* [[`af1863218c`](https://github.com/nodejs/node/commit/af1863218c)] - **doc**: fix links in some intra-repository docs (Vse Mozhet Byt) [#15675](https://github.com/nodejs/node/pull/15675) +* [[`926b46c138`](https://github.com/nodejs/node/commit/926b46c138)] - **doc**: update libuv license (Timothy Gu) [#15649](https://github.com/nodejs/node/pull/15649) +* [[`f29f20f3f9`](https://github.com/nodejs/node/commit/f29f20f3f9)] - **doc**: add bmeurer to collaborators (Benedikt Meurer) [#15677](https://github.com/nodejs/node/pull/15677) +* [[`eefa0a2dcc`](https://github.com/nodejs/node/commit/eefa0a2dcc)] - **doc**: retire bnoordhuis from the TSC (Ben Noordhuis) [#15626](https://github.com/nodejs/node/pull/15626) +* [[`b622a516e2`](https://github.com/nodejs/node/commit/b622a516e2)] - **doc**: ctc -\> tsc in collab guide (Bryan English) [#15590](https://github.com/nodejs/node/pull/15590) +* [[`377f7b9e9e`](https://github.com/nodejs/node/commit/377f7b9e9e)] - **doc**: fix 'aborted' event documentation (Luigi Pinca) [#15471](https://github.com/nodejs/node/pull/15471) +* [[`ccdc194350`](https://github.com/nodejs/node/commit/ccdc194350)] - **doc**: fix some internal links (Vse Mozhet Byt) [#15293](https://github.com/nodejs/node/pull/15293) +* [[`713f239900`](https://github.com/nodejs/node/commit/713f239900)] - **doc**: adding sebdeckers to collaborators (Sebastiaan Deckers) [#15354](https://github.com/nodejs/node/pull/15354) +* [[`21dec5573a`](https://github.com/nodejs/node/commit/21dec5573a)] - **doc**: update AUTHORS list (Michaël Zasso) [#15181](https://github.com/nodejs/node/pull/15181) +* [[`988eec3a93`](https://github.com/nodejs/node/commit/988eec3a93)] - **doc**: update README with SHASUMS256.txt.sig info (Jon Moss) [#15107](https://github.com/nodejs/node/pull/15107) +* [[`0b2d5486c6`](https://github.com/nodejs/node/commit/0b2d5486c6)] - **doc**: fix "added in" for Buffer.allocUnsafeSlow() (Tuan Anh Tran) [#15330](https://github.com/nodejs/node/pull/15330) +* [[`ae111c266c`](https://github.com/nodejs/node/commit/ae111c266c)] - **doc**: use consistent terminology in process doc (Rich Trott) [#15321](https://github.com/nodejs/node/pull/15321) +* [[`ab014d4056`](https://github.com/nodejs/node/commit/ab014d4056)] - **doc**: make mkdtemp example work on Windows (Bartosz Sosnowski) [#15408](https://github.com/nodejs/node/pull/15408) +* [[`a0b38054d9`](https://github.com/nodejs/node/commit/a0b38054d9)] - **doc**: make socket IPC examples more robust (cjihrig) [#13196](https://github.com/nodejs/node/pull/13196) +* [[`9ec87dcb0f`](https://github.com/nodejs/node/commit/9ec87dcb0f)] - **doc**: fix the description of 'close' event (Myles Borins) [#15800](https://github.com/nodejs/node/pull/15800) +* [[`323edfa42d`](https://github.com/nodejs/node/commit/323edfa42d)] - **docs**: clarify usage cli options -e,-p on windows (Łukasz Szewczak) [#15568](https://github.com/nodejs/node/pull/15568) +* [[`1de04908f3`](https://github.com/nodejs/node/commit/1de04908f3)] - **(SEMVER-MINOR)** **fs**: Fix default params for fs.write(Sync) (Andreas Lind) [#7856](https://github.com/nodejs/node/pull/7856) +* [[`3ac769091c`](https://github.com/nodejs/node/commit/3ac769091c)] - **(SEMVER-MINOR)** **gitignore**: add libuv book and GitHub template (cjihrig) [#13306](https://github.com/nodejs/node/pull/13306) +* [[`e31ab7c1ed`](https://github.com/nodejs/node/commit/e31ab7c1ed)] - **(SEMVER-MINOR)** **inspector**: enable --inspect-brk (Refael Ackermann) [#12615](https://github.com/nodejs/node/pull/12615) +* [[`880fba9c56`](https://github.com/nodejs/node/commit/880fba9c56)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`d1bf8cee63`](https://github.com/nodejs/node/commit/d1bf8cee63)] - **path**: fix normalize paths ending with two dots (Michaël Zasso) [nodejs-private/node-private#94](https://github.com/nodejs-private/node-private/pull/94) +* [[`f87a62699b`](https://github.com/nodejs/node/commit/f87a62699b)] - **path**: fix normalize on directories with two dots (Michaël Zasso) [#14107](https://github.com/nodejs/node/pull/14107) +* [[`16802c0b64`](https://github.com/nodejs/node/commit/16802c0b64)] - **(SEMVER-MINOR)** **process**: add --redirect-warnings command line argument (James M Snell) [#10116](https://github.com/nodejs/node/pull/10116) +* [[`02b46847c6`](https://github.com/nodejs/node/commit/02b46847c6)] - **repl**: force editorMode in .load (Lance Ball) [#14861](https://github.com/nodejs/node/pull/14861) +* [[`cdba9890a1`](https://github.com/nodejs/node/commit/cdba9890a1)] - **src**: replace manual memory mgmt with std::string (Ben Noordhuis) [#15782](https://github.com/nodejs/node/pull/15782) +* [[`931addba0b`](https://github.com/nodejs/node/commit/931addba0b)] - **src**: fix ^ in stack trace with vm's columnOffset (Timothy Gu) [#15771](https://github.com/nodejs/node/pull/15771) +* [[`81236d95f8`](https://github.com/nodejs/node/commit/81236d95f8)] - **src**: correct typo in trace_event header (Daniel Bevenius) [#15583](https://github.com/nodejs/node/pull/15583) +* [[`0b5798b3c3`](https://github.com/nodejs/node/commit/0b5798b3c3)] - **src**: remove outdated todo from node_crypto.cc (Bartek Szczepański) [#15104](https://github.com/nodejs/node/pull/15104) +* [[`cccf5a6edf`](https://github.com/nodejs/node/commit/cccf5a6edf)] - **(SEMVER-MINOR)** **src**: --abort-on-uncaught-exception in NODE_OPTIONS (Sam Roberts) [#13932](https://github.com/nodejs/node/pull/13932) +* [[`16f8f9b03f`](https://github.com/nodejs/node/commit/16f8f9b03f)] - **(SEMVER-MINOR)** **src**: allow --tls-cipher-list in NODE_OPTIONS (Sam Roberts) [#13172](https://github.com/nodejs/node/pull/13172) +* [[`12b66e60d7`](https://github.com/nodejs/node/commit/12b66e60d7)] - **src**: whitelist new options for NODE_OPTIONS (Sam Roberts) [#13002](https://github.com/nodejs/node/pull/13002) +* [[`dd6ea89217`](https://github.com/nodejs/node/commit/dd6ea89217)] - **src**: allow CLI args in env with NODE_OPTIONS (Sam Roberts) [#12028](https://github.com/nodejs/node/pull/12028) +* [[`8f4214836e`](https://github.com/nodejs/node/commit/8f4214836e)] - **src**: use a std::vector for preload_modules (Sam Roberts) [#12241](https://github.com/nodejs/node/pull/12241) +* [[`68f698c05a`](https://github.com/nodejs/node/commit/68f698c05a)] - **(SEMVER-MINOR)** **src**: use SafeGetenv() for NODE_REDIRECT_WARNINGS (Sam Roberts) [#12677](https://github.com/nodejs/node/pull/12677) +* [[`b166837551`](https://github.com/nodejs/node/commit/b166837551)] - **src,etw**: fix event 9 on 64 bit Windows (João Reis) [#15563](https://github.com/nodejs/node/pull/15563) +* [[`18987794bd`](https://github.com/nodejs/node/commit/18987794bd)] - **test**: move test-cluster-debug-port to sequential (Oleksandr Kushchak) [#16292](https://github.com/nodejs/node/pull/16292) +* [[`1fdbaed2f2`](https://github.com/nodejs/node/commit/1fdbaed2f2)] - **test**: begin normalizing fixtures use (James M Snell) [#14332](https://github.com/nodejs/node/pull/14332) +* [[`3ad6a9dfc4`](https://github.com/nodejs/node/commit/3ad6a9dfc4)] - **test**: remove assert message (Joe Henry) +* [[`58509ec471`](https://github.com/nodejs/node/commit/58509ec471)] - **test**: clarify assert messages in crypto tests (cpandrews8) [#16019](https://github.com/nodejs/node/pull/16019) +* [[`ab7f43aa41`](https://github.com/nodejs/node/commit/ab7f43aa41)] - **test**: include expected result in error messages (Chowdhurian) [#16039](https://github.com/nodejs/node/pull/16039) +* [[`342ac9f0c6`](https://github.com/nodejs/node/commit/342ac9f0c6)] - **test**: cleanup test-buffer-sharedarraybuffer (Rafal Leszczynski) [#15896](https://github.com/nodejs/node/pull/15896) +* [[`6eb88a4216`](https://github.com/nodejs/node/commit/6eb88a4216)] - **test**: updated error message (Emily Platzer) [#15906](https://github.com/nodejs/node/pull/15906) +* [[`40a98d6e7b`](https://github.com/nodejs/node/commit/40a98d6e7b)] - **test**: assert.strictEqual using template literals (jmcgui05) [#15944](https://github.com/nodejs/node/pull/15944) +* [[`cd57d2d92a`](https://github.com/nodejs/node/commit/cd57d2d92a)] - **test**: replace error msg w/ template literal (Sushil Tailor) [#15910](https://github.com/nodejs/node/pull/15910) +* [[`bce1f3810e`](https://github.com/nodejs/node/commit/bce1f3810e)] - **test**: add NODE_UNIQUE_ID value to err message (Daniele Lisi) [#15914](https://github.com/nodejs/node/pull/15914) +* [[`4243903278`](https://github.com/nodejs/node/commit/4243903278)] - **test**: replace string concatenation with template (Rob Paton) [#15915](https://github.com/nodejs/node/pull/15915) +* [[`f831744464`](https://github.com/nodejs/node/commit/f831744464)] - **test**: improve asset msg in test (Gene Wu) [#15918](https://github.com/nodejs/node/pull/15918) +* [[`d0bd56d509`](https://github.com/nodejs/node/commit/d0bd56d509)] - **test**: remove message from asserts (Justin Lee) [#15920](https://github.com/nodejs/node/pull/15920) +* [[`23e66edcbe`](https://github.com/nodejs/node/commit/23e66edcbe)] - **test**: improve an error message (Pavel Pomerantsev) [#15921](https://github.com/nodejs/node/pull/15921) +* [[`ad69a65b5f`](https://github.com/nodejs/node/commit/ad69a65b5f)] - **test**: replaced literals in errors with templates (Paul Milham) [#15911](https://github.com/nodejs/node/pull/15911) +* [[`16907461fe`](https://github.com/nodejs/node/commit/16907461fe)] - **test**: display better error message for assertion (Russell Dempsey) [#15883](https://github.com/nodejs/node/pull/15883) +* [[`4a664cea7d`](https://github.com/nodejs/node/commit/4a664cea7d)] - **test**: changed buffer-zero output (heeeunkimmm) [#15926](https://github.com/nodejs/node/pull/15926) +* [[`f8bc5ab262`](https://github.com/nodejs/node/commit/f8bc5ab262)] - **test**: remove literal error messages (Faisal Yaqoob) [#15928](https://github.com/nodejs/node/pull/15928) +* [[`1c1312e239`](https://github.com/nodejs/node/commit/1c1312e239)] - **test**: changes to use template literal (joanne-jjb) [#15937](https://github.com/nodejs/node/pull/15937) +* [[`fcab2c5ed2`](https://github.com/nodejs/node/commit/fcab2c5ed2)] - **test**: removed string from assert message arg (dpaulino) [#15954](https://github.com/nodejs/node/pull/15954) +* [[`f954536fc3`](https://github.com/nodejs/node/commit/f954536fc3)] - **test**: replace literal with template string (Brant Barger) [#15957](https://github.com/nodejs/node/pull/15957) +* [[`a93d3eb79d`](https://github.com/nodejs/node/commit/a93d3eb79d)] - **test**: improve assert messages (Eric Pemberton) [#15972](https://github.com/nodejs/node/pull/15972) +* [[`f9cb428cef`](https://github.com/nodejs/node/commit/f9cb428cef)] - **test**: replacing assert message with template (Barry Tam) [#15974](https://github.com/nodejs/node/pull/15974) +* [[`36747eeb62`](https://github.com/nodejs/node/commit/36747eeb62)] - **test**: alter assert.strictEqual to default message (Luke Greenleaf) [#15978](https://github.com/nodejs/node/pull/15978) +* [[`968cc44bd0`](https://github.com/nodejs/node/commit/968cc44bd0)] - **test**: remove messages in assert.strictEqual (Saeed H) [#16014](https://github.com/nodejs/node/pull/16014) +* [[`83a251336c`](https://github.com/nodejs/node/commit/83a251336c)] - **test**: skip test if host is too slow (Rich Trott) [#15688](https://github.com/nodejs/node/pull/15688) +* [[`e3ea2a455b`](https://github.com/nodejs/node/commit/e3ea2a455b)] - **test**: check that this != new.target in addon (Ben Noordhuis) [#15681](https://github.com/nodejs/node/pull/15681) +* [[`1483ebdc2c`](https://github.com/nodejs/node/commit/1483ebdc2c)] - **test**: improve readline test coverage for tty (Claudio Rodriguez) [#12064](https://github.com/nodejs/node/pull/12064) +* [[`96a64af7a6`](https://github.com/nodejs/node/commit/96a64af7a6)] - **test**: use reserved invalid hostname for tests (icarter09) [#14781](https://github.com/nodejs/node/pull/14781) +* [[`514ef7452c`](https://github.com/nodejs/node/commit/514ef7452c)] - **test**: make test-http-agent-maxsockets robust (Rich Trott) [#15192](https://github.com/nodejs/node/pull/15192) +* [[`c4b06b279d`](https://github.com/nodejs/node/commit/c4b06b279d)] - **test**: remove random timer in test-tls-fast-writing (Rich Trott) [#15138](https://github.com/nodejs/node/pull/15138) +* [[`9cebe8296a`](https://github.com/nodejs/node/commit/9cebe8296a)] - **test**: check inspect array with empty string key (Rahul Mishra) [#15258](https://github.com/nodejs/node/pull/15258) +* [[`6fe61d6d9c`](https://github.com/nodejs/node/commit/6fe61d6d9c)] - **test**: remove invalid test (Rich Trott) [#15320](https://github.com/nodejs/node/pull/15320) +* [[`48943e92d7`](https://github.com/nodejs/node/commit/48943e92d7)] - **test**: allow adding known-globals through ENV (Refael Ackermann) [#15187](https://github.com/nodejs/node/pull/15187) +* [[`5c99fc3fb3`](https://github.com/nodejs/node/commit/5c99fc3fb3)] - **test**: backward compatible api for tty (Gergely Nemeth) [#15235](https://github.com/nodejs/node/pull/15235) +* [[`06ee10e523`](https://github.com/nodejs/node/commit/06ee10e523)] - **test**: split path tests into multiple files (Michaël Zasso) [#15093](https://github.com/nodejs/node/pull/15093) +* [[`4030c7e077`](https://github.com/nodejs/node/commit/4030c7e077)] - **test**: update windows module load error message (cjihrig) [#14950](https://github.com/nodejs/node/pull/14950) +* [[`d25dc797f4`](https://github.com/nodejs/node/commit/d25dc797f4)] - **test**: skipIfInspectorDisabled cluster-inspect-brk (Daniel Bevenius) [#12757](https://github.com/nodejs/node/pull/12757) +* [[`7b9710d0df`](https://github.com/nodejs/node/commit/7b9710d0df)] - **test**: add inspect-brk option to cluster module (dave-k) [#12503](https://github.com/nodejs/node/pull/12503) +* [[`c9d440e8bd`](https://github.com/nodejs/node/commit/c9d440e8bd)] - **test**: change == to === in crypto test (Fabio Campinho) [#12405](https://github.com/nodejs/node/pull/12405) +* [[`dd946c3c2a`](https://github.com/nodejs/node/commit/dd946c3c2a)] - **test**: add hasCrypto check to test-cli-node-options (Daniel Bevenius) [#12692](https://github.com/nodejs/node/pull/12692) +* [[`ba830f0352`](https://github.com/nodejs/node/commit/ba830f0352)] - **test**: chdir before running test-cli-node-options (Daniel Bevenius) [#12660](https://github.com/nodejs/node/pull/12660) +* [[`d8f56371a9`](https://github.com/nodejs/node/commit/d8f56371a9)] - **test**: add cwd ENOENT known issue test (cjihrig) [#12343](https://github.com/nodejs/node/pull/12343) +* [[`1091b86290`](https://github.com/nodejs/node/commit/1091b86290)] - **(SEMVER-MINOR)** **test**: remove common.fail() (Rich Trott) [#12293](https://github.com/nodejs/node/pull/12293) +* [[`e0c4f0b85a`](https://github.com/nodejs/node/commit/e0c4f0b85a)] - **test,process**: run 'abort' suite on Windows (Refael Ackermann) [#15056](https://github.com/nodejs/node/pull/15056) +* [[`f49feab35f`](https://github.com/nodejs/node/commit/f49feab35f)] - **timers**: clarify lib/timer.js comment (Daniel Bevenius) [#11018](https://github.com/nodejs/node/pull/11018) +* [[`2409db6c99`](https://github.com/nodejs/node/commit/2409db6c99)] - **tools**: replace concatenation with string templates (Ethan Arrowood) [#15858](https://github.com/nodejs/node/pull/15858) +* [[`15ae5a44cf`](https://github.com/nodejs/node/commit/15ae5a44cf)] - **tools**: replace concat with template literals (Minya Liang) [#16046](https://github.com/nodejs/node/pull/16046) +* [[`705202d410`](https://github.com/nodejs/node/commit/705202d410)] - **tools**: use template literals (Sarah Meyer) [#15956](https://github.com/nodejs/node/pull/15956) +* [[`44cc39d278`](https://github.com/nodejs/node/commit/44cc39d278)] - **(SEMVER-MINOR)** **tools**: remove assert.fail() lint rule (Rich Trott) [#12293](https://github.com/nodejs/node/pull/12293) +* [[`88b9572d76`](https://github.com/nodejs/node/commit/88b9572d76)] - **tty**: require readline at top of file (Bryan English) [#15647](https://github.com/nodejs/node/pull/15647) +* [[`27af0bb446`](https://github.com/nodejs/node/commit/27af0bb446)] - **url**: change variable name to be more descriptive (Yang-Kichang) [#15551](https://github.com/nodejs/node/pull/15551) + ## 2017-10-24, Version 6.11.5 'Boron' (LTS), @MylesBorins diff --git a/src/node_version.h b/src/node_version.h index 0d6778476130fd..4632dbb59b9aa6 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -2,13 +2,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 6 -#define NODE_MINOR_VERSION 11 -#define NODE_PATCH_VERSION 6 +#define NODE_MINOR_VERSION 12 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Boron" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)