Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release Proposal: v3.1.0 #2347

Merged
merged 20 commits into from
Aug 19, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,74 @@
# io.js ChangeLog

## 2015-08-18, Version 3.1.0, @Fishrock123

### Notable changes

* **buffer**: Fixed a couple large memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352).
* **crypto**:
- Fixed a couple of minor memory leaks (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375).
- Signing now checks for OpenSSL errors (P.S.V.R) [#2342](https://github.com/nodejs/node/pull/2342). **Note that this may expose previously hidden errors in user code.**
* **intl**: Intl support using small-icu is now enabled by default in builds (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264).
- [`String#normalize()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) can now be used for unicode normalization.
- The [`Intl`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl) object and various `String` and `Number` methods are present, but only support the English locale.
- For support of all locales, node must be built with [full-icu](https://github.com/nodejs/node#build-with-full-icu-support-all-locales-supported-by-icu).
* **tls**: Fixed tls throughput being much lower after an incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381).
* **tools**: The v8 tick processor now comes bundled with node (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090).
- This can be used by producing performance profiling output by running node with `--perf`, then running your appropriate platform's script on the output as found in [tools/v8-prof](https://github.com/nodejs/node/tree/master/tools/v8-prof).
* **util**: `util.inspect(obj)` now prints the constructor name of the object if there is one (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935).

### Known issues

See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues.

* Possible remaining post-3.0.0 buffer memory leak(s), details at [#2308](https://github.com/nodejs/node/issues/2308). Mostly fixed in [2781333...8841947](https://github.com/nodejs/node/compare/27813339cf713275fa7bbf2ae497d13b66aa78ce...88419479ccb6384473339f09e5c55f234f4ee194) - [#2352](https://github.com/nodejs/node/pull/2352), and also [6fff0f7...a40ae51](https://github.com/nodejs/node/compare/6fff0f73dc371153507d96ecd5f88c1ddc7780c9...a40ae513bb99ec3f85ea5b864a366bc7552d61f0) - [#2375](https://github.com/nodejs/node/pull/2375).
* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264).
* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690)
* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760).
* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894)
* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435).

### Commits

* [[`3645dc62ed`](https://github.com/nodejs/node/commit/3645dc62ed)] - **build**: work around VS2015 issue in ICU <56 (Steven R. Loomis) [#2283](https://github.com/nodejs/node/pull/2283)
* [[`1f12e03266`](https://github.com/nodejs/node/commit/1f12e03266)] - **(SEMVER-MINOR)** **build**: intl: converge from joyent/node (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264)
* [[`071640abdd`](https://github.com/nodejs/node/commit/071640abdd)] - **build**: Intl: bump ICU4C from 54 to 55 (Steven R. Loomis) [#2293](https://github.com/nodejs/node/pull/2293)
* [[`07a88b0c8b`](https://github.com/nodejs/node/commit/07a88b0c8b)] - **build**: update manifest to include Windows 10 (Lucien Greathouse) [#2332](https://github.com/nodejs/io.js/pull/2332)
* [[`0bb099f444`](https://github.com/nodejs/node/commit/0bb099f444)] - **build**: expand ~ in install prefix early (Ben Noordhuis) [#2307](https://github.com/nodejs/io.js/pull/2307)
* [[`7fe6dd8f5d`](https://github.com/nodejs/node/commit/7fe6dd8f5d)] - **crypto**: check for OpenSSL errors when signing (P.S.V.R) [#2342](https://github.com/nodejs/node/pull/2342)
* [[`605f6ee904`](https://github.com/nodejs/node/commit/605f6ee904)] - **crypto**: fix memory leak in PBKDF2Request (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`ba6eb8af12`](https://github.com/nodejs/node/commit/ba6eb8af12)] - **crypto**: fix memory leak in ECDH::SetPrivateKey (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`6a16368611`](https://github.com/nodejs/node/commit/6a16368611)] - **crypto**: fix memory leak in PublicKeyCipher::Cipher (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`a760a87803`](https://github.com/nodejs/node/commit/a760a87803)] - **crypto**: fix memory leak in SafeX509ExtPrint (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`f45487cd6e`](https://github.com/nodejs/node/commit/f45487cd6e)] - **crypto**: fix memory leak in SetDHParam (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`2ff183dd86`](https://github.com/nodejs/node/commit/2ff183dd86)] - **doc**: Update FIPS instructions in README.md (Michael Dawson) [#2278](https://github.com/nodejs/node/pull/2278)
* [[`6483bc2e8f`](https://github.com/nodejs/node/commit/6483bc2e8f)] - **doc**: clarify options for fs.watchFile() (Rich Trott) [#2425](https://github.com/nodejs/node/pull/2425)
* [[`e76822f454`](https://github.com/nodejs/node/commit/e76822f454)] - **doc**: multiple documentation updates cherry picked from v0.12 (James M Snell) [#2302](https://github.com/nodejs/io.js/pull/2302)
* [[`1738c9680b`](https://github.com/nodejs/node/commit/1738c9680b)] - **net**: ensure Socket reported address is current (Ryan Graham) [#2095](https://github.com/nodejs/io.js/pull/2095)
* [[`844d3f0e3e`](https://github.com/nodejs/node/commit/844d3f0e3e)] - **path**: use '===' instead of '==' for comparison (Sam Stites) [#2388](https://github.com/nodejs/node/pull/2388)
* [[`7118b8a882`](https://github.com/nodejs/node/commit/7118b8a882)] - **path**: remove dead code in favor of unit tests (Nathan Woltman) [#2282](https://github.com/nodejs/io.js/pull/2282)
* [[`34f2cfa806`](https://github.com/nodejs/node/commit/34f2cfa806)] - **src**: better error message on failed Buffer malloc (Karl Skomski) [#2422](https://github.com/nodejs/node/pull/2422)
* [[`b196c1da3c`](https://github.com/nodejs/node/commit/b196c1da3c)] - **src**: fix memory leak in DLOpen (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375)
* [[`d1307b2995`](https://github.com/nodejs/node/commit/d1307b2995)] - **src**: don't use fopen() in require() fast path (Ben Noordhuis) [#2377](https://github.com/nodejs/node/pull/2377)
* [[`455ec570d1`](https://github.com/nodejs/node/commit/455ec570d1)] - **src**: rename Buffer::Use() to Buffer::New() (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352)
* [[`fd63e1ce2b`](https://github.com/nodejs/node/commit/fd63e1ce2b)] - **src**: introduce internal Buffer::Copy() function (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352)
* [[`5586ceca13`](https://github.com/nodejs/node/commit/5586ceca13)] - **src**: move internal functions out of node_buffer.h (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352)
* [[`bff9bcddb6`](https://github.com/nodejs/node/commit/bff9bcddb6)] - **src**: plug memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352)
* [[`ccf12df4f3`](https://github.com/nodejs/node/commit/ccf12df4f3)] - **(SEMVER-MINOR)** **src**: add total_available_size to v8 statistics (Roman Klauke) [#2348](https://github.com/nodejs/io.js/pull/2348)
* [[`194eeb841b`](https://github.com/nodejs/node/commit/194eeb841b)] - **test**: drop Isolate::GetCurrent() from addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427)
* [[`46cdb2f6e2`](https://github.com/nodejs/node/commit/46cdb2f6e2)] - **test**: lint addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427)
* [[`850c794882`](https://github.com/nodejs/node/commit/850c794882)] - **test**: refactor test-fs-watchfile.js (Rich Trott) [#2393](https://github.com/nodejs/node/pull/2393)
* [[`a3160c0a33`](https://github.com/nodejs/node/commit/a3160c0a33)] - **test**: correct spelling of 'childProcess' (muddletoes) [#2389](https://github.com/nodejs/node/pull/2389)
* [[`e51f90d747`](https://github.com/nodejs/node/commit/e51f90d747)] - **test**: option to run a subset of tests (João Reis) [#2260](https://github.com/nodejs/io.js/pull/2260)
* [[`cc46d3bca3`](https://github.com/nodejs/node/commit/cc46d3bca3)] - **test**: clarify dropMembership() call (Rich Trott) [#2062](https://github.com/nodejs/io.js/pull/2062)
* [[`0ee4df9c7a`](https://github.com/nodejs/node/commit/0ee4df9c7a)] - **test**: make listen-fd-cluster/server more robust (Sam Roberts) [#1944](https://github.com/nodejs/io.js/pull/1944)
* [[`cf9ba81398`](https://github.com/nodejs/node/commit/cf9ba81398)] - **test**: address timing issues in simple http tests (Gireesh Punathil) [#2294](https://github.com/nodejs/io.js/pull/2294)
* [[`cbb75c4f86`](https://github.com/nodejs/node/commit/cbb75c4f86)] - **tls**: fix throughput issues after incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381)
* [[`94b765f409`](https://github.com/nodejs/node/commit/94b765f409)] - **tls**: fix check for reused session (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312)
* [[`e83a41ad65`](https://github.com/nodejs/node/commit/e83a41ad65)] - **tls**: introduce internal `onticketkeycallback` (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312)
* [[`fb0f5d733f`](https://github.com/nodejs/node/commit/fb0f5d733f)] - **(SEMVER-MINOR)** **tools**: run the tick processor without building v8 (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090)
* [[`7606bdb897`](https://github.com/nodejs/node/commit/7606bdb897)] - **(SEMVER-MINOR)** **util**: display constructor when inspecting objects (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935)

## 2015-08-04, Version 3.0.0, @rvagg

### Notable changes
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -483,8 +483,19 @@ CPPLINT_EXCLUDE += src/node_win32_perfctr_provider.cc
CPPLINT_EXCLUDE += src/queue.h
CPPLINT_EXCLUDE += src/tree.h
CPPLINT_EXCLUDE += src/v8abbr.h

CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard src/*.cc src/*.h src/*.c tools/icu/*.h tools/icu/*.cc deps/debugger-agent/include/* deps/debugger-agent/src/*))
CPPLINT_EXCLUDE += $(wildcard test/addons/doc-*/*.cc test/addons/doc-*/*.h)

CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \
deps/debugger-agent/include/* \
deps/debugger-agent/src/* \
src/*.c \
src/*.cc \
src/*.h \
test/addons/*/*.cc \
test/addons/*/*.h \
tools/icu/*.cc \
tools/icu/*.h \
))

cpplint:
@$(PYTHON) tools/cpplint.py $(CPPLINT_FILES)
50 changes: 38 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -269,20 +269,46 @@ NOTE: Windows is not yet supported
It is possible to build io.js with
[OpenSSL FIPS module](https://www.openssl.org/docs/fips/fipsnotes.html).

**Note** that building in this way does **not** allow you to
claim that the runtime is FIPS 140-2 validated. Instead you
can indicate that the runtime uses a validated module. See
the [security policy]
(http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf)
page 60 for more details. In addition, the validation for
the underlying module is only valid if it is deployed in
accordance with its [security policy]
(http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf).
If you need FIPS validated cryptography it is recommended that you
read both the [security policy]
(http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf)
and [user guide] (https://openssl.org/docs/fips/UserGuide-2.0.pdf).

Instructions:

1. Download and verify `openssl-fips-x.x.x.tar.gz` from
https://www.openssl.org/source/
2. Extract source to `openssl-fips` folder
3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out``
(NOTE: On OS X, you may want to run
``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to
build x64-mode io.js)
4. `make -j && make install`
5. Get into io.js checkout folder
6. `./configure --openssl-fips=/path/to/openssl-fips/out`
7. Build io.js with `make -j`
8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`)
1. Obtain a copy of openssl-fips-x.x.x.tar.gz.
To comply with the security policy you must ensure the path
through which you get the file complies with the requirements
for a "secure intallation" as described in section 6.6 in
the [user guide] (https://openssl.org/docs/fips/UserGuide-2.0.pdf).
For evaluation/experimentation you can simply download and verify
`openssl-fips-x.x.x.tar.gz` from https://www.openssl.org/source/
2. Extract source to `openssl-fips` folder and `cd openssl-fips`
3. `./config`
4. `make`
5. `make install`
(NOTE: to comply with the security policy you must use the exact
commands in steps 3-5 without any additional options as per
Appendix A in the [security policy]
(http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp1747.pdf).
The only exception is that `./config no-asm` can be
used in place of `./config` )
6. Get into io.js checkout folder
7. `./configure --openssl-fips=/path/to/openssl-fips/installdir`
For example on ubuntu 12 the installation directory was
/usr/local/ssl/fips-2.0
8. Build io.js with `make -j`
9. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`)


## Resources for Newcomers

11 changes: 6 additions & 5 deletions doc/api/fs.markdown
Original file line number Diff line number Diff line change
@@ -557,11 +557,12 @@ The synchronous version of `fs.appendFile`. Returns `undefined`.
Watch for changes on `filename`. The callback `listener` will be called each
time the file is accessed.

The second argument is optional. The `options` if provided should be an object
containing two members a boolean, `persistent`, and `interval`. `persistent`
indicates whether the process should continue to run as long as files are
being watched. `interval` indicates how often the target should be polled,
in milliseconds. The default is `{ persistent: true, interval: 5007 }`.
The `options` argument may be omitted. If provided, it should be an object. The
`options` object may contain a boolean named `persistent` that indicates
whether the process should continue to run as long as files are being watched.
The `options` object may specify an `interval` property indicating how often the
target should be polled in milliseconds. The default is
`{ persistent: true, interval: 5007 }`.

The `listener` gets two arguments the current stat object and the previous
stat object:
2 changes: 1 addition & 1 deletion lib/path.js
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ win32.relative = function(from, to) {
}
}

if (samePartsLength == 0) {
if (samePartsLength === 0) {
return to;
}

5 changes: 5 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
@@ -2124,6 +2124,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {

if (is_dlopen_error) {
Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib));
uv_dlclose(&lib);
#ifdef _WIN32
// Windows needs to add the filename into the error message
errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate()));
@@ -2133,10 +2134,12 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
}

if (mp == nullptr) {
uv_dlclose(&lib);
env->ThrowError("Module did not self-register.");
return;
}
if (mp->nm_version != NODE_MODULE_VERSION) {
uv_dlclose(&lib);
char errmsg[1024];
snprintf(errmsg,
sizeof(errmsg),
@@ -2146,6 +2149,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
return;
}
if (mp->nm_flags & NM_F_BUILTIN) {
uv_dlclose(&lib);
env->ThrowError("Built-in module self-registered.");
return;
}
@@ -2162,6 +2166,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
} else if (mp->nm_register_func != nullptr) {
mp->nm_register_func(exports, module, mp->nm_priv);
} else {
uv_dlclose(&lib);
env->ThrowError("Module has no declared entry point.");
return;
}
6 changes: 4 additions & 2 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
@@ -408,8 +408,10 @@ void Create(const FunctionCallbackInfo<Value>& args) {
void* data;
if (length > 0) {
data = malloc(length);
if (data == nullptr)
return env->ThrowRangeError("invalid Buffer length");
if (data == nullptr) {
return env->ThrowRangeError(
"Buffer allocation failed - process out of memory");
}
} else {
data = nullptr;
}
37 changes: 32 additions & 5 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
@@ -805,10 +805,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
return;

const int keylen = BN_num_bits(dh->p);
if (keylen < 1024)
if (keylen < 1024) {
DH_free(dh);
return env->ThrowError("DH parameter is less than 1024 bits");
else if (keylen < 2048)
} else if (keylen < 2048) {
fprintf(stderr, "WARNING: DH parameter is less than 2048 bits\n");
}

SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_DH_USE);
int r = SSL_CTX_set_tmp_dh(sc->ctx_, dh);
@@ -1295,6 +1297,7 @@ static bool SafeX509ExtPrint(BIO* out, X509_EXTENSION* ext) {
if (nval == NULL)
return false;
X509V3_EXT_val_prn(out, nval, 0, 0);
sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
}
}
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
@@ -3580,7 +3583,11 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
nullptr,
CryptoPemCallback,
const_cast<char*>(passphrase));
if (pkey == nullptr)

// Errors might be injected into OpenSSL's error stack
// without `pkey` being set to nullptr;
// cf. the test of `test_bad_rsa_privkey.pem` for an example.
if (pkey == nullptr || 0 != ERR_peek_error())
goto exit;

if (EVP_SignFinal(&mdctx_, *sig, sig_len, pkey))
@@ -3628,6 +3635,9 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
md_len = 8192; // Maximum key size is 8192 bits
md_value = new unsigned char[md_len];

ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.

Error err = sign->SignFinal(
buf,
buf_len,
@@ -3928,6 +3938,8 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
fatal = false;

exit:
if (x509 != nullptr)
X509_free(x509);
if (pkey != nullptr)
EVP_PKEY_free(pkey);
if (bp != nullptr)
@@ -3960,6 +3972,9 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
unsigned char* out_value = nullptr;
size_t out_len = 0;

ClearErrorOnReturn clear_error_on_return;
(void) &clear_error_on_return; // Silence compiler warning.

bool r = Cipher<operation, EVP_PKEY_cipher_init, EVP_PKEY_cipher>(
kbuf,
klen,
@@ -4563,8 +4578,12 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
if (priv == nullptr)
return env->ThrowError("Failed to convert Buffer to BN");

if (!EC_KEY_set_private_key(ecdh->key_, priv))
int result = EC_KEY_set_private_key(ecdh->key_, priv);
BN_free(priv);

if (!result) {
return env->ThrowError("Failed to convert BN to a private key");
}
}


@@ -4613,6 +4632,7 @@ class PBKDF2Request : public AsyncWrap {
}

~PBKDF2Request() override {
release();
persistent().Reset();
}

@@ -4654,10 +4674,15 @@ class PBKDF2Request : public AsyncWrap {

inline void release() {
free(pass_);
pass_ = nullptr;
passlen_ = 0;

free(salt_);
salt_ = nullptr;
saltlen_ = 0;

free(key_);
key_ = nullptr;
keylen_ = 0;
}

@@ -4728,7 +4753,6 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
Local<Value> argv[2];
EIO_PBKDF2After(req, argv);
req->MakeCallback(env->ondone_string(), ARRAY_SIZE(argv), argv);
req->release();
delete req;
}

@@ -4839,6 +4863,9 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
Local<Value> argv[2];
EIO_PBKDF2(req);
EIO_PBKDF2After(req, argv);

delete req;

if (argv[0]->IsObject())
env->isolate()->ThrowException(argv[0]);
else
31 changes: 24 additions & 7 deletions src/node_file.cc
Original file line number Diff line number Diff line change
@@ -442,31 +442,48 @@ Local<Value> BuildStatsObject(Environment* env, const uv_stat_t* s) {
// comes from not creating Error objects on failure.
static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
uv_loop_t* loop = env->event_loop();

CHECK(args[0]->IsString());
node::Utf8Value path(env->isolate(), args[0]);

FILE* const stream = fopen(*path, "rb");
if (stream == nullptr) {
uv_fs_t open_req;
const int fd = uv_fs_open(loop, &open_req, *path, O_RDONLY, 0, nullptr);
uv_fs_req_cleanup(&open_req);

if (fd < 0) {
return;
}

std::vector<char> chars;
while (!ferror(stream)) {
int64_t offset = 0;
for (;;) {
const size_t kBlockSize = 32 << 10;
const size_t start = chars.size();
chars.resize(start + kBlockSize);
const size_t numchars = fread(&chars[start], 1, kBlockSize, stream);
if (numchars < kBlockSize) {

uv_buf_t buf;
buf.base = &chars[start];
buf.len = kBlockSize;

uv_fs_t read_req;
const ssize_t numchars =
uv_fs_read(loop, &read_req, fd, &buf, 1, offset, nullptr);
uv_fs_req_cleanup(&read_req);

CHECK_GE(numchars, 0);
if (static_cast<size_t>(numchars) < kBlockSize) {
chars.resize(start + numchars);
}
if (numchars == 0) {
break;
}
offset += numchars;
}

CHECK_EQ(false, ferror(stream));
CHECK_EQ(0, fclose(stream));
uv_fs_t close_req;
CHECK_EQ(0, uv_fs_close(loop, &close_req, fd, nullptr));
uv_fs_req_cleanup(&close_req);

size_t start = 0;
if (chars.size() >= 3 && 0 == memcmp(&chars[0], "\xEF\xBB\xBF", 3)) {
2 changes: 1 addition & 1 deletion src/node_version.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
#define SRC_NODE_VERSION_H_

#define NODE_MAJOR_VERSION 3
#define NODE_MINOR_VERSION 0
#define NODE_MINOR_VERSION 1
#define NODE_PATCH_VERSION 1

#define NODE_VERSION_IS_RELEASE 0
2 changes: 1 addition & 1 deletion src/tls_wrap.h
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ class TLSWrap : public crypto::SSLWrap<TLSWrap>,
size_t self_size() const override { return sizeof(*this); }

protected:
static const int kClearOutChunkSize = 1024;
static const int kClearOutChunkSize = 16384;

// Maximum number of bytes for hello parser
static const int kMaxHelloLength = 16384;
36 changes: 18 additions & 18 deletions test/addons/async-hello-world/binding.cc
Original file line number Diff line number Diff line change
@@ -3,57 +3,57 @@
#include <v8.h>
#include <uv.h>

using namespace v8;
using namespace node;

struct async_req {
uv_work_t req;
int input;
int output;
Persistent<Function> callback;
v8::Isolate* isolate;
v8::Persistent<v8::Function> callback;
};

void DoAsync(uv_work_t* r) {
async_req* req = reinterpret_cast<async_req*>(r->data);
sleep(1); // simulate CPU intensive process...
sleep(1); // Simulate CPU intensive process...
req->output = req->input * 2;
}

void AfterAsync(uv_work_t* r) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
async_req* req = reinterpret_cast<async_req*>(r->data);
v8::Isolate* isolate = req->isolate;
v8::HandleScope scope(isolate);

Handle<Value> argv[2] = {
Null(isolate),
Integer::New(isolate, req->output)
v8::Handle<v8::Value> argv[2] = {
v8::Null(isolate),
v8::Integer::New(isolate, req->output)
};

TryCatch try_catch;
v8::TryCatch try_catch(isolate);

Local<Function> callback = Local<Function>::New(isolate, req->callback);
v8::Local<v8::Function> callback =
v8::Local<v8::Function>::New(isolate, req->callback);
callback->Call(isolate->GetCurrentContext()->Global(), 2, argv);

// cleanup
req->callback.Reset();
delete req;

if (try_catch.HasCaught()) {
FatalException(isolate, try_catch);
node::FatalException(isolate, try_catch);
}
}

void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);

async_req* req = new async_req;
req->req.data = req;

req->input = args[0]->IntegerValue();
req->output = 0;
req->isolate = isolate;

Local<Function> callback = Local<Function>::Cast(args[1]);
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
req->callback.Reset(isolate, callback);

uv_queue_work(uv_default_loop(),
@@ -62,7 +62,7 @@ void Method(const FunctionCallbackInfo<Value>& args) {
(uv_after_work_cb)AfterAsync);
}

void init(Handle<Object> exports, Handle<Object> module) {
void init(v8::Handle<v8::Object> exports, v8::Handle<v8::Object> module) {
NODE_SET_METHOD(module, "exports", Method);
}

8 changes: 3 additions & 5 deletions test/addons/at-exit/binding.cc
Original file line number Diff line number Diff line change
@@ -16,12 +16,10 @@ static int at_exit_cb1_called = 0;
static int at_exit_cb2_called = 0;

static void at_exit_cb1(void* arg) {
// FIXME(bnoordhuis) Isolate::GetCurrent() is on its way out.
Isolate* isolate = Isolate::GetCurrent();
Isolate* isolate = static_cast<Isolate*>(arg);
HandleScope handle_scope(isolate);
assert(arg == 0);
Local<Object> obj = Object::New(isolate);
assert(!obj.IsEmpty()); // assert VM is still alive
assert(!obj.IsEmpty()); // Assert VM is still alive.
assert(obj->IsObject());
at_exit_cb1_called++;
}
@@ -37,7 +35,7 @@ static void sanity_check(void) {
}

void init(Handle<Object> target) {
AtExit(at_exit_cb1);
AtExit(at_exit_cb1, target->CreationContext()->GetIsolate());
AtExit(at_exit_cb2, cookie);
AtExit(at_exit_cb2, cookie);
atexit(sanity_check);
12 changes: 5 additions & 7 deletions test/addons/hello-world-function-export/binding.cc
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#include <node.h>
#include <v8.h>

using namespace v8;

void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world"));
}

void init(Handle<Object> exports, Handle<Object> module) {
void init(v8::Handle<v8::Object> exports, v8::Handle<v8::Object> module) {
NODE_SET_METHOD(module, "exports", Method);
}

12 changes: 5 additions & 7 deletions test/addons/hello-world/binding.cc
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#include <node.h>
#include <v8.h>

using namespace v8;

void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world"));
}

void init(Handle<Object> target) {
void init(v8::Handle<v8::Object> target) {
NODE_SET_METHOD(target, "hello", Method);
}

10 changes: 10 additions & 0 deletions test/fixtures/test_bad_rsa_privkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN RSA PRIVATE KEY-----
MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAz0ZHmXyxQSdWk6NF
GRotTax0O94iHv843su0mOynV9QLvlAwMrUk9k4+/SwyLu0eE3iYsYgXstXi3t2u
rDSIMwIDAQABAkAH4ag/Udp7m79TBdZOygwG9BPHYv7xJstGzYAkgHssf7Yd5ZuC
hpKtBvWdPXZaAFbwF8NSisMl98Q/9zgB/q5BAiEA5zXuwMnwt4hE2YqzBDRFB4g9
I+v+l1soy6x7Wdqo9esCIQDlf15qDb26uRDurBioE3IpZstWIIvLDdKqviZXKMs8
2QIgWeC5QvA9RtsOCJLGLCg1fUwUmFYwzZ1+Kk6OVMuPSqkCIDIWFSXyL8kzoKVm
O89axxyQCaqXWcsMDkEjVLzK82gpAiB7lzdDHr7MoMWwV2wC/heEFC2p0Rw4wg9j
1V8QbL0Q0A==
-----END RSA PRIVATE KEY-----
16 changes: 16 additions & 0 deletions test/parallel/test-crypto.js
Original file line number Diff line number Diff line change
@@ -124,5 +124,21 @@ assert.throws(function() {
crypto.createSign('RSA-SHA256').update('test').sign(priv);
}, /RSA_sign:digest too big for rsa key/);

assert.throws(function() {
// The correct header inside `test_bad_rsa_privkey.pem` should have been
// -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
// instead of
// -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----
// It is generated in this way:
// $ openssl genrsa -out mykey.pem 512;
// $ openssl pkcs8 -topk8 -inform PEM -outform PEM -in mykey.pem \
// -out private_key.pem -nocrypt;
// Then open private_key.pem and change its header and footer.
var sha1_privateKey = fs.readFileSync(common.fixturesDir +
'/test_bad_rsa_privkey.pem', 'ascii');
// this would inject errors onto OpenSSL's error stack
crypto.createSign('sha1').sign(sha1_privateKey);
}, /asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag/);

// Make sure memory isn't released before being returned
console.log(crypto.randomBytes(16));
21 changes: 4 additions & 17 deletions test/parallel/test-fs-watchfile.js
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@ const common = require('../common');
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const fixtures = path.join(__dirname, '..', 'fixtures');

// Basic usage tests.
assert.throws(function() {
@@ -19,7 +18,7 @@ assert.throws(function() {
fs.watchFile(new Object(), function() {});
}, /Path must be a string/);

const enoentFile = path.join(fixtures, 'non-existent-file');
const enoentFile = path.join(common.tmpDir, 'non-existent-file');
const expectedStatObject = new fs.Stats(
0, // dev
0, // mode
@@ -37,24 +36,13 @@ const expectedStatObject = new fs.Stats(
Date.UTC(1970, 0, 1, 0, 0, 0) // birthtime
);

function removeTestFile() {
try {
fs.unlinkSync(enoentFile);
} catch (ex) {
if (ex.code !== 'ENOENT') {
throw ex;
}
}
}

// Make sure that the file does not exist, when the test starts
removeTestFile();
common.refreshTmpDir();

// If the file initially didn't exist, and gets created at a later point of
// time, the callback should be invoked again with proper values in stat object
var fileExists = false;

fs.watchFile(enoentFile, common.mustCall(function(curr, prev) {
fs.watchFile(enoentFile, {interval: 0}, common.mustCall(function(curr, prev) {
if (!fileExists) {
// If the file does not exist, all the fields should be zero and the date
// fields should be UNIX EPOCH time
@@ -71,8 +59,7 @@ fs.watchFile(enoentFile, common.mustCall(function(curr, prev) {
// As the file just got created, previous ino value should be lesser than
// or equal to zero (non-existent file).
assert(prev.ino <= 0);
// Stop watching the file and delete it
// Stop watching the file
fs.unwatchFile(enoentFile);
removeTestFile();
}
}, 2));
16 changes: 16 additions & 0 deletions test/parallel/test-require-unicode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const fs = require('fs');
const path = require('path');

common.refreshTmpDir();

const dirname = path.join(common.tmpDir, '\u4e2d\u6587\u76ee\u5f55');
fs.mkdirSync(dirname);
fs.writeFileSync(path.join(dirname, 'file.js'), 'module.exports = 42;');
fs.writeFileSync(path.join(dirname, 'package.json'),
JSON.stringify({ name: 'test', main: 'file.js' }));
assert.equal(require(dirname), 42);
assert.equal(require(path.join(dirname, 'file.js')), 42);
45 changes: 45 additions & 0 deletions test/parallel/test-tick-processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';
var fs = require('fs');
var assert = require('assert');
var path = require('path');
var cp = require('child_process');
var common = require('../common');

common.refreshTmpDir();

process.chdir(common.tmpDir);
cp.execFileSync(process.execPath, ['-prof', '-pe',
'function foo(n) {' +
'require(\'vm\').runInDebugContext(\'Debug\');' +
'return n < 2 ? n : setImmediate(function() { foo(n-1) + foo(n-2);}); };' +
'setTimeout(function() { process.exit(0); }, 2000);' +
'foo(40);']);
var matches = fs.readdirSync(common.tmpDir).filter(function(file) {
return /^isolate-/.test(file);
});
if (matches.length != 1) {
assert.fail('There should be a single log file.');
}
var log = matches[0];
var processor =
path.join(common.testDir, '..', 'tools', 'v8-prof', getScriptName());
var out = cp.execSync(processor + ' ' + log, {encoding: 'utf8'});
assert(out.match(/LazyCompile.*foo/));
if (process.platform === 'win32' ||
process.platform === 'sunos' ||
process.platform === 'freebsd') {
console.log('1..0 # Skipped: C++ symbols are not mapped for this os.');
return;
}
assert(out.match(/RunInDebugContext/));

function getScriptName() {
switch (process.platform) {
case 'darwin':
return 'mac-tick-processor';
case 'win32':
return 'windows-tick-processor.bat';
default:
return 'linux-tick-processor';
}
}
4 changes: 2 additions & 2 deletions test/sequential/test-stdin-from-file.js
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
var common = require('../common');
var assert = require('assert');
var join = require('path').join;
var childProccess = require('child_process');
var childProcess = require('child_process');
var fs = require('fs');

var stdoutScript = join(common.fixturesDir, 'echo-close-check.js');
@@ -32,7 +32,7 @@ try {

fs.writeFileSync(tmpFile, string);

childProccess.exec(cmd, function(err, stdout, stderr) {
childProcess.exec(cmd, function(err, stdout, stderr) {
fs.unlinkSync(tmpFile);

if (err) throw err;
4 changes: 2 additions & 2 deletions test/sequential/test-stdout-to-file.js
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
var common = require('../common');
var assert = require('assert');
var path = require('path');
var childProccess = require('child_process');
var childProcess = require('child_process');
var fs = require('fs');

var scriptString = path.join(common.fixturesDir, 'print-chars.js');
@@ -26,7 +26,7 @@ function test(size, useBuffer, cb) {

common.print(size + ' chars to ' + tmpFile + '...');

childProccess.exec(cmd, function(err) {
childProcess.exec(cmd, function(err) {
if (err) throw err;

console.log('done!');
23 changes: 23 additions & 0 deletions tools/v8-prof/linux-tick-processor
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

umask 077
TEMP_SCRIPT_FILE="/tmp/node-tick-processor-input-script-$$"
tools_path=`cd $(dirname "$0");pwd`
v8_tools="$tools_path/../../deps/v8/tools"

cat "$tools_path/polyfill.js" "$v8_tools/splaytree.js" "$v8_tools/codemap.js" \
"$v8_tools/csvparser.js" "$v8_tools/consarray.js" \
"$v8_tools/profile.js" "$v8_tools/profile_view.js" \
"$v8_tools/logreader.js" "$v8_tools/tickprocessor.js" \
"$v8_tools/SourceMap.js" \
"$v8_tools/tickprocessor-driver.js" >> "$TEMP_SCRIPT_FILE"

NODE=${NODE:-node}

if [ ! -x "$NODE" ] && [ -x "$(dirname "$0")/../../iojs" ]; then
NODE="$(dirname "$0")/../../iojs"
fi

"$NODE" "$TEMP_SCRIPT_FILE" $@

rm -f "$TEMP_SCRIPT_FILE"
7 changes: 7 additions & 0 deletions tools/v8-prof/mac-tick-processor
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

# A wrapper script to call 'linux-tick-processor' with Mac-specific settings.

tools_path=`cd $(dirname "$0");pwd`
v8_tools="$tools_path/../../deps/v8/tools"
"$tools_path/linux-tick-processor" --mac --nm="$v8_tools/mac-nm" $@
92 changes: 92 additions & 0 deletions tools/v8-prof/polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Node polyfill
var fs = require('fs');
var os = {
system: function(name, args) {
if (process.platform === 'linux' && name === 'nm') {
// Filter out vdso and vsyscall entries.
var arg = args[args.length - 1];
if (arg === '[vdso]' ||
arg == '[vsyscall]' ||
/^[0-9a-f]+-[0-9a-f]+$/.test(arg)) {
return '';
}
}
return require('child_process').execFileSync(
name, args, {encoding: 'utf8'});
}
};
var print = console.log;
function read(fileName) {
return fs.readFileSync(fileName, 'utf8');
}
arguments = process.argv.slice(2);

// Polyfill "readline()".
var fd = fs.openSync(arguments[arguments.length - 1], 'r');
var buf = new Buffer(4096);
var dec = new (require('string_decoder').StringDecoder)('utf-8');
var line = '';
versionCheck();
function readline() {
while (true) {
var lineBreak = line.indexOf('\n');
if (lineBreak !== -1) {
var res = line.slice(0, lineBreak);
line = line.slice(lineBreak + 1);
return res;
}
var bytes = fs.readSync(fd, buf, 0, buf.length);
line += dec.write(buf.slice(0, bytes));
if (line.length === 0) {
return false;
}
}
}

function versionCheck() {
// v8-version looks like "v8-version,$major,$minor,$build,$patch,$candidate"
// whereas process.versions.v8 is either "$major.$minor.$build" or
// "$major.$minor.$build.$patch".
var firstLine = readline();
line = firstLine + '\n' + line;
firstLine = firstLine.split(',');
var curVer = process.versions.v8.split('.');
if (firstLine.length !== 6 && firstLine[0] !== 'v8-version') {
console.log('Unable to read v8-version from log file.');
return;
}
// Compare major, minor and build; ignore the patch and candidate fields.
for (var i = 0; i < 3; i++) {
if (curVer[i] !== firstLine[i + 1]) {
console.log('Testing v8 version different from logging version');
return;
}
}
}
19 changes: 19 additions & 0 deletions tools/v8-prof/windows-tick-processor.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@echo off
setlocal

SET tools_dir=%~dp0
SET v8_tools=%tools_dir%..\..\deps\v8\tools\

SET temp_script=%TEMP%\node-tick-processor-input-script

IF NOT DEFINED NODE (SET NODE=node.exe)
%NODE% --version 2> NUL
if %ERRORLEVEL%==9009 (SET NODE=%~dp0\..\..\Release\iojs.exe)


type %tools_dir%polyfill.js %v8_tools%splaytree.js %v8_tools%codemap.js^
%v8_tools%csvparser.js %v8_tools%consarray.js %v8_tools%profile.js^
%v8_tools%profile_view.js %v8_tools%logreader.js %v8_tools%SourceMap.js^
%v8_tools%tickprocessor.js %v8_tools%tickprocessor-driver.js >> %temp_script%
%NODE% %temp_script% --windows %*
del %temp_script%