From ef3617c6f862900ab5b4963164641c70f86c23a5 Mon Sep 17 00:00:00 2001 From: Bearice Ren Date: Sun, 26 Aug 2012 11:20:42 +0800 Subject: [PATCH 01/16] build: fix `make -j' fails after `make clean' make fails if: ./configure && make clean && make -j6 as out/Makefile has not yet be made when entering sub dirs --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 087adee1bf..d02a64a052 100644 --- a/Makefile +++ b/Makefile @@ -22,11 +22,11 @@ endif # to check for changes. .PHONY: node node_g -node: config.gypi +node: config.gypi out/Makefile $(MAKE) -C out BUILDTYPE=Release V=$(V) ln -fs out/Release/node node -node_g: config.gypi +node_g: config.gypi out/Makefile $(MAKE) -C out BUILDTYPE=Debug V=$(V) ln -fs out/Debug/node node_g From 0ef1e5b5eb31699ab5ec4272029f574c235b8a4c Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 28 Aug 2012 15:34:08 -0700 Subject: [PATCH 02/16] blog: Post for 0.9.1 release --- doc/blog/release/v0.9.1.md | 116 +++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 doc/blog/release/v0.9.1.md diff --git a/doc/blog/release/v0.9.1.md b/doc/blog/release/v0.9.1.md new file mode 100644 index 0000000000..dcc0bb0a73 --- /dev/null +++ b/doc/blog/release/v0.9.1.md @@ -0,0 +1,116 @@ +version: 0.9.1 +title: Version 0.9.1 (Unstable) +category: release +slug: node-v0-9-1-unstable +date: 2012-08-28T22:33:45.659Z + +2012.08.28, Version 0.9.1 (Unstable) + +* buffer: Add Buffer.isEncoding(enc) to test for valid encoding values (isaacs) + +* Raise UV_ECANCELED on premature close. (Ben Noordhuis) + +* Remove c-ares from libuv, move to a top-level node dependency (Bert Belder) + +* ref/unref for all HandleWraps, timers, servers, and sockets (Timothy J Fontaine) + +* addon: remove node-waf, superseded by node-gyp (Ben Noordhuis) + +* child_process: emit error on exec failure (Ben Noordhuis) + +* cluster: do not use internal server API (Andreas Madsen) + +* constants: add O_DIRECT (Ian Babrou) + +* crypto: add sync interface to crypto.pbkdf2() (Ben Noordhuis) + +* darwin: emulate fdatasync() (Fedor Indutny) + +* dgram: make .bind() always asynchronous (Ben Noordhuis) + +* events: Make emitter.listeners() side-effect free (isaacs, Joe Andaverde) + +* fs: Throw early on invalid encoding args (isaacs) + +* fs: fix naming of truncate/ftruncate functions (isaacs) + +* http: bubble up parser errors to ClientRequest (Brian White) + +* linux: improve cpuinfo parser on ARM and MIPS (Ben Noordhuis) + +* net: add support for IPv6 addresses ending in :: (Josh Erickson) + +* net: support Server.listen(Pipe) (Andreas Madsen) + +* node: don't scan add-on for "init" symbol (Ben Noordhuis) + +* remove process.uvCounters() (Ben Noordhuis) + +* repl: console writes to repl rather than process stdio (Nathan Rajlich) + +* timers: implement setImmediate (Timothy J Fontaine) + +* tls: fix segfault in pummel/test-tls-ci-reneg-attack (Ben Noordhuis) + +* tools: Move gyp addon tools to node-gyp (Nathan Rajlich) + +* unix: preliminary signal handler support (Ben Noordhuis) + +* unix: remove dependency on ev_child (Ben Noordhuis) + +* unix: work around darwin bug, don't poll() on pipe (Fedor Indutny) + +* util: Formally deprecate util.pump() (Ben Noordhuis) + +* windows: make active and closing handle state independent (Bert Belder) + +* windows: report spawn errors to the exit callback (Bert Belder) + +* windows: signal handling support with uv_signal_t (Bert Belder) + + +Source Code: http://nodejs.org/dist/v0.9.1/node-v0.9.1.tar.gz + +Macintosh Installer (Universal): http://nodejs.org/dist/v0.9.1/node-v0.9.1.pkg + +Windows Installer: http://nodejs.org/dist/v0.9.1/node-v0.9.1-x86.msi + +Windows x64 Installer: http://nodejs.org/dist/v0.9.1/x64/node-v0.9.1-x64.msi + +Windows x64 Files: http://nodejs.org/dist/v0.9.1/x64/ + +Linux 32-bit Binary: http://nodejs.org/dist/v0.9.1/node-v0.9.1-linux-x86.tar.gz + +Linux 64-bit Binary: http://nodejs.org/dist/v0.9.1/node-v0.9.1-linux-x64.tar.gz + +Solaris 32-bit Binary: http://nodejs.org/dist/v0.9.1/node-v0.9.1-sunos-x86.tar.gz + +Solaris 64-bit Binary: http://nodejs.org/dist/v0.9.1/node-v0.9.1-sunos-x64.tar.gz + +Other release files: http://nodejs.org/dist/v0.9.1/ + +Website: http://nodejs.org/docs/v0.9.1/ + +Documentation: http://nodejs.org/docs/v0.9.1/api/ + +Shasums: + +``` +b86a5b0b2c9a89d08baaeb3d5270a8f247b4ba43 node-v0.9.1-darwin-x64.tar.gz +800af9d15a4b65e624351bb94dedc3b7eb322b86 node-v0.9.1-darwin-x86.tar.gz +a7ea43b0db472ca84dc9838960dae57ff0abaa72 node-v0.9.1-linux-x64.tar.gz +89c4be492a946eefa45aa87d16787875aa0f2dff node-v0.9.1-linux-x86.tar.gz +6495d2814541e945dba5941b8d3facf2a61dc55d node-v0.9.1-sunos-x64.tar.gz +05ea83ba4d648f5b949833bb28d69e6eeebabb78 node-v0.9.1-sunos-x86.tar.gz +3ccf1ac2fea7f2d05bcaed590bc54ee61c982fbb node-v0.9.1-x86.msi +bd0ede40e4681b16088284fe6a18ae3a5c5a3795 node-v0.9.1.tar.gz +159470a999ef23fa940ad3c54265053c3d2a4332 node.exe +02472e388a44b91e2644178a0fe011354fcd361e node.exp +c6d6ce22be4b47ad022d82dd91ebd4c040742fee node.lib +7b4cec8b4106d90a077388fe483fdbb13119dcb1 node.pdb +a5fbf5e22c7623a9206abc6608d084ff53c7c4c9 x64/node-v0.9.1-x64.msi +9755685a9d7bea6dc63d3260829c26c5b0430a7a x64/node.exe +621f177733647848f7f667926fe4f498a1f50c97 x64/node.exp +5877dffbf012c458dab88f3392af59cb33720d2f x64/node.lib +dc513ce5c16771dcfab9c1777d5949252290b412 x64/node.pdb +``` From dec16aa5c2e21de1d0db737f2a08872993c1b2dd Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 29 Aug 2012 12:26:28 -0700 Subject: [PATCH 03/16] Test client renegotiation attacks on HTTPS This test should output roughly the same results as the tls ci-reneg attack pummel test. However, it does not. --- test/pummel/test-https-ci-reneg-attack.js | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/pummel/test-https-ci-reneg-attack.js diff --git a/test/pummel/test-https-ci-reneg-attack.js b/test/pummel/test-https-ci-reneg-attack.js new file mode 100644 index 0000000000..83b76b4585 --- /dev/null +++ b/test/pummel/test-https-ci-reneg-attack.js @@ -0,0 +1,106 @@ +// 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 spawn = require('child_process').spawn; +var tls = require('tls'); +var https = require('https'); +var fs = require('fs'); + +// renegotiation limits to test +var LIMITS = [0, 1, 2, 3, 5, 10, 16]; + +if (process.platform === 'win32') { + console.log('Skipping test, you probably don\'t have openssl installed.'); + process.exit(); +} + +(function() { + var n = 0; + function next() { + if (n >= LIMITS.length) return; + tls.CLIENT_RENEG_LIMIT = LIMITS[n++]; + test(next); + } + next(); +})(); + +function test(next) { + var options = { + cert: fs.readFileSync(common.fixturesDir + '/test_cert.pem'), + key: fs.readFileSync(common.fixturesDir + '/test_key.pem') + }; + + var seenError = false; + + var server = https.createServer(options, function(req, res) { + var conn = req.connection; + conn.on('error', function(err) { + console.error('Caught exception: ' + err); + assert(/TLS session renegotiation attack/.test(err)); + conn.destroy(); + seenError = true; + }); + res.end('ok'); + }); + + server.listen(common.PORT, function() { + var args = ('s_client -connect 127.0.0.1:' + common.PORT).split(' '); + var child = spawn('openssl', args); + + child.stdout.pipe(process.stdout); + child.stderr.pipe(process.stderr); + + // count handshakes, start the attack after the initial handshake is done + var handshakes = 0; + var renegs = 0; + + child.stderr.on('data', function(data) { + if (seenError) return; + handshakes += (('' + data).match(/verify return:1/g) || []).length; + if (handshakes === 2) spam(); + renegs += (('' + data).match(/RENEGOTIATING/g) || []).length; + }); + + child.on('exit', function() { + assert.equal(renegs, tls.CLIENT_RENEG_LIMIT + 1); + server.close(); + process.nextTick(next); + }); + + var closed = false; + child.stdin.on('error', function(err) { + assert.equal(err.code, 'EPIPE'); + closed = true; + }); + child.stdin.on('close', function() { + closed = true; + }); + + // simulate renegotiation attack + function spam() { + if (closed) return; + child.stdin.write('R\n'); + setTimeout(spam, 50); + } + }); +} From a57d31595d842b7f250d06e14c58340d5c4c453e Mon Sep 17 00:00:00 2001 From: Ankur Oberoi Date: Wed, 29 Aug 2012 13:52:55 -0300 Subject: [PATCH 04/16] doc: fix grammar errors --- doc/api/http.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/http.markdown b/doc/api/http.markdown index df4976115c..48c9abaa09 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -354,7 +354,7 @@ which has been transmitted are equal or not. ### response.statusCode When using implicit headers (not calling `response.writeHead()` explicitly), this property -controls the status code that will be send to the client when the headers get +controls the status code that will be sent to the client when the headers get flushed. Example: @@ -452,7 +452,7 @@ emit trailers, with a list of the header fields in its value. E.g., ### response.end([data], [encoding]) This method signals to the server that all of the response headers and body -has been sent; that server should consider this message complete. +have been sent; that server should consider this message complete. The method, `response.end()`, MUST be called on each response. From 355c14842734e790a2581b9db58041c7ca54edf9 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Wed, 29 Aug 2012 14:57:25 -0700 Subject: [PATCH 05/16] build: set `process.platform` to "sunos" on SunOS gyp sets it to "solaris" by default, but versions of node v0.6.x and older would report "sunos". Let's keep things consistent. Fixes #3944. --- node.gyp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/node.gyp b/node.gyp index 84ec69d6b7..82af2fe7ca 100644 --- a/node.gyp +++ b/node.gyp @@ -228,6 +228,14 @@ '-lkstat', '-lumem', ], + 'defines!': [ + 'PLATFORM="solaris"', + ], + 'defines': [ + # we need to use node's preferred "sunos" + # rather than gyp's preferred "solaris" + 'PLATFORM="sunos"', + ], }], ], 'msvs-settings': { From b0d2795fe9501218dd8c953252fffe2d05d59c2a Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Thu, 30 Aug 2012 16:13:27 +0200 Subject: [PATCH 06/16] child process: fix processes with IPC channel don't emit 'close' With this patch the IPC socket is no longer available in the ChildProcess.stdio array. This shouldn't be very problematic, since this socket was effectively non-functional; it would never emit any events. --- lib/child_process.js | 10 +++- .../child-process-message-and-exit.js | 3 + test/simple/test-child-process-fork-close.js | 57 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/child-process-message-and-exit.js create mode 100644 test/simple/test-child-process-fork-close.js diff --git a/lib/child_process.js b/lib/child_process.js index 215da0bebd..9b31586c44 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -300,6 +300,9 @@ function setupChannel(target, channel) { } else { this.buffering = false; target.disconnect(); + channel.onread = nop; + channel.close(); + maybeClose(target); } }; @@ -745,7 +748,7 @@ ChildProcess.prototype.spawn = function(options) { ipc = createPipe(true); ipcFd = i; - acc.push({ type: 'pipe', handle: ipc }); + acc.push({ type: 'pipe', handle: ipc, ipc: true }); } else if (typeof stdio === 'number' || typeof stdio.fd === 'number') { acc.push({ type: 'fd', fd: stdio.fd || stdio }); } else if (getHandleWrapType(stdio) || getHandleWrapType(stdio.handle) || @@ -796,6 +799,11 @@ ChildProcess.prototype.spawn = function(options) { stdio.forEach(function(stdio, i) { if (stdio.type === 'ignore') return; + if (stdio.ipc) { + self._closesNeeded++; + return; + } + if (stdio.handle) { // when i === 0 - we're dealing with stdin // (which is the only one writable pipe) diff --git a/test/fixtures/child-process-message-and-exit.js b/test/fixtures/child-process-message-and-exit.js new file mode 100644 index 0000000000..56e83ce801 --- /dev/null +++ b/test/fixtures/child-process-message-and-exit.js @@ -0,0 +1,3 @@ + +process.send('hello'); +process.exit(0); diff --git a/test/simple/test-child-process-fork-close.js b/test/simple/test-child-process-fork-close.js new file mode 100644 index 0000000000..342cffec3c --- /dev/null +++ b/test/simple/test-child-process-fork-close.js @@ -0,0 +1,57 @@ +// 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 assert = require('assert'), + common = require('../common'), + fork = require('child_process').fork, + fork = require('child_process').fork; + +var cp = fork(common.fixturesDir + '/child-process-message-and-exit.js'); + +var gotMessage = false, + gotExit = false, + gotClose = false; + +cp.on('message', function(message) { + assert(!gotMessage); + assert(!gotClose); + assert.strictEqual(message, 'hello'); + gotMessage = true; +}); + +cp.on('exit', function() { + assert(!gotExit); + assert(!gotClose); + gotExit = true; +}); + +cp.on('close', function() { + assert(gotMessage); + assert(gotExit); + assert(!gotClose); + gotClose = true; +}); + +process.on('exit', function() { + assert(gotMessage); + assert(gotExit); + assert(gotClose); +}); From 9603f08f21987d5367d98267a16179a61e4400c1 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Thu, 30 Aug 2012 17:28:02 +0200 Subject: [PATCH 07/16] uv: upgrade to 24c062c --- deps/uv/include/uv.h | 5 +++-- deps/uv/src/unix/error.c | 1 + deps/uv/src/unix/udp.c | 5 +++++ deps/uv/src/win/core.c | 3 +++ deps/uv/src/win/tcp.c | 14 +++++++++++++- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 7c2c03f928..49160b2bc2 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -120,8 +120,9 @@ extern "C" { XX( 53, ENOTEMPTY, "directory not empty") \ XX( 54, ENOSPC, "no space left on device") \ XX( 55, EIO, "i/o error") \ - XX( 56, EROFS, "read-only file system" ) \ - XX( 57, ENODEV, "no such device" ) + XX( 56, EROFS, "read-only file system") \ + XX( 57, ENODEV, "no such device") \ + XX( 58, ESPIPE, "invalid seek") \ #define UV_ERRNO_GEN(val, name, s) UV_##name = val, diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index 9fbb312eef..b2add994a0 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -68,6 +68,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case EAFNOSUPPORT: return UV_EAFNOSUPPORT; case EBADF: return UV_EBADF; case EPIPE: return UV_EPIPE; + case ESPIPE: return UV_ESPIPE; case EAGAIN: return UV_EAGAIN; #if EWOULDBLOCK != EAGAIN case EWOULDBLOCK: return UV_EAGAIN; diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 9f87060aee..634d4a0613 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -86,6 +86,10 @@ void uv__udp_finish_close(uv_udp_t* handle) { req = ngx_queue_data(q, uv_udp_send_t, queue); uv__req_unregister(handle->loop, req); + if (req->bufs != req->bufsml) + free(req->bufs); + req->bufs = NULL; + if (req->send_cb) { /* FIXME proper error code like UV_EABORTED */ uv__set_artificial_error(handle->loop, UV_EINTR); @@ -171,6 +175,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) { if (req->bufs != req->bufsml) free(req->bufs); + req->bufs = NULL; if (req->send_cb == NULL) continue; diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index 7a35580382..79fb655c0f 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -70,6 +70,9 @@ static void uv_loop_init(uv_loop_t* loop) { uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); } + /* To prevent uninitialized memory access, loop->time must be intialized */ + /* to zero before calling uv_update_time for the first time. */ + loop->time = 0; uv_update_time(loop); ngx_queue_init(&loop->handle_queue); diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index e13c0f3dfe..9ac01401e1 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -547,7 +547,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { if(!handle->accept_reqs) { handle->accept_reqs = (uv_tcp_accept_t*) - malloc(simultaneous_accepts * sizeof(uv_tcp_accept_t)); + malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); if (!handle->accept_reqs) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } @@ -571,6 +571,18 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { uv_tcp_queue_accept(handle, req); } + + /* Initialize other unused requests too, because uv_tcp_endgame */ + /* doesn't know how how many requests were intialized, so it will */ + /* try to clean up {uv_simultaneous_server_accepts} requests. */ + for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { + req = &handle->accept_reqs[i]; + uv_req_init(loop, (uv_req_t*) req); + req->type = UV_ACCEPT; + req->accept_socket = INVALID_SOCKET; + req->data = handle; + req->wait_handle = INVALID_HANDLE_VALUE; + } } return 0; From f347077e786b1ca78d44e2c77b1bc1366735af76 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Fri, 31 Aug 2012 00:11:05 +0900 Subject: [PATCH 08/16] tls: support unix domain socket/named pipe in tls.connect --- lib/net.js | 1 + lib/tls.js | 49 ++++++++++++---------------- test/simple/test-tls-connect-pipe.js | 49 ++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 test/simple/test-tls-connect-pipe.js diff --git a/lib/net.js b/lib/net.js index d0a4c641bf..efed0cacde 100644 --- a/lib/net.js +++ b/lib/net.js @@ -106,6 +106,7 @@ function normalizeConnectArgs(args) { var cb = args[args.length - 1]; return (typeof cb === 'function') ? [options, cb] : [options]; } +exports._normalizeConnectArgs = normalizeConnectArgs; /* called when creating new Socket, or when re-using a closed Socket */ diff --git a/lib/tls.js b/lib/tls.js index 350b5776d0..ee3695567c 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -1183,34 +1183,24 @@ Server.prototype.SNICallback = function(servername) { // }); // // +function normalizeConnectArgs(listArgs) { + var args = net._normalizeConnectArgs(listArgs); + var options = args[0]; + var cb = args[1]; + + if (typeof listArgs[1] === 'object') { + options = util._extend(options, listArgs[1]); + } else if (typeof listArgs[2] === 'object') { + options = util._extend(options, listArgs[2]); + } + + return (cb) ? [options, cb] : [options]; +} + exports.connect = function(/* [port, host], options, cb */) { - var options, port, host, cb; - - if (typeof arguments[0] === 'object') { - options = arguments[0]; - } else if (typeof arguments[1] === 'object') { - options = arguments[1]; - port = arguments[0]; - } else if (typeof arguments[2] === 'object') { - options = arguments[2]; - port = arguments[0]; - host = arguments[1]; - } else { - // This is what happens when user passes no `options` argument, we can't - // throw `TypeError` here because it would be incompatible with old API - if (typeof arguments[0] === 'number') { - port = arguments[0]; - } - if (typeof arguments[1] === 'string') { - host = arguments[1]; - } - } - - options = util._extend({ port: port, host: host }, options || {}); - - if (typeof arguments[arguments.length - 1] === 'function') { - cb = arguments[arguments.length - 1]; - } + var args = normalizeConnectArgs(arguments); + var options = args[0]; + var cb = args[1]; var socket = options.socket ? options.socket : new net.Stream(); @@ -1235,11 +1225,12 @@ exports.connect = function(/* [port, host], options, cb */) { } if (!options.socket) { - socket.connect({ + var connect_opt = (options.path && !options.port) ? {path: options.path} : { port: options.port, host: options.host, localAddress: options.localAddress - }); + }; + socket.connect(connect_opt); } pair.on('secure', function() { diff --git a/test/simple/test-tls-connect-pipe.js b/test/simple/test-tls-connect-pipe.js new file mode 100644 index 0000000000..f58aaabcfe --- /dev/null +++ b/test/simple/test-tls-connect-pipe.js @@ -0,0 +1,49 @@ +// 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 clientConnected = 0; +var serverConnected = 0; + +var options = { + key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), + cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') +}; + +var server = tls.Server(options, function(socket) { + ++serverConnected; + server.close(); +}); +server.listen(common.PIPE, function() { + var client = tls.connect(common.PIPE, function() { + ++clientConnected; + client.end(); + }); +}); + +process.on('exit', function() { + assert.equal(clientConnected, 1); + assert.equal(serverConnected, 1); +}); From 6b9425fe3783193cf95cb04cbcbcbb97f5a77d31 Mon Sep 17 00:00:00 2001 From: koichik Date: Sun, 2 Sep 2012 00:14:18 +0900 Subject: [PATCH 09/16] buffer: added support for writing NaN and Infinity to writeDoubleBE(), writeDoubleLE(), writeFloatBE() and writeFloatLE(). Fixes #3934. --- lib/buffer.js | 10 ++++-- test/simple/test-writedouble.js | 63 +++++++++++++++++++++++++++++++++ test/simple/test-writefloat.js | 39 ++++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index 53f484c56d..cf458b0b2a 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -1002,10 +1002,14 @@ function verifsint(value, max, min) { assert.ok(Math.floor(value) === value, 'value has a fractional component'); } -function verifIEEE754(value, max, min) { +function verifyIEEE754(value, max, min) { assert.ok(typeof (value) == 'number', 'cannot write a non-number as a number'); + if (isNaN(value) || value === Infinity || value === -Infinity) { + return; + } + assert.ok(value <= max, 'value larger than maximum allowed value'); assert.ok(value >= min, 'value smaller than minimum allowed value'); @@ -1112,7 +1116,7 @@ function writeFloat(buffer, value, offset, isBigEndian, noAssert) { assert.ok(offset + 3 < buffer.length, 'Trying to write beyond buffer length'); - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + verifyIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); } require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, @@ -1141,7 +1145,7 @@ function writeDouble(buffer, value, offset, isBigEndian, noAssert) { assert.ok(offset + 7 < buffer.length, 'Trying to write beyond buffer length'); - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + verifyIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); } require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, diff --git a/test/simple/test-writedouble.js b/test/simple/test-writedouble.js index 829ba29a73..58c88272c7 100644 --- a/test/simple/test-writedouble.js +++ b/test/simple/test-writedouble.js @@ -123,6 +123,69 @@ function test(clazz) { ASSERT.equal(0x00, buffer[13]); ASSERT.equal(0x00, buffer[14]); ASSERT.equal(0x80, buffer[15]); + + buffer.writeDoubleBE(Infinity, 0); + buffer.writeDoubleLE(Infinity, 8); + ASSERT.equal(0x7F, buffer[0]); + ASSERT.equal(0xF0, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x00, buffer[7]); + ASSERT.equal(0x00, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0xF0, buffer[14]); + ASSERT.equal(0x7F, buffer[15]); + ASSERT.equal(Infinity, buffer.readDoubleBE(0)); + ASSERT.equal(Infinity, buffer.readDoubleLE(8)); + + buffer.writeDoubleBE(-Infinity, 0); + buffer.writeDoubleLE(-Infinity, 8); + ASSERT.equal(0xFF, buffer[0]); + ASSERT.equal(0xF0, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x00, buffer[7]); + ASSERT.equal(0x00, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0xF0, buffer[14]); + ASSERT.equal(0xFF, buffer[15]); + ASSERT.equal(-Infinity, buffer.readDoubleBE(0)); + ASSERT.equal(-Infinity, buffer.readDoubleLE(8)); + + buffer.writeDoubleBE(NaN, 0); + buffer.writeDoubleLE(NaN, 8); + ASSERT.equal(0x7F, buffer[0]); + ASSERT.equal(0xF0, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x01, buffer[7]); + ASSERT.equal(0x01, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0xF0, buffer[14]); + ASSERT.equal(0x7F, buffer[15]); + ASSERT.ok(isNaN(buffer.readDoubleBE(0))); + ASSERT.ok(isNaN(buffer.readDoubleLE(8))); } diff --git a/test/simple/test-writefloat.js b/test/simple/test-writefloat.js index d10cb7547b..b160d1290d 100644 --- a/test/simple/test-writefloat.js +++ b/test/simple/test-writefloat.js @@ -83,6 +83,45 @@ function test(clazz) { ASSERT.equal(0x00, buffer[5]); ASSERT.equal(0x00, buffer[6]); ASSERT.equal(0x80, buffer[7]); + + buffer.writeFloatBE(Infinity, 0); + buffer.writeFloatLE(Infinity, 4); + ASSERT.equal(0x7F, buffer[0]); + ASSERT.equal(0x80, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x80, buffer[6]); + ASSERT.equal(0x7F, buffer[7]); + ASSERT.equal(Infinity, buffer.readFloatBE(0)); + ASSERT.equal(Infinity, buffer.readFloatLE(4)); + + buffer.writeFloatBE(-Infinity, 0); + buffer.writeFloatLE(-Infinity, 4); + ASSERT.equal(0xFF, buffer[0]); + ASSERT.equal(0x80, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x80, buffer[6]); + ASSERT.equal(0xFF, buffer[7]); + ASSERT.equal(-Infinity, buffer.readFloatBE(0)); + ASSERT.equal(-Infinity, buffer.readFloatLE(4)); + + buffer.writeFloatBE(NaN, 0); + buffer.writeFloatLE(NaN, 4); + ASSERT.equal(0x7F, buffer[0]); + ASSERT.equal(0x80, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x01, buffer[3]); + ASSERT.equal(0x01, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x80, buffer[6]); + ASSERT.equal(0x7F, buffer[7]); + ASSERT.ok(isNaN(buffer.readFloatBE(0))); + ASSERT.ok(isNaN(buffer.readFloatLE(4))); } From 6c5fdd5223963631ea97d8a20388fc3147a8bdeb Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 2 Sep 2012 13:32:57 +0200 Subject: [PATCH 10/16] doc: document prerequisites in README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 309d539b10..988305facd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,13 @@ Evented I/O for V8 javascript. [![Build Status](https://secure.travis-ci.org/joy ### To build: -Unix/Macintosh. Requires python 2.6 or 2.7 and GNU make 3.81 or newer: +Prerequisites (Unix only): + + * Python 2.6 or 2.7 + * GNU Make 3.81 or newer + * libexecinfo (FreeBSD and OpenBSD only) + +Unix/Macintosh: ./configure make From 37f0eb8df310fb43f29ff4ffff5e23fba660dbaa Mon Sep 17 00:00:00 2001 From: koichik Date: Sun, 2 Sep 2012 20:59:50 +0900 Subject: [PATCH 11/16] Revert "buffer: added support for writing NaN and Infinity" This reverts commit 6b9425fe3783193cf95cb04cbcbcbb97f5a77d31. --- lib/buffer.js | 10 ++---- test/simple/test-writedouble.js | 63 --------------------------------- test/simple/test-writefloat.js | 39 -------------------- 3 files changed, 3 insertions(+), 109 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index cf458b0b2a..53f484c56d 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -1002,14 +1002,10 @@ function verifsint(value, max, min) { assert.ok(Math.floor(value) === value, 'value has a fractional component'); } -function verifyIEEE754(value, max, min) { +function verifIEEE754(value, max, min) { assert.ok(typeof (value) == 'number', 'cannot write a non-number as a number'); - if (isNaN(value) || value === Infinity || value === -Infinity) { - return; - } - assert.ok(value <= max, 'value larger than maximum allowed value'); assert.ok(value >= min, 'value smaller than minimum allowed value'); @@ -1116,7 +1112,7 @@ function writeFloat(buffer, value, offset, isBigEndian, noAssert) { assert.ok(offset + 3 < buffer.length, 'Trying to write beyond buffer length'); - verifyIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); } require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, @@ -1145,7 +1141,7 @@ function writeDouble(buffer, value, offset, isBigEndian, noAssert) { assert.ok(offset + 7 < buffer.length, 'Trying to write beyond buffer length'); - verifyIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); } require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, diff --git a/test/simple/test-writedouble.js b/test/simple/test-writedouble.js index 58c88272c7..829ba29a73 100644 --- a/test/simple/test-writedouble.js +++ b/test/simple/test-writedouble.js @@ -123,69 +123,6 @@ function test(clazz) { ASSERT.equal(0x00, buffer[13]); ASSERT.equal(0x00, buffer[14]); ASSERT.equal(0x80, buffer[15]); - - buffer.writeDoubleBE(Infinity, 0); - buffer.writeDoubleLE(Infinity, 8); - ASSERT.equal(0x7F, buffer[0]); - ASSERT.equal(0xF0, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x00, buffer[3]); - ASSERT.equal(0x00, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x00, buffer[6]); - ASSERT.equal(0x00, buffer[7]); - ASSERT.equal(0x00, buffer[8]); - ASSERT.equal(0x00, buffer[9]); - ASSERT.equal(0x00, buffer[10]); - ASSERT.equal(0x00, buffer[11]); - ASSERT.equal(0x00, buffer[12]); - ASSERT.equal(0x00, buffer[13]); - ASSERT.equal(0xF0, buffer[14]); - ASSERT.equal(0x7F, buffer[15]); - ASSERT.equal(Infinity, buffer.readDoubleBE(0)); - ASSERT.equal(Infinity, buffer.readDoubleLE(8)); - - buffer.writeDoubleBE(-Infinity, 0); - buffer.writeDoubleLE(-Infinity, 8); - ASSERT.equal(0xFF, buffer[0]); - ASSERT.equal(0xF0, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x00, buffer[3]); - ASSERT.equal(0x00, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x00, buffer[6]); - ASSERT.equal(0x00, buffer[7]); - ASSERT.equal(0x00, buffer[8]); - ASSERT.equal(0x00, buffer[9]); - ASSERT.equal(0x00, buffer[10]); - ASSERT.equal(0x00, buffer[11]); - ASSERT.equal(0x00, buffer[12]); - ASSERT.equal(0x00, buffer[13]); - ASSERT.equal(0xF0, buffer[14]); - ASSERT.equal(0xFF, buffer[15]); - ASSERT.equal(-Infinity, buffer.readDoubleBE(0)); - ASSERT.equal(-Infinity, buffer.readDoubleLE(8)); - - buffer.writeDoubleBE(NaN, 0); - buffer.writeDoubleLE(NaN, 8); - ASSERT.equal(0x7F, buffer[0]); - ASSERT.equal(0xF0, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x00, buffer[3]); - ASSERT.equal(0x00, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x00, buffer[6]); - ASSERT.equal(0x01, buffer[7]); - ASSERT.equal(0x01, buffer[8]); - ASSERT.equal(0x00, buffer[9]); - ASSERT.equal(0x00, buffer[10]); - ASSERT.equal(0x00, buffer[11]); - ASSERT.equal(0x00, buffer[12]); - ASSERT.equal(0x00, buffer[13]); - ASSERT.equal(0xF0, buffer[14]); - ASSERT.equal(0x7F, buffer[15]); - ASSERT.ok(isNaN(buffer.readDoubleBE(0))); - ASSERT.ok(isNaN(buffer.readDoubleLE(8))); } diff --git a/test/simple/test-writefloat.js b/test/simple/test-writefloat.js index b160d1290d..d10cb7547b 100644 --- a/test/simple/test-writefloat.js +++ b/test/simple/test-writefloat.js @@ -83,45 +83,6 @@ function test(clazz) { ASSERT.equal(0x00, buffer[5]); ASSERT.equal(0x00, buffer[6]); ASSERT.equal(0x80, buffer[7]); - - buffer.writeFloatBE(Infinity, 0); - buffer.writeFloatLE(Infinity, 4); - ASSERT.equal(0x7F, buffer[0]); - ASSERT.equal(0x80, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x00, buffer[3]); - ASSERT.equal(0x00, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x80, buffer[6]); - ASSERT.equal(0x7F, buffer[7]); - ASSERT.equal(Infinity, buffer.readFloatBE(0)); - ASSERT.equal(Infinity, buffer.readFloatLE(4)); - - buffer.writeFloatBE(-Infinity, 0); - buffer.writeFloatLE(-Infinity, 4); - ASSERT.equal(0xFF, buffer[0]); - ASSERT.equal(0x80, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x00, buffer[3]); - ASSERT.equal(0x00, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x80, buffer[6]); - ASSERT.equal(0xFF, buffer[7]); - ASSERT.equal(-Infinity, buffer.readFloatBE(0)); - ASSERT.equal(-Infinity, buffer.readFloatLE(4)); - - buffer.writeFloatBE(NaN, 0); - buffer.writeFloatLE(NaN, 4); - ASSERT.equal(0x7F, buffer[0]); - ASSERT.equal(0x80, buffer[1]); - ASSERT.equal(0x00, buffer[2]); - ASSERT.equal(0x01, buffer[3]); - ASSERT.equal(0x01, buffer[4]); - ASSERT.equal(0x00, buffer[5]); - ASSERT.equal(0x80, buffer[6]); - ASSERT.equal(0x7F, buffer[7]); - ASSERT.ok(isNaN(buffer.readFloatBE(0))); - ASSERT.ok(isNaN(buffer.readFloatLE(4))); } From ea1cba6246a8b1784e22d076139b9244a9ff42f8 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Mon, 3 Sep 2012 19:05:40 +0200 Subject: [PATCH 12/16] windows: don't blow when a signal handler is attached Blowing up when the user attaches a signal handler makes no sense. Also, in Node 0.10 signals will be supported, so allow people to get used to it. --- src/node.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/node.js b/src/node.js index 071016e0d0..1abd0b6506 100644 --- a/src/node.js +++ b/src/node.js @@ -462,6 +462,10 @@ }; startup.processSignalHandlers = function() { + // Not supported on Windows. + if (process.platform === 'win32') + return; + // Load events module in order to access prototype elements on process like // process.addListener. var signalWatchers = {}; From d1eff9ab68ae3fa32285544ad9f1d2c2ed52ab82 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 3 Sep 2012 23:09:17 +0200 Subject: [PATCH 13/16] crypto: make randomBytes() compatible with domains Don't execute the callback in the context of the global object. MakeCallback() tries to apply the active domain to the callback. If the user polluted the global object with a 'domain' property, as in the code example below, MakeCallback() will try to apply that. Example: domain = {}; // missing var keyword is intentional crypto.randomBytes(8, cb); // TypeError: undefined is not a function Fixes #3956. --- src/node_crypto.cc | 22 +++++++------------ test/simple/test-domain-crypto.js | 36 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 test/simple/test-domain-crypto.js diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 5b21e55a8c..dc5da802bb 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4354,7 +4354,7 @@ typedef int (*RandomBytesGenerator)(unsigned char* buf, int size); struct RandomBytesRequest { ~RandomBytesRequest(); - Persistent callback_; + Persistent obj_; unsigned long error_; // openssl error code or zero uv_work_t work_req_; size_t size_; @@ -4363,10 +4363,9 @@ struct RandomBytesRequest { RandomBytesRequest::~RandomBytesRequest() { - if (!callback_.IsEmpty()) { - callback_.Dispose(); - callback_.Clear(); - } + if (obj_.IsEmpty()) return; + obj_.Dispose(); + obj_.Clear(); } @@ -4427,12 +4426,7 @@ void RandomBytesAfter(uv_work_t* work_req) { HandleScope scope; Local argv[2]; RandomBytesCheck(req, argv); - - // XXX There should be an object connected to this that - // we can attach a domain onto. - MakeCallback(Context::GetCurrent()->Global(), - req->callback_, - ARRAY_SIZE(argv), argv); + MakeCallback(req->obj_, "ondone", ARRAY_SIZE(argv), argv); delete req; } @@ -4457,15 +4451,15 @@ Handle RandomBytes(const Arguments& args) { req->size_ = size; if (args[1]->IsFunction()) { - Local callback_v = Local(Function::Cast(*args[1])); - req->callback_ = Persistent::New(callback_v); + req->obj_ = Persistent::New(Object::New()); + req->obj_->Set(String::New("ondone"), args[1]); uv_queue_work(uv_default_loop(), &req->work_req_, RandomBytesWork, RandomBytesAfter); - return Undefined(); + return req->obj_; } else { Local argv[2]; diff --git a/test/simple/test-domain-crypto.js b/test/simple/test-domain-crypto.js new file mode 100644 index 0000000000..532a8b09d3 --- /dev/null +++ b/test/simple/test-domain-crypto.js @@ -0,0 +1,36 @@ +// 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. + +try { + var crypto = require('crypto'); +} catch (e) { + console.log('Not compiled with OPENSSL support.'); + process.exit(); +} + +// the missing var keyword is intentional +domain = require('domain'); + +// should not throw a 'TypeError: undefined is not a function' exception +crypto.randomBytes(8); +crypto.randomBytes(8, function() {}); +crypto.pseudoRandomBytes(8); +crypto.pseudoRandomBytes(8, function() {}); From 7d0543c128839523e088f3ef3aeec88ee884b4e4 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 3 Sep 2012 23:15:30 +0200 Subject: [PATCH 14/16] crypto: make pbkdf2() compatible with domains --- src/node_crypto.cc | 17 ++++++++--------- test/simple/test-domain-crypto.js | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index dc5da802bb..50f0b42d1f 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4201,7 +4201,7 @@ struct pbkdf2_req { size_t iter; char* key; size_t keylen; - Persistent callback; + Persistent obj; }; void @@ -4236,16 +4236,13 @@ EIO_PBKDF2After(uv_work_t* req) { argv[1] = Local::New(Undefined()); } - // XXX There should be an object connected to this that - // we can attach a domain onto. - MakeCallback(Context::GetCurrent()->Global(), - request->callback, - ARRAY_SIZE(argv), argv); + MakeCallback(request->obj, "ondone", ARRAY_SIZE(argv), argv); delete[] request->pass; delete[] request->salt; delete[] request->key; - request->callback.Dispose(); + request->obj.Dispose(); + request->obj.Clear(); delete request; } @@ -4267,6 +4264,7 @@ PBKDF2(const Arguments& args) { Local callback; pbkdf2_req* request = NULL; uv_work_t* req = NULL; + Persistent obj; if (args.Length() != 5) { type_error = "Bad parameter"; @@ -4324,7 +4322,8 @@ PBKDF2(const Arguments& args) { goto err; } - callback = Local::Cast(args[4]); + obj = Persistent::New(Object::New()); + obj->Set(String::New("ondone"), args[4]); request = new pbkdf2_req; request->err = 0; @@ -4335,7 +4334,7 @@ PBKDF2(const Arguments& args) { request->iter = iter; request->key = key; request->keylen = keylen; - request->callback = Persistent::New(callback); + request->obj = obj; req = new uv_work_t(); req->data = request; diff --git a/test/simple/test-domain-crypto.js b/test/simple/test-domain-crypto.js index 532a8b09d3..66e9628804 100644 --- a/test/simple/test-domain-crypto.js +++ b/test/simple/test-domain-crypto.js @@ -34,3 +34,4 @@ crypto.randomBytes(8); crypto.randomBytes(8, function() {}); crypto.pseudoRandomBytes(8); crypto.pseudoRandomBytes(8, function() {}); +crypto.pbkdf2('password', 'salt', 8, 8, function() {}); From 7dfa587d18c9d55cf2625c138250ef02c464d911 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 3 Sep 2012 23:26:19 +0200 Subject: [PATCH 15/16] crypto, tls: make setSNICallback() compatible with domains --- src/node_crypto.cc | 23 ++++++++++------------- src/node_crypto.h | 4 ++-- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 50f0b42d1f..0d681bb81f 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -938,23 +938,20 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) { } p->servername_ = Persistent::New(String::New(servername)); - // Call sniCallback_ and use it's return value as context - if (!p->sniCallback_.IsEmpty()) { + // Call the SNI callback and use its return value as context + if (!p->sniObject_.IsEmpty()) { if (!p->sniContext_.IsEmpty()) { p->sniContext_.Dispose(); } // Get callback init args Local argv[1] = {*p->servername_}; - Local callback = *p->sniCallback_; // Call it - // - // XXX There should be an object connected to this that - // we can attach a domain onto. - Local ret; - ret = Local::New(MakeCallback(Context::GetCurrent()->Global(), - callback, ARRAY_SIZE(argv), argv)); + Local ret = Local::New(MakeCallback(p->sniObject_, + "onselect", + ARRAY_SIZE(argv), + argv)); // If ret is SecureContext if (secure_context_constructor->HasInstance(ret)) { @@ -1774,11 +1771,11 @@ Handle Connection::SetSNICallback(const Arguments& args) { } // Release old handle - if (!ss->sniCallback_.IsEmpty()) { - ss->sniCallback_.Dispose(); + if (!ss->sniObject_.IsEmpty()) { + ss->sniObject_.Dispose(); } - ss->sniCallback_ = Persistent::New( - Local::Cast(args[0])); + ss->sniObject_ = Persistent::New(Object::New()); + ss->sniObject_->Set(String::New("onselect"), args[0]); return True(); } diff --git a/src/node_crypto.h b/src/node_crypto.h index 1ee23c8a74..fe433596ac 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -110,7 +110,7 @@ class Connection : ObjectWrap { #endif #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - v8::Persistent sniCallback_; + v8::Persistent sniObject_; v8::Persistent sniContext_; v8::Persistent servername_; #endif @@ -185,7 +185,7 @@ class Connection : ObjectWrap { #endif #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - if (!sniCallback_.IsEmpty()) sniCallback_.Dispose(); + if (!sniObject_.IsEmpty()) sniObject_.Dispose(); if (!sniContext_.IsEmpty()) sniContext_.Dispose(); if (!servername_.IsEmpty()) servername_.Dispose(); #endif From 9f57e422cf15fbd1abdaa7795d373058ea9ee133 Mon Sep 17 00:00:00 2001 From: Atsuya Takagi Date: Mon, 3 Sep 2012 03:09:50 -0700 Subject: [PATCH 16/16] doc: fix typo in api/cluster --- doc/api/cluster.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/cluster.markdown b/doc/api/cluster.markdown index fa96d488d6..aa59acbf48 100644 --- a/doc/api/cluster.markdown +++ b/doc/api/cluster.markdown @@ -357,7 +357,7 @@ the worker finally die. Because there might be long living connections, it is useful to implement a timeout. This example ask the worker to disconnect and after 2 seconds it will destroy the -server. An alternative wound be to execute `worker.destroy()` after 2 seconds, but +server. An alternative would be to execute `worker.destroy()` after 2 seconds, but that would normally not allow the worker to do any cleanup if needed. if (cluster.isMaster) {