From 8aac118b69a10a134e57e8e066c56ba7370d25cc Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Thu, 10 Oct 2013 22:28:01 -0700 Subject: [PATCH 01/10] process: document kill(0), disallow kill(O_RDWR) The null signal test existed, but only tested the case where the target process existed, not when it did not exist. Also clarified that SIGUSR1 is reserved by Node.js only for receiveing, its not at all reserved when sending a signal with kill(). kill(pid, 'O_RDWR'), or any other node constant, "worked". I fixed this by also checking for 'SIG'. The same as done in the isSignal() function. Now the signal names supported by process.kill() are the same as those supported by process.on(). --- doc/api/process.markdown | 7 +++++-- src/node.js | 3 ++- test/simple/test-process-kill-null.js | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/doc/api/process.markdown b/doc/api/process.markdown index d36af6b5a7a..0514f5e2e7e 100644 --- a/doc/api/process.markdown +++ b/doc/api/process.markdown @@ -421,6 +421,9 @@ string describing the signal to send. Signal names are strings like 'SIGINT' or 'SIGHUP'. If omitted, the signal will be 'SIGTERM'. See kill(2) for more information. +Will throw an error if target does not exist, and as a special case, a signal of +`0` can be used to test for the existence of a process. + Note that just because the name of this function is `process.kill`, it is really just a signal sender, like the `kill` system call. The signal sent may do something other than kill the target process. @@ -438,8 +441,8 @@ Example of sending a signal to yourself: process.kill(process.pid, 'SIGHUP'); -Note: SIGUSR1 is reserved by node.js. It can be used to kickstart the -debugger. +Note: When SIGUSR1 is received by Node.js it starts the debugger, see +[Signal Events](#process_signal_events). ## process.pid diff --git a/src/node.js b/src/node.js index e5833cb5cc8..375bdfa18e1 100644 --- a/src/node.js +++ b/src/node.js @@ -717,7 +717,8 @@ r = process._kill(pid, 0); } else { sig = sig || 'SIGTERM'; - if (startup.lazyConstants()[sig]) { + if (startup.lazyConstants()[sig] && + sig.slice(0, 3) === 'SIG') { r = process._kill(pid, startup.lazyConstants()[sig]); } else { throw new Error('Unknown signal: ' + sig); diff --git a/test/simple/test-process-kill-null.js b/test/simple/test-process-kill-null.js index 708e27dff7c..520210ef1f8 100644 --- a/test/simple/test-process-kill-null.js +++ b/test/simple/test-process-kill-null.js @@ -27,7 +27,13 @@ var spawn = require('child_process').spawn; var cat = spawn('cat'); var called; -process.kill(cat.pid, 0); +assert.ok(process.kill(cat.pid, 0)); + +cat.on('exit', function() { + assert.throws(function() { + process.kill(cat.pid, 0); + }, Error); +}); cat.stdout.on('data', function() { called = true; From 94c4ba9dd33bf6d1ab4936f5d4039ecf7957bb32 Mon Sep 17 00:00:00 2001 From: Gabriel Falkenberg Date: Mon, 2 Dec 2013 11:18:37 +0100 Subject: [PATCH 02/10] doc: change constant to consistent --- doc/api/dns.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index 1ad6e6574c6..efcf127e8b1 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -5,7 +5,7 @@ Use `require('dns')` to access this module. All methods in the dns module use C-Ares except for `dns.lookup` which uses `getaddrinfo(3)` in a thread pool. C-Ares is much faster than `getaddrinfo` but the system resolver is -more constant with how other programs operate. When a user does +more consistent with how other programs operate. When a user does `net.connect(80, 'google.com')` or `http.get({ host: 'google.com' })` the `dns.lookup` method is used. Users who need to do a large number of lookups quickly should use the methods that go through C-Ares. From bd7fa92de421048b0eb8fb810eb66829424fc07f Mon Sep 17 00:00:00 2001 From: Yazhong Liu Date: Mon, 2 Dec 2013 13:31:06 +0800 Subject: [PATCH 03/10] doc: list execArgv option for child_process.fork() --- doc/api/child_process.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/api/child_process.markdown b/doc/api/child_process.markdown index 40cd1835207..7b51902d3b5 100644 --- a/doc/api/child_process.markdown +++ b/doc/api/child_process.markdown @@ -555,6 +555,8 @@ leaner than `child_process.exec`. It has the same options. * `env` {Object} Environment key-value pairs * `encoding` {String} (Default: 'utf8') * `execPath` {String} Executable used to create the child process + * `execArgv` {Array} List of string arguments passed to the executable + (Default: `process.execArgv`) * `silent` {Boolean} If true, prevent stdout and stderr in the spawned node process from being associated with the parent's (default is false) * Return: ChildProcess object From 60f777d343c5aea9021f008c4fb07541ccba4ad4 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 29 Nov 2013 20:09:59 +0400 Subject: [PATCH 04/10] tls: fix pool usage race When calling `encOut` in loop, `maybeInitFinished()` may invoke `clearOut`'s loop, leading to the writing of interleaved data (encrypted and cleartext) into the one shared pool. Move `maybeInitFinished()` out of the loop and add assertion for future. --- lib/tls.js | 15 +++---- test/simple/test-tls-interleave.js | 69 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 test/simple/test-tls-interleave.js diff --git a/lib/tls.js b/lib/tls.js index 2077b8f5c69..ab2704445f9 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -445,30 +445,29 @@ CryptoStream.prototype._read = function read(size) { } var bytesRead = 0, - start = this._buffer.offset; + start = this._buffer.offset, + last = start; do { + assert(last === this._buffer.offset); var read = this._buffer.use(this.pair.ssl, out, size - bytesRead); if (read > 0) { bytesRead += read; } + last = this._buffer.offset; // Handle and report errors if (this.pair.ssl && this.pair.ssl.error) { this.pair.error(); break; } - - // Get NPN and Server name when ready - this.pair.maybeInitFinished(); - - // `maybeInitFinished()` can emit the 'secure' event which - // in turn destroys the connection in case of authentication - // failure and sets `this.pair.ssl` to `null`. } while (read > 0 && !this._buffer.isFull && bytesRead < size && this.pair.ssl !== null); + // Get NPN and Server name when ready + this.pair.maybeInitFinished(); + // Create new buffer if previous was filled up var pool = this._buffer.pool; if (this._buffer.isFull) this._buffer.create(); diff --git a/test/simple/test-tls-interleave.js b/test/simple/test-tls-interleave.js new file mode 100644 index 00000000000..8bebb807e54 --- /dev/null +++ b/test/simple/test-tls-interleave.js @@ -0,0 +1,69 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var common = require('../common'); +var assert = require('assert'); + +var tls = require('tls'); +var fs = require('fs'); + +var PORT = common.PORT; +var dir = common.fixturesDir; +var options = { key: fs.readFileSync(dir + '/test_key.pem'), + cert: fs.readFileSync(dir + '/test_cert.pem'), + ca: [ fs.readFileSync(dir + '/test_ca.pem') ] }; + +var writes = [ + 'some server data', + 'and a separate packet', + 'and one more', +]; +var receivedWrites = 0; + +var server = tls.createServer(options, function(c) { + writes.forEach(function(str) { + c.write(str); + }); +}).listen(PORT, function() { + var c = tls.connect(PORT, { rejectUnauthorized: false }, function() { + c.write('some client data'); + c.on('readable', function() { + var data = c.read(); + if (data === null) + return; + + data = data.toString(); + while (data.length !== 0) { + assert.strictEqual(data.indexOf(writes[receivedWrites]), 0); + data = data.slice(writes[receivedWrites].length); + + if (++receivedWrites === writes.length) { + c.end(); + server.close(); + } + } + }); + }); +}); + +process.on('exit', function() { + assert.equal(receivedWrites, writes.length); +}); From b371d4ae8fdbf1b9046b9076cae1ee5fdc196724 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 4 Dec 2013 01:00:07 -0800 Subject: [PATCH 05/10] blog: bnoordhuis departure --- doc/blog/Uncategorized/bnoordhuis-departure.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 doc/blog/Uncategorized/bnoordhuis-departure.md diff --git a/doc/blog/Uncategorized/bnoordhuis-departure.md b/doc/blog/Uncategorized/bnoordhuis-departure.md new file mode 100644 index 00000000000..e49baf7a675 --- /dev/null +++ b/doc/blog/Uncategorized/bnoordhuis-departure.md @@ -0,0 +1,17 @@ +title: Ben Noordhuis's Departure +date: Tue Dec 3 14:13:57 PST 2013 +slug: bnoordhuis-departure + +As of this past weekend, Ben Noordhuis has decided to step away from +Node.js and libuv, and is no longer acting as a core committer. + +Ben has done a tremendous amount of great work in the past. We're sad +to lose the benefit of his continued hard work and expertise, and +extremely grateful for what he has added to Node.js and libuv over the +years. + +Many of you already have expressed your opinion regarding recent +drama, and I'd like to ask that you please respect our wishes to let +this issue rest, so that we can all focus on the road forward. + +Thanks. From 98be8df571f92ad0b846209c21cc00139bc14805 Mon Sep 17 00:00:00 2001 From: Kai Groner Date: Thu, 18 Apr 2013 19:01:14 -0400 Subject: [PATCH 06/10] crypto: Make Decipher._flush() emit errors. When Decipher processes a stream using an incorrect key, the DecipherFinal() method throws an unhandled exception at the end of the stream. --- lib/crypto.js | 7 ++++++- test/simple/test-crypto-stream.js | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/crypto.js b/lib/crypto.js index 0cc70ff15a8..22141ff8ae9 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -263,7 +263,12 @@ Cipher.prototype._transform = function(chunk, encoding, callback) { }; Cipher.prototype._flush = function(callback) { - this.push(this._binding.final()); + try { + this.push(this._binding.final()); + } catch (e) { + callback(e); + return; + } callback(); }; diff --git a/test/simple/test-crypto-stream.js b/test/simple/test-crypto-stream.js index b51516f7d19..72c9776d09b 100644 --- a/test/simple/test-crypto-stream.js +++ b/test/simple/test-crypto-stream.js @@ -60,3 +60,18 @@ crypto.createHash('md5').unpipe({}); crypto.createHash('md5').setEncoding('utf8'); crypto.createHash('md5').pause(); crypto.createHash('md5').resume(); + +// Decipher._flush() should emit an error event, not an exception. +var key = new Buffer('48fb56eb10ffeb13fc0ef551bbca3b1b', 'hex'), + badkey = new Buffer('12341234123412341234123412341234', 'hex'), + iv = new Buffer('6d358219d1f488f5f4eb12820a66d146', 'hex'), + cipher = crypto.createCipheriv('aes-128-cbc', key, iv), + decipher = crypto.createDecipheriv('aes-128-cbc', badkey, iv); + +cipher.pipe(decipher) + .on('error', common.mustCall(function end(err) { + // TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt + assert(/:06065064:/.test(err)); + })); + +cipher.end('Papaya!'); // Should not cause an unhandled exception. From 796834bf18d3af28216267ab54b8861e2ce981d3 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 6 Dec 2013 19:36:43 +0400 Subject: [PATCH 07/10] doc: document 'error' event for stream.Writable fix #5255 --- doc/api/stream.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index d750dbf5291..5ea3e3d0801 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -577,6 +577,10 @@ reader.pipe(writer); reader.unpipe(writer); ``` +#### Event: 'error' + +Emitted if there was an error when writing or piping data. + ### Class: stream.Duplex Duplex streams are streams that implement both the [Readable][] and From 5cfee927cd09dc9e74e2bc1d7454284d90831456 Mon Sep 17 00:00:00 2001 From: Yazhong Liu Date: Sat, 7 Dec 2013 02:28:39 +0800 Subject: [PATCH 08/10] doc: mention execArgv in setupMaster --- doc/api/cluster.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index 7f9ab25e3b4..b4c475f57fd 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -94,6 +94,8 @@ the worker pool for your application's needs. ## cluster.settings * {Object} + * `execArgv` {Array} list of string arguments passed to the node executable. + (Default=`process.execArgv`) * `exec` {String} file path to worker file. (Default=`process.argv[1]`) * `args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) From b5e161989cc3551ad7ec3723801a696fdbbf1525 Mon Sep 17 00:00:00 2001 From: Timothy J Fontaine Date: Fri, 6 Dec 2013 20:58:00 -0800 Subject: [PATCH 09/10] build: ./configure pass positional args to gyp use `--` to specify the arguments you want to pass directly to gyp. for example: `./configure -- --no-parallel -Dsome_define=foo` fixes #6370 --- configure | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 1a56c0db35c..0053b8de700 100755 --- a/configure +++ b/configure @@ -695,13 +695,17 @@ config = '\n'.join(map('='.join, config.iteritems())) + '\n' write('config.mk', '# Do not edit. Generated by the configure script.\n' + config) -if options.use_ninja: - gyp_args = ['-f', 'ninja-' + flavor] -elif options.use_xcode: - gyp_args = ['-f', 'xcode'] -elif flavor == 'win': - gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto'] -else: - gyp_args = ['-f', 'make-' + flavor] +gyp_args = [sys.executable, 'tools/gyp_node.py'] -subprocess.call([sys.executable, 'tools/gyp_node.py'] + gyp_args) +if options.use_ninja: + gyp_args += ['-f', 'ninja-' + flavor] +elif options.use_xcode: + gyp_args += ['-f', 'xcode'] +elif flavor == 'win': + gyp_args += ['-f', 'msvs', '-G', 'msvs_version=auto'] +else: + gyp_args += ['-f', 'make-' + flavor] + +gyp_args += args + +subprocess.call(gyp_args) From 2905884b63eb24184b576b1a963a4d72b0159171 Mon Sep 17 00:00:00 2001 From: Timothy J Fontaine Date: Fri, 6 Dec 2013 21:00:32 -0800 Subject: [PATCH 10/10] build: pass --no-parallel by default to gyp gyp by default now tries to process gyp files in parallel by using python's multiprocessing module, but it has problems on oddball platforms. We don't have many files or complex dependency chains that would benefit from parallel processing so disable by deafult fixes #6640 --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 0053b8de700..72c3c5f30a6 100755 --- a/configure +++ b/configure @@ -695,7 +695,7 @@ config = '\n'.join(map('='.join, config.iteritems())) + '\n' write('config.mk', '# Do not edit. Generated by the configure script.\n' + config) -gyp_args = [sys.executable, 'tools/gyp_node.py'] +gyp_args = [sys.executable, 'tools/gyp_node.py', '--no-parallel'] if options.use_ninja: gyp_args += ['-f', 'ninja-' + flavor]