As documented in #3042 and in [1], the existing vm implementation has
many problems. All of these are solved by @brianmcd's [contextify][2]
package. This commit uses contextify as a conceptual base and its code
core to overhaul the vm module and fix its many edge cases and caveats.
Functionally, this fixes#3042. In particular:
- A context is now indistinguishable from the object it is based on
(the "sandbox"). A context is simply a sandbox that has been marked
by the vm module, via `vm.createContext`, with special internal
information that allows scripts to be run inside of it.
- Consequently, items added to the context from anywhere are
immediately visible to all code that can access that context, both
inside and outside the virtual machine.
This commit also smooths over the API very slightly:
- Parameter defaults are now uniformly triggered via `undefined`, per
ES6 semantics and previous discussion at [3].
- Several undocumented and problematic features have been removed, e.g.
the conflation of `vm.Script` with `vm` itself, and the fact that
`Script` instances also had all static `vm` methods. The API is now
exactly as documented (although arguably the existence of the
`vm.Script` export is not yet documented, just the `Script` class
itself).
In terms of implementation, this replaces node_script.cc with
node_contextify.cc, which is derived originally from [4] (see [5]) but
has since undergone extensive modifications and iterations to expose
the most useful C++ API and use the coding conventions and utilities of
Node core.
The bindings exposed by `process.binding('contextify')`
(node_contextify.cc) replace those formerly exposed by
`process.binding('evals')` (node_script.cc). They are:
- ContextifyScript(code, [filename]), with methods:
- runInThisContext()
- runInContext(sandbox, [timeout])
- makeContext(sandbox)
From this, the vm.js file builds the entire documented vm module API.
node.js and module.js were modified to use this new native binding, or
the vm module itself where possible. This introduces an extra line or
two into the stack traces of module compilation (and thus into most
stack traces), explaining the changed tests.
The tests were also updated slightly, with all vm-related simple tests
consolidated as test/simple/test-vm-* (some of them were formerly
test/simple/test-script-*). At the same time they switched from
`common.debug` to `console.error` and were updated to use
`assert.throws` instead of rolling their own error-testing methods.
New tests were also added, of course, demonstrating the new
capabilities and fixes.
[1]: http://nodejs.org/docs/v0.10.16/api/vm.html#vm_caveats
[2]: https://github.com/brianmcd/contextify
[3]: https://github.com/joyent/node/issues/5323#issuecomment-20250726
[4]: bf123f3ef9/src/contextify.cc
[5]: https://gist.github.com/domenic/6068120
* uv: Upgrade v0.10.14
* http_parser: Do not accept PUN/GEM methods as PUT/GET (Chris Dickinson)
* tls: fix assertion when ssl is destroyed at read (Fedor Indutny)
* stream: Throw on 'error' if listeners removed (isaacs)
* dgram: fix assertion on bad send() arguments (Ben Noordhuis)
* readline: pause stdin before turning off terminal raw mode (Daniel Chatfield)
`maybeInitFinished()` can emit the 'secure' event which
in turn destroys the connection in case of authentication
failure and sets `this.pair.ssl` to `null`.
If such condition appeared after non-empty read - loop will continue
and `clearOut` will be called on `null` object instead of
`crypto::Connection` instance. Resulting in the following assertion:
ERROR: Error: Hostname/IP doesn't match certificate's altnames
Assertion failed: handle->InternalFieldCount() > 0
fix#5756
The C++ API has been changed so the passed length is the byte size of
the data, not the length of the array.
This was done so users need to explicitly define how much memory they
want allocated.
`dns.lookup` defaults to selecting IPv4 record even if IPv6 is available
for the desired zone. Generally, this approach works, but if IPv4
address is unavailable - there'll be no other way to opt-out and connect using
IPv6 address than calling `dns.lookup` and passing it to `.connect()`
directly.
This commit adds `family` option to `net.connect` method to figure out
this issue.
It only fails once in about 1000 times, but that's too many.
It's timing dependent, and the main behavior is covered by the other
assertions in the test anyway.
This change is 100% backwards compatible.
This change will make using `EventEmitter` slightly simpler / nicer and
adheres to the best practice set forth by substack.
```js
var EventEmitter = require("events")
var emitter = new EventEmitter()
```
The only difference is that we now have to set `EventEmitter` as a
property of `EventEmitter` for backwards compatibility like we do with
[`Stream`][1]
We have also set the `usingDomains` property on the `EventEmitter`
constructor itself because that aligns with it's current usage of
`require("events").usingDomains = true`
There are other internals that would benefit from this change as well
like `StringDecoder`
This allows automatically-inserted headers to be removed permanently by
calling OutgoingMessage.removeHeader() on them, as if they were normal
headers.
In this situation:
writable.on('error', handler);
readable.pipe(writable);
writable.removeListener('error', handler);
writable.emit('error', new Error('boom'));
there is actually no error handler, but it doesn't throw, because of the
fix for stream.once('error', handler), in 23d92ec.
Note that simply reverting that change is not valid either, because
otherwise this will emit twice, being handled the first time, and then
throwing the second:
writable.once('error', handler);
readable.pipe(writable);
writable.emit('error', new Error('boom'));
Fix this with a horrible hack to make the stream pipe onerror handler
added before any other userland handlers, so that our handler is not
affected by adding or removing any userland handlers.
Closes#6007.
Commit 03e008d introduced src/tls_wrap.cc and src/tls_wrap.h but
said files copied on the order of 1 kLoC from src/node_crypto.cc
and src/node_crypto.h. This commit undoes some of the duplication.
Fixes#6024.
Add range checks for the offset, length and port arguments to
dgram.Socket#send(). Fixes the following assertion:
node: ../../src/udp_wrap.cc:264: static v8::Handle<v8::Value>
node::UDPWrap::DoSend(const v8::Arguments&, int): Assertion
`offset < Buffer::Length(buffer_obj)' failed.
And:
node: ../../src/udp_wrap.cc:265: static v8::Handle<v8::Value>
node::UDPWrap::DoSend(const v8::Arguments&, int): Assertion
`length <= Buffer::Length(buffer_obj) - offset' failed.
Interestingly enough, a negative port number was accepted until now but
silently ignored. (In other words, it would send the datagram to a
random port.)
This commit exposed a bug in the simple/test-dgram-close test which
has also been fixed.
This is a back-port of commit 41ec6d0 from the master branch.
Fixes#6025.
On windows, libuv will immediately make a `ReadConsole` call (in the
thread pool) when a 'flowing' `uv_tty_t` handle is switched to
line-buffered mode. That causes an immediate issue for some users,
since libuv can't cancel the `ReadConsole` operation on Windows 8 /
Server 2012 and up if the program switches back to raw mode later.
But even if this will be fixed in libuv at some point, it's better to
avoid the overhead of starting work in the thread pool and immediately
cancelling it afther that.
See also f34f1e3, where the same change is made for the opposite
flow, e.g. move `resume()` after `_setRawMode(true)`.
Fixes#5927
This is a backport of dfb0461 (see #5930) to the v0.10 branch.
On windows, libuv will immediately make a `ReadConsole` call (in the
thread pool) when a 'flowing' `uv_tty_t` handle is switched to
line-buffered mode. That causes an immediate issue for some users,
since libuv can't cancel the `ReadConsole` operation on Windows 8 /
Server 2012 and up if the program switches back to raw mode later.
But even if this will be fixed in libuv at some point, it's better to
avoid the overhead of starting work in the thread pool and immediately
cancelling it afther that.
See also f34f1e3, where the same change is made for the opposite
flow, e.g. move `resume()` after `_setRawMode(true)`.
Fixes#5927Closes#5930
RandomBytes() allocated memory with new[] which was then handed off to
Buffer::Use() which eventually releases it again with free().
Mixing the two is technically a violation of the spec and besides, it's
generally frowned upon.