diff --git a/.eslintrc b/.eslintrc index 2197bf35ccf7..8d9988acef7a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,6 +25,8 @@ rules: no-dupe-keys: 2 ## check duplicate switch-case no-duplicate-case: 2 + ## disallow superfluous semicolons + no-extra-semi: 2 ## disallow assignment of exceptional params no-ex-assign: 2 ## disallow unreachable code @@ -65,8 +67,10 @@ rules: eol-last: 2 ## no trailing spaces no-trailing-spaces: 2 - # require space after keywords, eg 'for (..)' + ## require space after keywords, eg 'for (..)' space-after-keywords: 2 + ## no leading/trailing spaces in parens + space-in-parens: [2, "never"] # ECMAScript 6 # list: http://eslint.org/docs/rules/#ecmascript-6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 314a2a66ac86..74f1bc53b6a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,89 @@ # Node.js ChangeLog +## 2016-01-20, Version 5.5.0 (Stable), @evanlucas + +### Notable Changes + +- **events**: make sure console functions exist (Dave) [#4479](https://github.com/nodejs/node/pull/4479) +- **fs**: add autoClose option to fs.createWriteStream (Saquib) [#3679](https://github.com/nodejs/node/pull/3679) +- **http**: improves expect header handling (Daniel Sellers) [#4501](https://github.com/nodejs/node/pull/4501) +- **node**: allow preload modules with -i (Evan Lucas) [#4696](https://github.com/nodejs/node/pull/4696) +- **v8,src**: expose statistics about heap spaces (`v8.getHeapSpaceStatistics()`) (Ben Ripkens) [#4463](https://github.com/nodejs/node/pull/4463) +* Minor performance improvements: + - **lib**: Use arrow functions instead of bind where possible (Minwoo Jung) [#3622](https://github.com/nodejs/node/pull/3622). + - (Mistakenly missing from v5.4.0) + - **module**: cache stat() results more aggressively (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) + - **querystring**: improve parse() performance (Brian White) [#4675](https://github.com/nodejs/node/pull/4675) + +### Known issues + +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* 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/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* Unicode characters in filesystem paths are not handled consistently across platforms or Node.js APIs. See [#2088](https://github.com/nodejs/node/issues/2088), [#3401](https://github.com/nodejs/node/issues/3401) and [#3519](https://github.com/nodejs/node/issues/3519). + +### Commits + +* [[`8d0ca10752`](https://github.com/nodejs/node/commit/8d0ca10752)] - **buffer**: make byteLength work with Buffer correctly (Jackson Tian) [#4738](https://github.com/nodejs/node/pull/4738) +* [[`83d2b7707e`](https://github.com/nodejs/node/commit/83d2b7707e)] - **buffer**: remove unnecessary TODO comments (Peter Geiss) [#4719](https://github.com/nodejs/node/pull/4719) +* [[`8182ec094d`](https://github.com/nodejs/node/commit/8182ec094d)] - **build**: add option to select VS version (julien.waechter) [#4645](https://github.com/nodejs/node/pull/4645) +* [[`4383acd9f4`](https://github.com/nodejs/node/commit/4383acd9f4)] - **build**: fix and refactor VTune config in vcbuild.bat (Rod Vagg) [#4192](https://github.com/nodejs/node/pull/4192) +* [[`be0b0b8cb9`](https://github.com/nodejs/node/commit/be0b0b8cb9)] - **build**: minor corrections in VTune configure text (Rod Vagg) [#4192](https://github.com/nodejs/node/pull/4192) +* [[`9571be12f6`](https://github.com/nodejs/node/commit/9571be12f6)] - **cluster**: fix race condition setting suicide prop (Santiago Gimeno) [#4349](https://github.com/nodejs/node/pull/4349) +* [[`ebd9addcd1`](https://github.com/nodejs/node/commit/ebd9addcd1)] - **crypto**: clear error stack in ECDH::Initialize (Fedor Indutny) [#4689](https://github.com/nodejs/node/pull/4689) +* [[`66b9c0d8bd`](https://github.com/nodejs/node/commit/66b9c0d8bd)] - **debugger**: remove variable redeclarations (Rich Trott) [#4633](https://github.com/nodejs/node/pull/4633) +* [[`88b2889679`](https://github.com/nodejs/node/commit/88b2889679)] - **dgram**: prevent disabled optimization of bind() (Brian White) [#4613](https://github.com/nodejs/node/pull/4613) +* [[`d56e3f8b67`](https://github.com/nodejs/node/commit/d56e3f8b67)] - **doc**: restore ICU third-party software licenses (Richard Lau) [#4762](https://github.com/nodejs/node/pull/4762) +* [[`212a44df03`](https://github.com/nodejs/node/commit/212a44df03)] - **doc**: clarify protocol default in http.request() (cjihrig) [#4714](https://github.com/nodejs/node/pull/4714) +* [[`3297036345`](https://github.com/nodejs/node/commit/3297036345)] - **doc**: update branch-diff arguments in release doc (Rod Vagg) [#4691](https://github.com/nodejs/node/pull/4691) +* [[`666c089e68`](https://github.com/nodejs/node/commit/666c089e68)] - **doc**: fix named anchors in addons.markdown and http.markdown (Michael Theriot) [#4708](https://github.com/nodejs/node/pull/4708) +* [[`310530b7ec`](https://github.com/nodejs/node/commit/310530b7ec)] - **doc**: add path property to Write/ReadStream in fs.markdown (Claudio Rodriguez) [#4368](https://github.com/nodejs/node/pull/4368) +* [[`3470574cb6`](https://github.com/nodejs/node/commit/3470574cb6)] - **doc**: clarify explanation of first stream section (Vitor Cortez) [#4234](https://github.com/nodejs/node/pull/4234) +* [[`d91646b9c7`](https://github.com/nodejs/node/commit/d91646b9c7)] - **doc**: rebuild LICENSE using tools/license-builder.sh (Rod Vagg) [#4194](https://github.com/nodejs/node/pull/4194) +* [[`265e2f557b`](https://github.com/nodejs/node/commit/265e2f557b)] - **doc**: fix typo in doc/node.1 (Jérémy Lal) [#4680](https://github.com/nodejs/node/pull/4680) +* [[`4c132fe61e`](https://github.com/nodejs/node/commit/4c132fe61e)] - **doc**: make references clickable (Roman Klauke) [#4654](https://github.com/nodejs/node/pull/4654) +* [[`d139704ff7`](https://github.com/nodejs/node/commit/d139704ff7)] - **doc**: improve child_process.execFile() code example (Ryan Sobol) [#4504](https://github.com/nodejs/node/pull/4504) +* [[`eeb6fdcd0f`](https://github.com/nodejs/node/commit/eeb6fdcd0f)] - **doc**: add docs for more stream options (zoubin) [#4639](https://github.com/nodejs/node/pull/4639) +* [[`b6ab6d2de5`](https://github.com/nodejs/node/commit/b6ab6d2de5)] - **doc**: add branch-diff example to releases.md (Myles Borins) [#4636](https://github.com/nodejs/node/pull/4636) +* [[`287325c5e8`](https://github.com/nodejs/node/commit/287325c5e8)] - **docs**: update gpg key for Myles Borins (Myles Borins) [#4657](https://github.com/nodejs/node/pull/4657) +* [[`65825b79aa`](https://github.com/nodejs/node/commit/65825b79aa)] - **docs**: fix npm command in releases.md (Myles Borins) [#4656](https://github.com/nodejs/node/pull/4656) +* [[`f9a59c1d3b`](https://github.com/nodejs/node/commit/f9a59c1d3b)] - **(SEMVER-MINOR)** **events**: make sure console functions exist (Dave) [#4479](https://github.com/nodejs/node/pull/4479) +* [[`6039a7c1b5`](https://github.com/nodejs/node/commit/6039a7c1b5)] - **(SEMVER-MINOR)** **fs**: add autoClose option to fs.createWriteStream (Saquib) [#3679](https://github.com/nodejs/node/pull/3679) +* [[`ed55169834`](https://github.com/nodejs/node/commit/ed55169834)] - **gitignore**: never ignore debug module (Michaël Zasso) [#2286](https://github.com/nodejs/node/pull/2286) +* [[`d755432fa9`](https://github.com/nodejs/node/commit/d755432fa9)] - **(SEMVER-MINOR)** **http**: improves expect header handling (Daniel Sellers) [#4501](https://github.com/nodejs/node/pull/4501) +* [[`7ce0e04f44`](https://github.com/nodejs/node/commit/7ce0e04f44)] - **lib**: fix style issues after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`ae5bcf9528`](https://github.com/nodejs/node/commit/ae5bcf9528)] - **lib**: use arrow functions instead of bind (Minwoo Jung) [#3622](https://github.com/nodejs/node/pull/3622) +* [[`0ec093cd41`](https://github.com/nodejs/node/commit/0ec093cd41)] - **lib,test**: remove extra semicolons (Michaël Zasso) [#2205](https://github.com/nodejs/node/pull/2205) +* [[`d8f5bd4fe1`](https://github.com/nodejs/node/commit/d8f5bd4fe1)] - **module**: avoid ArgumentsAdaptorTrampoline frame (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) +* [[`83f8d98806`](https://github.com/nodejs/node/commit/83f8d98806)] - **module**: cache stat() results more aggressively (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) +* [[`ff64a4c395`](https://github.com/nodejs/node/commit/ff64a4c395)] - **(SEMVER-MINOR)** **node**: allow preload modules with -i (Evan Lucas) [#4696](https://github.com/nodejs/node/pull/4696) +* [[`4bc1a47761`](https://github.com/nodejs/node/commit/4bc1a47761)] - **querystring**: improve parse() performance (Brian White) [#4675](https://github.com/nodejs/node/pull/4675) +* [[`ad63d350d4`](https://github.com/nodejs/node/commit/ad63d350d4)] - **readline**: Remove XXX and output debuglog (Kohei TAKATA) [#4690](https://github.com/nodejs/node/pull/4690) +* [[`da550aa063`](https://github.com/nodejs/node/commit/da550aa063)] - **repl**: make sure historyPath is trimmed (Evan Lucas) [#4539](https://github.com/nodejs/node/pull/4539) +* [[`1a6e7d1b52`](https://github.com/nodejs/node/commit/1a6e7d1b52)] - **src**: fix negative values in process.hrtime() (Ben Noordhuis) [#4757](https://github.com/nodejs/node/pull/4757) +* [[`8bad51977a`](https://github.com/nodejs/node/commit/8bad51977a)] - **src**: return UV_EAI_NODATA on empty lookup (cjihrig) [#4715](https://github.com/nodejs/node/pull/4715) +* [[`761cf2bf6a`](https://github.com/nodejs/node/commit/761cf2bf6a)] - **src**: don't check failure with ERR_peek_error() (Ben Noordhuis) [#4731](https://github.com/nodejs/node/pull/4731) +* [[`953f4a3999`](https://github.com/nodejs/node/commit/953f4a3999)] - **stream**: prevent object map change in ReadableState (Evan Lucas) [#4761](https://github.com/nodejs/node/pull/4761) +* [[`e65f1f7954`](https://github.com/nodejs/node/commit/e65f1f7954)] - **test**: fix tls-multi-key race condition (Santiago Gimeno) [#3966](https://github.com/nodejs/node/pull/3966) +* [[`3727ae0d7d`](https://github.com/nodejs/node/commit/3727ae0d7d)] - **test**: use addon.md block headings as test dir names (Rod Vagg) [#4412](https://github.com/nodejs/node/pull/4412) +* [[`47960a07c0`](https://github.com/nodejs/node/commit/47960a07c0)] - **test**: make test-cluster-disconnect-leak reliable (Rich Trott) [#4736](https://github.com/nodejs/node/pull/4736) +* [[`9926b5a25f`](https://github.com/nodejs/node/commit/9926b5a25f)] - **test**: fix issues for space-in-parens ESLint rule (Roman Reiss) [#4753](https://github.com/nodejs/node/pull/4753) +* [[`d1aabd6264`](https://github.com/nodejs/node/commit/d1aabd6264)] - **test**: fix style issues after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`e98bcfa2cb`](https://github.com/nodejs/node/commit/e98bcfa2cb)] - **test**: remove 1 second delay from test (Rich Trott) [#4616](https://github.com/nodejs/node/pull/4616) +* [[`6cfd0b5a32`](https://github.com/nodejs/node/commit/6cfd0b5a32)] - **test**: fix flaky test-net-socket-local-address (cjihrig) [#4650](https://github.com/nodejs/node/pull/4650) +* [[`e22cc6c2eb`](https://github.com/nodejs/node/commit/e22cc6c2eb)] - **test**: fix race in test-net-server-pause-on-connect (Rich Trott) [#4637](https://github.com/nodejs/node/pull/4637) +* [[`9164c00bdb`](https://github.com/nodejs/node/commit/9164c00bdb)] - **test**: move resource intensive tests to sequential (Rich Trott) [#4615](https://github.com/nodejs/node/pull/4615) +* [[`d8ba2c0de4`](https://github.com/nodejs/node/commit/d8ba2c0de4)] - **test**: fix `http-upgrade-client` flakiness (Santiago Gimeno) [#4602](https://github.com/nodejs/node/pull/4602) +* [[`6018fa1f57`](https://github.com/nodejs/node/commit/6018fa1f57)] - **test**: fix `http-upgrade-agent` flakiness (Santiago Gimeno) [#4520](https://github.com/nodejs/node/pull/4520) +* [[`c33f6a87d0`](https://github.com/nodejs/node/commit/c33f6a87d0)] - **tools**: enable space-in-parens ESLint rule (Roman Reiss) [#4753](https://github.com/nodejs/node/pull/4753) +* [[`162e16afdb`](https://github.com/nodejs/node/commit/162e16afdb)] - **tools**: enable no-extra-semi rule in eslint (Michaël Zasso) [#2205](https://github.com/nodejs/node/pull/2205) +* [[`031b87d42d`](https://github.com/nodejs/node/commit/031b87d42d)] - **tools**: add license-builder.sh to construct LICENSE (Rod Vagg) [#4194](https://github.com/nodejs/node/pull/4194) +* [[`ec8e0ae697`](https://github.com/nodejs/node/commit/ec8e0ae697)] - **tools**: fix style issue after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`4d5ee7a512`](https://github.com/nodejs/node/commit/4d5ee7a512)] - **tools**: update eslint config (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`2d441493a4`](https://github.com/nodejs/node/commit/2d441493a4)] - **tools**: update eslint to v1.10.3 (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`aba3cc834e`](https://github.com/nodejs/node/commit/aba3cc834e)] - **tools**: fix license-builder.sh for ICU (Richard Lau) [#4762](https://github.com/nodejs/node/pull/4762) +* [[`5f57005ec9`](https://github.com/nodejs/node/commit/5f57005ec9)] - **(SEMVER-MINOR)** **v8,src**: expose statistics about heap spaces (Ben Ripkens) [#4463](https://github.com/nodejs/node/pull/4463) + ## 2016-01-12, Version 5.4.1 (Stable), @TheAlphaNerd ### Notable Changes diff --git a/LICENSE b/LICENSE index 78edee8cf322..0bef53603420 100644 --- a/LICENSE +++ b/LICENSE @@ -98,6 +98,10 @@ The externally maintained libraries used by Node.js are: - ICU, located at deps/icu, is licensed as follows: """ + ICU License - ICU 1.8.1 and later + + COPYRIGHT AND PERMISSION NOTICE + Copyright (c) 1995-2015 International Business Machines Corporation and others All rights reserved. @@ -124,6 +128,330 @@ The externally maintained libraries used by Node.js are: Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. + + All trademarks and registered trademarks mentioned herein are the property of their respective owners. + + Third-Party Software Licenses + This section contains third-party software notices and/or additional terms for licensed + third-party software components included within ICU libraries. + + 1. Unicode Data Files and Software + + COPYRIGHT AND PERMISSION NOTICE + + Copyright © 1991-2015 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in + http://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, + (b) this copyright and permission notice appear in associated + documentation, and + (c) there is clear notice in each modified Data File or in the Software + as well as in the documentation associated with the Data File(s) or + Software that the data or software has been modified. + + THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. + + 2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt) + + # The Google Chrome software developed by Google is licensed under the BSD license. Other software included in this distribution is provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # 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. + # + # + # The word list in cjdict.txt are generated by combining three word lists listed + # below with further processing for compound word breaking. The frequency is generated + # with an iterative training against Google web corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + # + # ---------COPYING.libtabe ---- BEGIN-------------------- + # + # /* + # * Copyrighy (c) 1999 TaBE Project. + # * Copyright (c) 1999 Pai-Hsiang Hsiao. + # * 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 the TaBE Project 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 + # * REGENTS 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. + # */ + # + # /* + # * Copyright (c) 1999 Computer Systems and Communication Lab, + # * Institute of Information Science, Academia Sinica. + # * 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 the Computer Systems and Communication Lab + # * 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 + # * REGENTS 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. + # */ + # + # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + # + # ---------------COPYING.libtabe-----END------------------------------------ + # + # + # ---------------COPYING.ipadic-----BEGIN------------------------------------ + # + # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science + # and Technology. All Rights Reserved. + # + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, indirect or consequential damages or any damages + # whatsoever resulting from loss of use, data or profits, whether in an + # action of contract, negligence or other tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + # + # ---------------COPYING.ipadic-----END------------------------------------ + + 3. Lao Word Break Dictionary Data (laodict.txt) + + # Copyright (c) 2013 International Business Machines Corporation + # and others. All Rights Reserved. + # + # Project: http://code.google.com/p/lao-dictionary/ + # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt + # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary, with slight modifications. + # -------------------------------------------------------------------------------- + # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. + # 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. + # + # 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 HOLDER 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. + # -------------------------------------------------------------------------------- + + 4. Burmese Word Break Dictionary Data (burmesedict.txt) + + # Copyright (c) 2014 International Business Machines Corporation + # and others. All Rights Reserved. + # + # This list is part of a project hosted at: + # github.com/kanyawtech/myanmar-karen-word-lists + # + # -------------------------------------------------------------------------------- + # Copyright (c) 2013, LeRoy Benjamin Sharon + # 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 Myanmar Karen Word Lists, 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 HOLDER 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. + # -------------------------------------------------------------------------------- + + 5. Time Zone Database + ICU uses the public domain data and code derived from + Time Zone Database for its time zone support. The ownership of the TZ database is explained + in BCP 175: Procedure for Maintaining the Time Zone + Database section 7. + + 7. Database Ownership + + The TZ database itself is not an IETF Contribution or an IETF + document. Rather it is a pre-existing and regularly updated work + that is in the public domain, and is intended to remain in the public + domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do not apply + to the TZ Database or contributions that individuals make to it. + Should any claims be made and substantiated against the TZ Database, + the organization that is providing the IANA Considerations defined in + this RFC, under the memorandum of understanding with the IETF, + currently ICANN, may act in accordance with all competent court + orders. No ownership claims will be made by ICANN or the IETF Trust + on the database or the code. Any person making a contribution to the + database or code waives all rights to future claims in that + contribution or in the TZ Database. """ - libuv, located at deps/uv, is licensed as follows: diff --git a/benchmark/querystring/querystring-parse.js b/benchmark/querystring/querystring-parse.js index 3d88bed07d63..6a4d9f5e6169 100644 --- a/benchmark/querystring/querystring-parse.js +++ b/benchmark/querystring/querystring-parse.js @@ -3,7 +3,7 @@ var querystring = require('querystring'); var v8 = require('v8'); var bench = common.createBenchmark(main, { - type: ['noencode', 'encodemany', 'encodelast'], + type: ['noencode', 'encodemany', 'encodelast', 'multivalue'], n: [1e6], }); @@ -14,7 +14,8 @@ function main(conf) { var inputs = { noencode: 'foo=bar&baz=quux&xyzzy=thud', encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d', - encodelast: 'foo=bar&baz=quux&xyzzy=thu%64' + encodelast: 'foo=bar&baz=quux&xyzzy=thu%64', + multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz' }; var input = inputs[type]; diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index ed2c5058a492..845b20c2bdb2 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -1018,5 +1018,5 @@ Test in JavaScript by running: [Native Abstrations for Node.js]: https://github.com/nodejs/nan [examples]: https://github.com/nodejs/nan/tree/master/examples/ [bindings]: https://github.com/TooTallNate/node-bindings -[Linking to Node.js' own dependencies]: #linking-to-node-js-own-dependencies +[Linking to Node.js' own dependencies]: #linking-to-nodejs-own-dependencies [installation instructions]: https://github.com/nodejs/node-gyp#installation diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 42e347f43aa3..0f2c2575bbe3 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -116,6 +116,10 @@ Stop watching for changes on the given `fs.FSWatcher`. Emitted when the ReadStream's file is opened. +### readStream.path + +The path to the file the stream is reading from. + ## Class: fs.Stats Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and their @@ -196,6 +200,10 @@ Emitted when the WriteStream's file is opened. The number of bytes written so far. Does not include data that is still queued for writing. +### writeStream.path + +The path to the file the stream is writing to. + ## fs.access(path[, mode], callback) Tests a user's permissions for the file specified by `path`. `mode` is an @@ -334,13 +342,20 @@ Returns a new [`WriteStream`][] object. (See [Writable Stream][]). { flags: 'w', defaultEncoding: 'utf8', fd: null, - mode: 0o666 } + mode: 0o666, + autoClose: true } `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a `flags` mode of `r+` rather than the default mode `w`. The `defaultEncoding` can be any one of those accepted by [`Buffer`][]. +If `autoClose` is set to true (default behavior) on `error` or `end` +the file descriptor will be closed automatically. If `autoClose` is false, +then the file descriptor won't be closed, even if there's an error. +It is your responsiblity to close it and make sure +there's no file descriptor leak. + Like [`ReadStream`][], if `fd` is specified, `WriteStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. Note that `fd` should be blocking; non-blocking diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 010427ef9215..0f3f6c538f4c 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -192,6 +192,17 @@ The request implements the [Writable Stream][] interface. This is an Emitted when the request has been aborted by the client. This event is only emitted on the first call to `abort()`. +### Event: 'checkExpectation' + +`function (request, response) { }` + +Emitted each time a request with an http Expect header is received, where the +value is not 100-continue. If this event isn't listened for, the server will +automatically respond with a 417 Expectation Failed as appropriate. + +Note that when this event is emitted and handled, the `request` event will +not be emitted. + ### Event: 'connect' `function (response, socket, head) { }` @@ -992,7 +1003,7 @@ automatically parsed with [`url.parse()`][]. Options: -- `protocol`: Protocol to use. Defaults to `'http'`. +- `protocol`: Protocol to use. Defaults to `'http:'`. - `host`: A domain name or IP address of the server to issue the request to. Defaults to `'localhost'`. - `hostname`: Alias for `host`. To support [`url.parse()`][] `hostname` is @@ -1096,7 +1107,7 @@ There are a few special headers that should be noted. [`http.Agent`]: #http_class_http_agent [`http.ClientRequest`]: #http_class_http_clientrequest [`http.globalAgent`]: #http_http_globalagent -[`http.IncomingMessage`]: #http_http_incomingmessage +[`http.IncomingMessage`]: #http_class_http_incomingmessage [`http.request()`]: #http_http_request_options_callback [`http.Server`]: #http_class_http_server [`http.ServerResponse`]: #http_class_http_serverresponse diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown index b9d706beef02..d045d7c4332c 100644 --- a/doc/api/repl.markdown +++ b/doc/api/repl.markdown @@ -37,7 +37,7 @@ via the following environment variables: - `NODE_REPL_HISTORY` - When a valid path is given, persistent REPL history will be saved to the specified file rather than `.node_repl_history` in the user's home directory. Setting this value to `""` will disable persistent - REPL history. + REPL history. Whitespace will be trimmed from the value. - `NODE_REPL_HISTORY_SIZE` - defaults to `1000`. Controls how many lines of history will be persisted if history is available. Must be a positive number. - `NODE_REPL_MODE` - may be any of `sloppy`, `strict`, or `magic`. Defaults diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index dcb64c17dd66..554ddc222d6f 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -11,19 +11,17 @@ You can load the Stream base classes by doing `require('stream')`. There are base classes provided for [Readable][] streams, [Writable][] streams, [Duplex][] streams, and [Transform][] streams. -This document is split up into 3 sections. The first explains the -parts of the API that you need to be aware of to use streams in your -programs. If you never implement a streaming API yourself, you can -stop there. - -The second section explains the parts of the API that you need to use -if you implement your own custom streams yourself. The API is -designed to make this easy for you to do. - -The third section goes into more depth about how streams work, -including some of the internal mechanisms and functions that you -should probably not modify unless you definitely know what you are -doing. +This document is split up into 3 sections: + +1. The first section explains the parts of the API that you need to be + aware of to use streams in your programs. +2. The second section explains the parts of the API that you need to + use if you implement your own custom streams yourself. The API is + designed to make this easy for you to do. +3. The third section goes into more depth about how streams work, + including some of the internal mechanisms and functions that you + should probably not modify unless you definitely know what you are + doing. ## API for Stream Consumers diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown index 70abd6c6473f..c6d760b0d5ff 100644 --- a/doc/api/v8.markdown +++ b/doc/api/v8.markdown @@ -21,6 +21,55 @@ Returns an object with the following properties } ``` +## getHeapSpaceStatistics() + +Returns statistics about the V8 heap spaces, i.e. the segments which make up +the V8 heap. Order of heap spaces nor availability of a heap space can be +guaranteed as the statistics are provided via the V8 `GetHeapSpaceStatistics` +function. + +Example result: + +``` +[ + { + "space_name": "new_space", + "space_size": 2063872, + "space_used_size": 951112, + "space_available_size": 80824, + "physical_space_size": 2063872 + }, + { + "space_name": "old_space", + "space_size": 3090560, + "space_used_size": 2493792, + "space_available_size": 0, + "physical_space_size": 3090560 + }, + { + "space_name": "code_space", + "space_size": 1260160, + "space_used_size": 644256, + "space_available_size": 960, + "physical_space_size": 1260160 + }, + { + "space_name": "map_space", + "space_size": 1094160, + "space_used_size": 201608, + "space_available_size": 0, + "physical_space_size": 1094160 + }, + { + "space_name": "large_object_space", + "space_size": 0, + "space_used_size": 0, + "space_available_size": 1490980608, + "physical_space_size": 0 + } +] +``` + ## setFlagsFromString(string) Set additional V8 command line flags. Use with care; changing settings diff --git a/doc/releases.md b/doc/releases.md index daa325b0bce3..c41241de0ef7 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -57,7 +57,7 @@ Create a new branch named _"vx.y.z-proposal"_, or something similar. Using `git For a list of commits that could be landed in a patch release on v5.x ``` -$ branch-diff v5.x master --exclude-label semver-major,semver-minor,dont-land-on-v5.x --simple +$ branch-diff v5.x master --exclude-label=semver-major,semver-minor,dont-land-on-v5.x --filter-release --format=simple ``` Carefully review the list of commits looking for errors (incorrect `PR-URL`, incorrect semver, etc.). Commits labeled as semver minor or semver major should only be cherry-picked when appropriate for the type of release being made. Previous release commits and version bumps do not need to be cherry-picked. diff --git a/lib/_debugger.js b/lib/_debugger.js index 58dc6dbb8497..5339ebbb56fe 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -462,7 +462,7 @@ Client.prototype.setBreakpoint = function(req, cb) { }; Client.prototype.clearBreakpoint = function(req, cb) { - var req = { + req = { command: 'clearbreakpoint', arguments: req }; @@ -573,7 +573,7 @@ Client.prototype.mirrorObject = function(handle, depth, cb) { }); cb(null, mirror); } - }; + } }); return; } else if (handle.type === 'function') { @@ -799,7 +799,7 @@ function Interface(stdin, stdout, args) { } else { self.repl.context[key] = fn; } - }; + } // Copy all prototype methods in repl context // Setup them as getters if possible @@ -1352,9 +1352,10 @@ Interface.prototype.setBreakpoint = function(script, line, return; } + let req; if (/\(\)$/.test(script)) { // setBreakpoint('functionname()'); - var req = { + req = { type: 'function', target: script.replace(/\(\)$/, ''), condition: condition @@ -1380,7 +1381,6 @@ Interface.prototype.setBreakpoint = function(script, line, if (ambiguous) return this.error('Script name is ambiguous'); if (line <= 0) return this.error('Line should be a positive value'); - var req; if (scriptId) { req = { type: 'scriptId', @@ -1651,7 +1651,7 @@ Interface.prototype.trySpawn = function(cb) { var isRemote = false; if (this.args.length === 2) { - var match = this.args[1].match(/^([^:]+):(\d+)$/); + const match = this.args[1].match(/^([^:]+):(\d+)$/); if (match) { // Connecting to remote debugger @@ -1675,7 +1675,7 @@ Interface.prototype.trySpawn = function(cb) { } isRemote = true; } else { - var match = this.args[1].match(/^--port=(\d+)$/); + const match = this.args[1].match(/^--port=(\d+)$/); if (match) { // Start debugger on custom port // `node debug --port=5858 app.js` diff --git a/lib/_http_server.js b/lib/_http_server.js index 3e4e7f4dd898..62f23e8a3c88 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -2,7 +2,6 @@ const util = require('util'); const net = require('net'); -const EventEmitter = require('events'); const HTTPParser = process.binding('http_parser').HTTPParser; const assert = require('assert').ok; const common = require('_http_common'); @@ -391,7 +390,7 @@ function connectionListener(socket) { parser = null; var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; - if (EventEmitter.listenerCount(self, eventName) > 0) { + if (self.listenerCount(eventName) > 0) { debug('SERVER have listener for %s', eventName); var bodyHead = d.slice(bytesParsed, d.length); @@ -516,14 +515,23 @@ function connectionListener(socket) { } if (req.headers.expect !== undefined && - (req.httpVersionMajor == 1 && req.httpVersionMinor == 1) && - continueExpression.test(req.headers['expect'])) { - res._expect_continue = true; - if (EventEmitter.listenerCount(self, 'checkContinue') > 0) { - self.emit('checkContinue', req, res); + (req.httpVersionMajor == 1 && req.httpVersionMinor == 1)) { + if (continueExpression.test(req.headers.expect)) { + res._expect_continue = true; + + if (self.listenerCount('checkContinue') > 0) { + self.emit('checkContinue', req, res); + } else { + res.writeContinue(); + self.emit('request', req, res); + } } else { - res.writeContinue(); - self.emit('request', req, res); + if (self.listenerCount('checkExpectation') > 0) { + self.emit('checkExpectation', req, res); + } else { + res.writeHead(417); + res.end(); + } } } else { self.emit('request', req, res); diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 7074cd2ca508..33a5f0a7733e 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -51,6 +51,7 @@ function ReadableState(options, stream) { this.needReadable = false; this.emittedReadable = false; this.readableListening = false; + this.resumeScheduled = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. diff --git a/lib/buffer.js b/lib/buffer.js index 2daebb5e301e..3d28bf9a23dc 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -257,6 +257,9 @@ function base64ByteLength(str, bytes) { function byteLength(string, encoding) { + if (string instanceof Buffer) + return string.length; + if (typeof string !== 'string') string = '' + string; @@ -536,8 +539,6 @@ Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) { }, 'Buffer.set is deprecated. Use array indexes instead.'); -// TODO(trevnorris): fix these checks to follow new standard -// write(string, offset = 0, length = buffer.length, encoding = 'utf8') var writeWarned = false; const writeMsg = 'Buffer.write(string, encoding, offset, length) is ' + 'deprecated. Use write(string[, offset[, length]]' + @@ -630,8 +631,6 @@ Buffer.prototype.toJSON = function() { }; -// TODO(trevnorris): currently works like Array.prototype.slice(), which -// doesn't follow the new standard for throwing on out of range indexes. Buffer.prototype.slice = function slice(start, end) { const buffer = this.subarray(start, end); Object.setPrototypeOf(buffer, Buffer.prototype); diff --git a/lib/events.js b/lib/events.js index ea3f2831eb3b..d20460720eda 100644 --- a/lib/events.js +++ b/lib/events.js @@ -18,7 +18,20 @@ EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +var defaultMaxListeners = 10; + +Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: true, + get: function() { + return defaultMaxListeners; + }, + set: function(arg) { + // force global console to be compiled. + // see https://github.com/nodejs/node/issues/4467 + console; + defaultMaxListeners = arg; + } +}); EventEmitter.init = function() { this.domain = null; @@ -417,7 +430,7 @@ function listenerCount(type) { } return 0; -}; +} // About 1.5x faster than the two-arg version of Array#splice(). function spliceOne(list, index) { diff --git a/lib/fs.js b/lib/fs.js index 74cc9cbf5c81..978b8cedf40d 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1886,6 +1886,7 @@ function WriteStream(path, options) { this.mode = options.mode === undefined ? 0o666 : options.mode; this.start = options.start; + this.autoClose = options.autoClose === undefined ? true : !!options.autoClose; this.pos = undefined; this.bytesWritten = 0; @@ -1907,7 +1908,11 @@ function WriteStream(path, options) { this.open(); // dispose on finish. - this.once('finish', this.close); + this.once('finish', function() { + if (this.autoClose) { + this.close(); + } + }); } fs.FileWriteStream = fs.WriteStream; // support the legacy name @@ -1916,7 +1921,9 @@ fs.FileWriteStream = fs.WriteStream; // support the legacy name WriteStream.prototype.open = function() { fs.open(this.path, this.flags, this.mode, function(er, fd) { if (er) { - this.destroy(); + if (this.autoClose) { + this.destroy(); + } this.emit('error', er); return; } @@ -1939,7 +1946,9 @@ WriteStream.prototype._write = function(data, encoding, cb) { var self = this; fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { if (er) { - self.destroy(); + if (self.autoClose) { + self.destroy(); + } return cb(er); } self.bytesWritten += bytes; diff --git a/lib/internal/module.js b/lib/internal/module.js index ef55aa64bd56..29f88999dbf7 100644 --- a/lib/internal/module.js +++ b/lib/internal/module.js @@ -1,6 +1,8 @@ 'use strict'; -module.exports = { makeRequireFunction, stripBOM }; +exports = module.exports = { makeRequireFunction, stripBOM }; + +exports.requireDepth = 0; // Invoke with makeRequireFunction.call(module) where |module| is the // Module object to use as the context for the require() function. @@ -9,7 +11,12 @@ function makeRequireFunction() { const self = this; function require(path) { - return self.require(path); + try { + exports.requireDepth += 1; + return self.require(path); + } finally { + exports.requireDepth -= 1; + } } require.resolve = function(request) { diff --git a/lib/internal/repl.js b/lib/internal/repl.js index e6b41fbdd89b..371446a83bd4 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -55,15 +55,26 @@ function createRepl(env, opts, cb) { } const repl = REPL.start(opts); - if (opts.terminal && env.NODE_REPL_HISTORY !== '') { + if (opts.terminal) { return setupHistory(repl, env.NODE_REPL_HISTORY, env.NODE_REPL_HISTORY_FILE, cb); } + repl._historyPrev = _replHistoryMessage; cb(null, repl); } function setupHistory(repl, historyPath, oldHistoryPath, ready) { + // Empty string disables persistent history. + + if (typeof historyPath === 'string') + historyPath = historyPath.trim(); + + if (historyPath === '') { + repl._historyPrev = _replHistoryMessage; + return ready(null, repl); + } + if (!historyPath) { try { historyPath = path.join(os.homedir(), '.node_repl_history'); diff --git a/lib/module.js b/lib/module.js index 02e6cccf77d1..7d3f0f6c71d5 100644 --- a/lib/module.js +++ b/lib/module.js @@ -23,6 +23,20 @@ function hasOwnProperty(obj, prop) { } +function stat(filename) { + filename = path._makeLong(filename); + const cache = stat.cache; + if (cache !== null) { + const result = cache.get(filename); + if (result !== undefined) return result; + } + const result = internalModuleStat(filename); + if (cache !== null) cache.set(filename, result); + return result; +} +stat.cache = null; + + function Module(id, parent) { this.id = id; this.exports = {}; @@ -104,7 +118,7 @@ Module._realpathCache = {}; // check if the file exists and is not a directory function tryFile(requestPath) { - const rc = internalModuleStat(path._makeLong(requestPath)); + const rc = stat(requestPath); return rc === 0 && toRealPath(requestPath); } @@ -141,12 +155,12 @@ Module._findPath = function(request, paths) { // For each path for (var i = 0, PL = paths.length; i < PL; i++) { // Don't search further if path doesn't exist - if (paths[i] && internalModuleStat(path._makeLong(paths[i])) < 1) continue; + if (paths[i] && stat(paths[i]) < 1) continue; var basePath = path.resolve(paths[i], request); var filename; if (!trailingSlash) { - const rc = internalModuleStat(path._makeLong(basePath)); + const rc = stat(basePath); if (rc === 0) { // File. filename = toRealPath(basePath); } else if (rc === 1) { // Directory. @@ -394,7 +408,11 @@ Module.prototype._compile = function(content, filename) { const dirname = path.dirname(filename); const require = internalModule.makeRequireFunction.call(this); const args = [this.exports, require, this, filename, dirname]; - return compiledWrapper.apply(this.exports, args); + const depth = internalModule.requireDepth; + if (depth === 0) stat.cache = new Map(); + const result = compiledWrapper.apply(this.exports, args); + if (depth === 0) stat.cache = null; + return result; }; diff --git a/lib/net.js b/lib/net.js index ec8f1c470e2d..7a612096ab45 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1186,7 +1186,7 @@ function createServerHandle(address, port, addressType, fd) { } return handle; -}; +} exports._createServerHandle = createServerHandle; diff --git a/lib/querystring.js b/lib/querystring.js index 5f8df9303892..b034635668fa 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -209,7 +209,6 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { return obj; } - var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; @@ -230,7 +229,9 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { var keys = []; for (var i = 0; i < len; ++i) { - const x = qs[i].replace(regexp, '%20'); + // replacePlus() is used instead of a regexp because it is ~15-30% faster + // with v8 4.7 + const x = replacePlus(qs[i]); const idx = x.indexOf(eq); var k, v; @@ -242,10 +243,14 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { v = ''; } + // Use a key array lookup instead of using hasOwnProperty(), which is slower if (keys.indexOf(k) === -1) { obj[k] = v; keys.push(k); - } else if (Array.isArray(obj[k])) { + } else if (obj[k] instanceof Array) { + // `instanceof Array` is used instead of Array.isArray() because it is + // ~15-20% faster with v8 4.7 and is safe to use because we are using it + // with values being created within this function obj[k].push(v); } else { obj[k] = [obj[k], v]; @@ -256,6 +261,25 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { }; +function replacePlus(str) { + var ret = ''; + var start = 0; + var i = -1; + while ((i = str.indexOf('+', i + 1)) !== -1) { + ret += str.slice(start, i); + ret += '%20'; + start = i + 1; + } + if (start === 0) + return str; + if (start < str.length) + ret += str.slice(start); + return ret; +} + + +// v8 does not optimize functions with try-catch blocks, so we isolate them here +// to minimize the damage function decodeStr(s, decoder) { try { return decoder(s); diff --git a/lib/readline.js b/lib/readline.js index 00d9f8984e6a..8ee10850e54f 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -9,6 +9,7 @@ const kHistorySize = 30; const util = require('util'); +const debug = util.debuglog('readline'); const internalUtil = require('internal/util'); const inherits = util.inherits; const Buffer = require('buffer').Buffer; @@ -375,7 +376,7 @@ Interface.prototype._tabComplete = function() { self.resume(); if (err) { - // XXX Log it somewhere? + debug('tab completion error %j', err); return; } diff --git a/lib/tls.js b/lib/tls.js index 1abeb7787369..245afb6bdc75 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -46,7 +46,7 @@ function convertProtocols(protocols) { }, 0); return buff; -}; +} exports.convertNPNProtocols = function(protocols, out) { // If protocols is Array - translate it into buffer diff --git a/lib/v8.js b/lib/v8.js index acadfa64e065..551b2ada9852 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -16,9 +16,9 @@ const v8binding = process.binding('v8'); +// Properties for heap statistics buffer extraction. const heapStatisticsBuffer = new Uint32Array(v8binding.heapStatisticsArrayBuffer); - const kTotalHeapSizeIndex = v8binding.kTotalHeapSizeIndex; const kTotalHeapSizeExecutableIndex = v8binding.kTotalHeapSizeExecutableIndex; const kTotalPhysicalSizeIndex = v8binding.kTotalPhysicalSizeIndex; @@ -26,6 +26,18 @@ const kTotalAvailableSize = v8binding.kTotalAvailableSize; const kUsedHeapSizeIndex = v8binding.kUsedHeapSizeIndex; const kHeapSizeLimitIndex = v8binding.kHeapSizeLimitIndex; +// Properties for heap space statistics buffer extraction. +const heapSpaceStatisticsBuffer = + new Uint32Array(v8binding.heapSpaceStatisticsArrayBuffer); +const kHeapSpaces = v8binding.kHeapSpaces; +const kNumberOfHeapSpaces = kHeapSpaces.length; +const kHeapSpaceStatisticsPropertiesCount = + v8binding.kHeapSpaceStatisticsPropertiesCount; +const kSpaceSizeIndex = v8binding.kSpaceSizeIndex; +const kSpaceUsedSizeIndex = v8binding.kSpaceUsedSizeIndex; +const kSpaceAvailableSizeIndex = v8binding.kSpaceAvailableSizeIndex; +const kPhysicalSpaceSizeIndex = v8binding.kPhysicalSpaceSizeIndex; + exports.getHeapStatistics = function() { const buffer = heapStatisticsBuffer; @@ -42,3 +54,22 @@ exports.getHeapStatistics = function() { }; exports.setFlagsFromString = v8binding.setFlagsFromString; + +exports.getHeapSpaceStatistics = function() { + const heapSpaceStatistics = new Array(kNumberOfHeapSpaces); + const buffer = heapSpaceStatisticsBuffer; + v8binding.updateHeapSpaceStatisticsArrayBuffer(); + + for (let i = 0; i < kNumberOfHeapSpaces; i++) { + const propertyOffset = i * kHeapSpaceStatisticsPropertiesCount; + heapSpaceStatistics[i] = { + space_name: kHeapSpaces[i], + space_size: buffer[propertyOffset + kSpaceSizeIndex], + space_used_size: buffer[propertyOffset + kSpaceUsedSizeIndex], + space_available_size: buffer[propertyOffset + kSpaceAvailableSizeIndex], + physical_space_size: buffer[propertyOffset + kPhysicalSpaceSizeIndex] + }; + } + + return heapSpaceStatistics; +}; diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 8f57dfe477cd..46636c528b7f 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -983,6 +983,10 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { address = address->ai_next; } + // No responses were found to return + if (n == 0) { + argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA); + } argv[1] = results; } diff --git a/src/env-inl.h b/src/env-inl.h index f73e9c6ba200..d2c0e048a6d3 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -242,6 +242,7 @@ inline Environment::~Environment() { isolate_data()->Put(); delete[] heap_statistics_buffer_; + delete[] heap_space_statistics_buffer_; delete[] http_parser_buffer_; } @@ -374,6 +375,17 @@ inline void Environment::set_heap_statistics_buffer(uint32_t* pointer) { heap_statistics_buffer_ = pointer; } +inline uint32_t* Environment::heap_space_statistics_buffer() const { + CHECK_NE(heap_space_statistics_buffer_, nullptr); + return heap_space_statistics_buffer_; +} + +inline void Environment::set_heap_space_statistics_buffer(uint32_t* pointer) { + CHECK_EQ(heap_space_statistics_buffer_, nullptr); // Should be set only once. + heap_space_statistics_buffer_ = pointer; +} + + inline char* Environment::http_parser_buffer() const { return http_parser_buffer_; } diff --git a/src/env.h b/src/env.h index 6151c57069ad..0431ecab77b3 100644 --- a/src/env.h +++ b/src/env.h @@ -461,6 +461,9 @@ class Environment { inline uint32_t* heap_statistics_buffer() const; inline void set_heap_statistics_buffer(uint32_t* pointer); + inline uint32_t* heap_space_statistics_buffer() const; + inline void set_heap_space_statistics_buffer(uint32_t* pointer); + inline char* http_parser_buffer() const; inline void set_http_parser_buffer(char* buffer); @@ -561,6 +564,7 @@ class Environment { int handle_cleanup_waiting_; uint32_t* heap_statistics_buffer_ = nullptr; + uint32_t* heap_space_statistics_buffer_ = nullptr; char* http_parser_buffer_; diff --git a/src/node.js b/src/node.js index 993e596ba614..67f6cdb5ceda 100644 --- a/src/node.js +++ b/src/node.js @@ -140,6 +140,7 @@ } } else { + startup.preloadModules(); // If -i or --interactive were passed, or stdin is a TTY. if (process._forceRepl || NativeModule.require('tty').isatty(0)) { // REPL @@ -192,10 +193,9 @@ if (typeof ar !== 'undefined') { if (Array.isArray(ar)) { - return [ - (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0], - hrValues[2] - ar[1] - ]; + const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0]; + const nsec = hrValues[2] - ar[1]; + return [nsec < 0 ? sec - 1 : sec, nsec < 0 ? nsec + 1e9 : nsec]; } throw new TypeError('process.hrtime() only accepts an Array tuple'); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 35a0687b9f95..a27f97dc7407 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3611,8 +3611,7 @@ bool Hash::HashInit(const char* hash_type) { if (md_ == nullptr) return false; EVP_MD_CTX_init(&mdctx_); - EVP_DigestInit_ex(&mdctx_, md_, nullptr); - if (0 != ERR_peek_error()) { + if (EVP_DigestInit_ex(&mdctx_, md_, nullptr) <= 0) { return false; } initialised_ = true; @@ -4678,6 +4677,8 @@ void ECDH::Initialize(Environment* env, Local target) { void ECDH::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + MarkPopErrorOnReturn mark_pop_error_on_return; + // TODO(indutny): Support raw curves? CHECK(args[0]->IsString()); node::Utf8Value curve(env->isolate(), args[0]); diff --git a/src/node_v8.cc b/src/node_v8.cc index 9f456daec464..a1122e57f13c 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -7,13 +7,16 @@ namespace node { +using v8::Array; using v8::ArrayBuffer; using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; +using v8::HeapSpaceStatistics; using v8::HeapStatistics; using v8::Isolate; using v8::Local; +using v8::NewStringType; using v8::Object; using v8::String; using v8::Uint32; @@ -34,6 +37,21 @@ static const size_t kHeapStatisticsPropertiesCount = HEAP_STATISTICS_PROPERTIES(V); #undef V +#define HEAP_SPACE_STATISTICS_PROPERTIES(V) \ + V(0, space_size, kSpaceSizeIndex) \ + V(1, space_used_size, kSpaceUsedSizeIndex) \ + V(2, space_available_size, kSpaceAvailableSizeIndex) \ + V(3, physical_space_size, kPhysicalSpaceSizeIndex) + +#define V(a, b, c) +1 +static const size_t kHeapSpaceStatisticsPropertiesCount = + HEAP_SPACE_STATISTICS_PROPERTIES(V); +#undef V + +// Will be populated in InitializeV8Bindings. +static size_t number_of_heap_spaces = 0; + + void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); HeapStatistics s; @@ -45,6 +63,23 @@ void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { } +void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + HeapSpaceStatistics s; + Isolate* const isolate = env->isolate(); + uint32_t* buffer = env->heap_space_statistics_buffer(); + + for (size_t i = 0; i < number_of_heap_spaces; i++) { + isolate->GetHeapSpaceStatistics(&s, i); + size_t const property_offset = i * kHeapSpaceStatisticsPropertiesCount; +#define V(index, name, _) buffer[property_offset + index] = \ + static_cast(s.name()); + HEAP_SPACE_STATISTICS_PROPERTIES(V) +#undef V + } +} + + void SetFlagsFromString(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -62,10 +97,10 @@ void InitializeV8Bindings(Local target, Local unused, Local context) { Environment* env = Environment::GetCurrent(context); + env->SetMethod(target, "updateHeapStatisticsArrayBuffer", UpdateHeapStatisticsArrayBuffer); - env->SetMethod(target, "setFlagsFromString", SetFlagsFromString); env->set_heap_statistics_buffer(new uint32_t[kHeapStatisticsPropertiesCount]); @@ -84,6 +119,56 @@ void InitializeV8Bindings(Local target, HEAP_STATISTICS_PROPERTIES(V) #undef V + + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), + "kHeapSpaceStatisticsPropertiesCount"), + Uint32::NewFromUnsigned(env->isolate(), + kHeapSpaceStatisticsPropertiesCount)); + + number_of_heap_spaces = env->isolate()->NumberOfHeapSpaces(); + + // Heap space names are extracted once and exposed to JavaScript to + // avoid excessive creation of heap space name Strings. + HeapSpaceStatistics s; + const Local heap_spaces = Array::New(env->isolate(), + number_of_heap_spaces); + for (size_t i = 0; i < number_of_heap_spaces; i++) { + env->isolate()->GetHeapSpaceStatistics(&s, i); + Local heap_space_name = String::NewFromUtf8(env->isolate(), + s.space_name(), + NewStringType::kNormal) + .ToLocalChecked(); + heap_spaces->Set(i, heap_space_name); + } + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kHeapSpaces"), + heap_spaces); + + env->SetMethod(target, + "updateHeapSpaceStatisticsArrayBuffer", + UpdateHeapSpaceStatisticsBuffer); + + env->set_heap_space_statistics_buffer( + new uint32_t[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]); + + const size_t heap_space_statistics_buffer_byte_length = + sizeof(*env->heap_space_statistics_buffer()) * + kHeapSpaceStatisticsPropertiesCount * + number_of_heap_spaces; + + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), + "heapSpaceStatisticsArrayBuffer"), + ArrayBuffer::New(env->isolate(), + env->heap_space_statistics_buffer(), + heap_space_statistics_buffer_byte_length)); + +#define V(i, _, name) \ + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name), \ + Uint32::NewFromUnsigned(env->isolate(), i)); + + HEAP_SPACE_STATISTICS_PROPERTIES(V) +#undef V + + env->SetMethod(target, "setFlagsFromString", SetFlagsFromString); } } // namespace node diff --git a/src/node_version.h b/src/node_version.h index 29e5d0366cc1..b2f753e58195 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -2,8 +2,8 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 5 -#define NODE_MINOR_VERSION 4 -#define NODE_PATCH_VERSION 2 +#define NODE_MINOR_VERSION 5 +#define NODE_PATCH_VERSION 1 #define NODE_VERSION_IS_RELEASE 0 diff --git a/test/common.js b/test/common.js index 133294d91e15..b91044ec4b6f 100644 --- a/test/common.js +++ b/test/common.js @@ -337,7 +337,7 @@ function leakedGlobals() { leaked.push(val); return leaked; -}; +} exports.leakedGlobals = leakedGlobals; // Turn this off if the test should not check for global leaks. diff --git a/test/debugger/helper-debugger-repl.js b/test/debugger/helper-debugger-repl.js index 714a22c2a22f..20cd34116504 100644 --- a/test/debugger/helper-debugger-repl.js +++ b/test/debugger/helper-debugger-repl.js @@ -103,7 +103,7 @@ function addTest(input, output) { } else { quit(); } - }; + } expected.push({input: input, lines: output, callback: next}); } diff --git a/test/fixtures/define-global.js b/test/fixtures/define-global.js new file mode 100644 index 000000000000..82b6a5a72cc9 --- /dev/null +++ b/test/fixtures/define-global.js @@ -0,0 +1 @@ +global.a = 'test'; diff --git a/test/fixtures/module-require-depth/one.js b/test/fixtures/module-require-depth/one.js new file mode 100644 index 000000000000..5927908b7540 --- /dev/null +++ b/test/fixtures/module-require-depth/one.js @@ -0,0 +1,9 @@ +// Flags: --expose_internals +'use strict'; +const assert = require('assert'); +const internalModule = require('internal/module'); + +exports.requireDepth = internalModule.requireDepth; +assert.strictEqual(internalModule.requireDepth, 1); +assert.deepStrictEqual(require('./two'), { requireDepth: 2 }); +assert.strictEqual(internalModule.requireDepth, 1); diff --git a/test/fixtures/module-require-depth/two.js b/test/fixtures/module-require-depth/two.js new file mode 100644 index 000000000000..aea49947d115 --- /dev/null +++ b/test/fixtures/module-require-depth/two.js @@ -0,0 +1,9 @@ +// Flags: --expose_internals +'use strict'; +const assert = require('assert'); +const internalModule = require('internal/module'); + +exports.requireDepth = internalModule.requireDepth; +assert.strictEqual(internalModule.requireDepth, 2); +assert.deepStrictEqual(require('./one'), { requireDepth: 1 }); +assert.strictEqual(internalModule.requireDepth, 2); diff --git a/test/parallel/test-beforeexit-event.js b/test/parallel/test-beforeexit-event.js index 8e5d66f5f5d7..6bc5ef53ed95 100644 --- a/test/parallel/test-beforeexit-event.js +++ b/test/parallel/test-beforeexit-event.js @@ -5,7 +5,7 @@ var common = require('../common'); var revivals = 0; var deaths = 0; -process.on('beforeExit', function() { deaths++; } ); +process.on('beforeExit', function() { deaths++; }); process.once('beforeExit', tryImmediate); diff --git a/test/parallel/test-buffer-bytelength.js b/test/parallel/test-buffer-bytelength.js index 32ed6dbd6761..ef68097157b1 100644 --- a/test/parallel/test-buffer-bytelength.js +++ b/test/parallel/test-buffer-bytelength.js @@ -10,6 +10,12 @@ assert.equal(Buffer.byteLength(NaN, 'utf8'), 3); assert.equal(Buffer.byteLength({}, 'binary'), 15); assert.equal(Buffer.byteLength(), 9); +// buffer +var incomplete = new Buffer([0xe4, 0xb8, 0xad, 0xe6, 0x96]); +assert.equal(Buffer.byteLength(incomplete), 5); +var ascii = new Buffer('abc'); +assert.equal(Buffer.byteLength(ascii), 3); + // special case: zero length string assert.equal(Buffer.byteLength('', 'ascii'), 0); assert.equal(Buffer.byteLength('', 'HeX'), 0); diff --git a/test/parallel/test-child-process-spawnsync-input.js b/test/parallel/test-child-process-spawnsync-input.js index 338b4277fb19..0116f092920a 100644 --- a/test/parallel/test-child-process-spawnsync-input.js +++ b/test/parallel/test-child-process-spawnsync-input.js @@ -23,7 +23,7 @@ var ret; function checkSpawnSyncRet(ret) { assert.strictEqual(ret.status, 0); assert.strictEqual(ret.error, undefined); -}; +} function verifyBufOutput(ret) { checkSpawnSyncRet(ret); diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index a1e8fb1d7da4..68394dd9bcaf 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -159,6 +159,11 @@ secret2 = ecdh2.computeSecret(key1, 'binary', 'buffer'); assert.equal(secret1, secret2.toString('base64')); +// Oakley curves do not clean up ERR stack, it was causing unexpected failure +// when accessing other OpenSSL APIs afterwards. +crypto.createECDH('Oakley-EC2N-3'); +crypto.createHash('sha256'); + // Point formats assert.equal(ecdh1.getPublicKey('buffer', 'uncompressed')[0], 4); let firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0]; diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index c244c9e0dd12..7d66f83baaed 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -62,7 +62,7 @@ var wikipedia = [ for (var i = 0, l = wikipedia.length; i < l; i++) { for (var hash in wikipedia[i]['hmac']) { // FIPS does not support MD5. - if (common.hasFipsCrypto && hash == 'md5' ) + if (common.hasFipsCrypto && hash == 'md5') continue; var result = crypto.createHmac(hash, wikipedia[i]['key']) .update(wikipedia[i]['data']) diff --git a/test/parallel/test-fs-write-stream-autoclose-option.js b/test/parallel/test-fs-write-stream-autoclose-option.js new file mode 100644 index 000000000000..0706ed648588 --- /dev/null +++ b/test/parallel/test-fs-write-stream-autoclose-option.js @@ -0,0 +1,52 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const file = path.join(common.tmpDir, 'write-autoclose-opt1.txt'); +common.refreshTmpDir(); +let stream = fs.createWriteStream(file, {flags: 'w+', autoClose: false}); +stream.write('Test1'); +stream.end(); +stream.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert.strictEqual(stream.closed, undefined); + assert(stream.fd !== null); + next(); + })); +})); + +function next() { + // This will tell us if the fd is usable again or not + stream = fs.createWriteStream(null, {fd: stream.fd, start: 0}); + stream.write('Test2'); + stream.end(); + stream.on('finish', common.mustCall(function() { + assert.strictEqual(stream.closed, true); + assert.strictEqual(stream.fd, null); + process.nextTick(common.mustCall(next2)); + })); +} + +function next2() { + // This will test if after reusing the fd data is written properly + fs.readFile(file, function(err, data) { + assert(!err); + assert.strictEqual(data.toString(), 'Test2'); + process.nextTick(common.mustCall(next3)); + }); +} + +function next3() { + // This is to test success scenario where autoClose is true + const stream = fs.createWriteStream(file, {autoClose: true}); + stream.write('Test3'); + stream.end(); + stream.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert.strictEqual(stream.closed, true); + assert.strictEqual(stream.fd, null); + })); + })); +} diff --git a/test/parallel/test-global-console-exists.js b/test/parallel/test-global-console-exists.js new file mode 100644 index 000000000000..1a13ffec29c2 --- /dev/null +++ b/test/parallel/test-global-console-exists.js @@ -0,0 +1,36 @@ +/* eslint-disable required-modules */ +// ordinarily test files must require('common') but that action causes +// the global console to be compiled, defeating the purpose of this test + +'use strict'; + +const assert = require('assert'); +const EventEmitter = require('events'); +const leak_warning = /EventEmitter memory leak detected\. 2 hello listeners/; + +var write_calls = 0; +process.stderr.write = function(data) { + if (write_calls === 0) + assert.ok(data.match(leak_warning)); + else if (write_calls === 1) + assert.ok(data.match(/Trace/)); + else + assert.ok(false, 'stderr.write should be called only twice'); + + write_calls++; +}; + +const old_default = EventEmitter.defaultMaxListeners; +EventEmitter.defaultMaxListeners = 1; + +const e = new EventEmitter(); +e.on('hello', function() {}); +e.on('hello', function() {}); + +// TODO: figure out how to validate console. Currently, +// there is no obvious way of validating that console +// exists here exactly when it should. + +assert.equal(write_calls, 2); + +EventEmitter.defaultMaxListeners = old_default; diff --git a/test/parallel/test-http-1.0-keep-alive.js b/test/parallel/test-http-1.0-keep-alive.js index 516a02031ef2..fa49707c24a8 100644 --- a/test/parallel/test-http-1.0-keep-alive.js +++ b/test/parallel/test-http-1.0-keep-alive.js @@ -122,7 +122,7 @@ function check(tests) { current++; if (ctx.expectClose) return; conn.removeListener('close', onclose); - conn.removeListener('data', ondata);; + conn.removeListener('data', ondata); connected(); } conn.on('data', ondata); diff --git a/test/parallel/test-http-client-timeout-agent.js b/test/parallel/test-http-client-timeout-agent.js index 51bfb8299b13..6892b38719fb 100644 --- a/test/parallel/test-http-client-timeout-agent.js +++ b/test/parallel/test-http-client-timeout-agent.js @@ -17,7 +17,7 @@ var options = { var server = http.createServer(function(req, res) { const m = /\/(.*)/.exec(req.url); const reqid = parseInt(m[1], 10); - if ( reqid % 2 ) { + if (reqid % 2) { // do not reply the request } else { res.writeHead(200, {'Content-Type': 'text/plain'}); diff --git a/test/parallel/test-http-expect-handling.js b/test/parallel/test-http-expect-handling.js new file mode 100644 index 000000000000..fd88ae0ded60 --- /dev/null +++ b/test/parallel/test-http-expect-handling.js @@ -0,0 +1,55 @@ +// Spec documentation http://httpwg.github.io/specs/rfc7231.html#header.expect +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const tests = [417, 417]; + +let testsComplete = 0; +let testIdx = 0; + +const s = http.createServer(function(req, res) { + throw new Error('this should never be executed'); +}); + +s.listen(common.PORT, nextTest); + +function nextTest() { + const options = { + port: common.PORT, + headers: { 'Expect': 'meoww' } + }; + + if (testIdx === tests.length) { + return s.close(); + } + + const test = tests[testIdx]; + + if (testIdx > 0) { + s.on('checkExpectation', common.mustCall((req, res) => { + res.statusCode = 417; + res.end(); + })); + } + + http.get(options, function(response) { + console.log('client: expected status: ' + test); + console.log('client: statusCode: ' + response.statusCode); + assert.equal(response.statusCode, test); + assert.equal(response.statusMessage, 'Expectation Failed'); + + response.on('end', function() { + testsComplete++; + testIdx++; + nextTest(); + }); + response.resume(); + }); +} + + +process.on('exit', function() { + assert.equal(2, testsComplete); +}); diff --git a/test/parallel/test-module-require-depth.js b/test/parallel/test-module-require-depth.js new file mode 100644 index 000000000000..4d2ddac151be --- /dev/null +++ b/test/parallel/test-module-require-depth.js @@ -0,0 +1,13 @@ +// Flags: --expose_internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const internalModule = require('internal/module'); + +// Module one loads two too so the expected depth for two is, well, two. +assert.strictEqual(internalModule.requireDepth, 0); +const one = require(common.fixturesDir + '/module-require-depth/one'); +const two = require(common.fixturesDir + '/module-require-depth/two'); +assert.deepStrictEqual(one, { requireDepth: 1 }); +assert.deepStrictEqual(two, { requireDepth: 2 }); +assert.strictEqual(internalModule.requireDepth, 0); diff --git a/test/parallel/test-preload.js b/test/parallel/test-preload.js index f94a7eae9424..e7d89d124c79 100644 --- a/test/parallel/test-preload.js +++ b/test/parallel/test-preload.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const path = require('path'); const child_process = require('child_process'); @@ -21,6 +21,7 @@ var fixture = function(name) { var fixtureA = fixture('printA.js'); var fixtureB = fixture('printB.js'); var fixtureC = fixture('printC.js'); +const fixtureD = fixture('define-global.js'); var fixtureThrows = fixture('throws_error4.js'); // test preloading a single module works @@ -73,6 +74,18 @@ child_process.exec(nodeBinary + ' ' assert.equal(stdout, 'A\nB\nhello\n'); }); +// test that preload works with -i +const interactive = child_process.exec(nodeBinary + ' ' + + preloadOption([fixtureD]) + + '-i', + common.mustCall(function(err, stdout, stderr) { + assert.ifError(err); + assert.strictEqual(stdout, `> 'test'\n> `); + })); + +interactive.stdin.write('a\n'); +interactive.stdin.write('process.exit()\n'); + child_process.exec(nodeBinary + ' ' + '--require ' + fixture('cluster-preload.js') + ' ' + fixture('cluster-preload-test.js'), diff --git a/test/parallel/test-process-binding.js b/test/parallel/test-process-binding.js index 5350a8c66932..722e9333aff6 100644 --- a/test/parallel/test-process-binding.js +++ b/test/parallel/test-process-binding.js @@ -12,7 +12,7 @@ assert.throws( assert.doesNotThrow(function() { process.binding('buffer'); }, function(err) { - if ( (err instanceof Error) ) { + if (err instanceof Error) { return true; } }, 'unexpected error'); diff --git a/test/parallel/test-process-hrtime.js b/test/parallel/test-process-hrtime.js index ad186a3507d1..db16be0ad9e8 100644 --- a/test/parallel/test-process-hrtime.js +++ b/test/parallel/test-process-hrtime.js @@ -24,3 +24,6 @@ function validateTuple(tuple) { assert(isFinite(v)); }); } + +const diff = process.hrtime([0, 1e9 - 1]); +assert(diff[1] >= 0); // https://github.com/nodejs/node/issues/4751 diff --git a/test/parallel/test-repl-persistent-history.js b/test/parallel/test-repl-persistent-history.js index 81e728974f17..387cef7e97a7 100644 --- a/test/parallel/test-repl-persistent-history.js +++ b/test/parallel/test-repl-persistent-history.js @@ -85,6 +85,11 @@ const tests = [ test: [UP], expected: [prompt, replDisabled, prompt] }, + { + env: { NODE_REPL_HISTORY: ' ' }, + test: [UP], + expected: [prompt, replDisabled, prompt] + }, { env: { NODE_REPL_HISTORY: '', NODE_REPL_HISTORY_FILE: enoentHistoryPath }, diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index 67bb32847bd7..e64f4aa34fd4 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -8,7 +8,7 @@ var passed = false; function PassThrough() { stream.Transform.call(this); -}; +} util.inherits(PassThrough, stream.Transform); PassThrough.prototype._transform = function(chunk, encoding, done) { this.push(chunk); @@ -17,7 +17,7 @@ PassThrough.prototype._transform = function(chunk, encoding, done) { function TestStream() { stream.Transform.call(this); -}; +} util.inherits(TestStream, stream.Transform); TestStream.prototype._transform = function(chunk, encoding, done) { if (!passed) { diff --git a/test/parallel/test-stream-pipe-without-listenerCount.js b/test/parallel/test-stream-pipe-without-listenerCount.js index d7a6a6b653a6..872be6d7be5c 100644 --- a/test/parallel/test-stream-pipe-without-listenerCount.js +++ b/test/parallel/test-stream-pipe-without-listenerCount.js @@ -16,4 +16,4 @@ r.on('error', common.mustCall(noop)); w.on('error', common.mustCall(noop)); r.pipe(w); -function noop() {}; +function noop() {} diff --git a/test/parallel/test-stream-writable-change-default-encoding.js b/test/parallel/test-stream-writable-change-default-encoding.js index d8193123d6f3..d1d4af5b824b 100644 --- a/test/parallel/test-stream-writable-change-default-encoding.js +++ b/test/parallel/test-stream-writable-change-default-encoding.js @@ -8,7 +8,7 @@ var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; -}; +} util.inherits(MyWritable, stream.Writable); diff --git a/test/parallel/test-stream-writable-decoded-encoding.js b/test/parallel/test-stream-writable-decoded-encoding.js index b5f1b4f6b73f..75d5d4247663 100644 --- a/test/parallel/test-stream-writable-decoded-encoding.js +++ b/test/parallel/test-stream-writable-decoded-encoding.js @@ -8,7 +8,7 @@ var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; -}; +} util.inherits(MyWritable, stream.Writable); @@ -17,7 +17,7 @@ MyWritable.prototype._write = function(chunk, encoding, callback) { callback(); }; -;(function decodeStringsTrue() { +(function decodeStringsTrue() { var m = new MyWritable(function(isBuffer, type, enc) { assert(isBuffer); assert.equal(type, 'object'); @@ -28,7 +28,7 @@ MyWritable.prototype._write = function(chunk, encoding, callback) { m.end(); })(); -;(function decodeStringsFalse() { +(function decodeStringsFalse() { var m = new MyWritable(function(isBuffer, type, enc) { assert(!isBuffer); assert.equal(type, 'string'); diff --git a/test/parallel/test-stream2-base64-single-char-read-end.js b/test/parallel/test-stream2-base64-single-char-read-end.js index 900e090921b7..0f9f56b3e707 100644 --- a/test/parallel/test-stream2-base64-single-char-read-end.js +++ b/test/parallel/test-stream2-base64-single-char-read-end.js @@ -17,7 +17,7 @@ src._read = function(n) { src.push(new Buffer('1')); src.push(null); }); - }; + } }; dst._write = function(chunk, enc, cb) { diff --git a/test/parallel/test-stream3-pause-then-read.js b/test/parallel/test-stream3-pause-then-read.js index e4e33738b332..0aee70f6832c 100644 --- a/test/parallel/test-stream3-pause-then-read.js +++ b/test/parallel/test-stream3-pause-then-read.js @@ -42,7 +42,7 @@ function read100() { function readn(n, then) { console.error('read %d', n); expectEndingData -= n; - ;(function read() { + (function read() { var c = r.read(n); if (!c) r.once('readable', read); diff --git a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js index c9ca3eafd64e..a26b548385e5 100644 --- a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js +++ b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js @@ -39,7 +39,7 @@ server.listen(common.PORT, common.localhostIPv4, function() { if (nbClientsEnded === 2) { server.close(); } - }; + } const client1 = net.connect({ port: common.PORT }); client1.on('end', addEndedClient); diff --git a/test/parallel/test-tls-alpn-server-client.js b/test/parallel/test-tls-alpn-server-client.js index e5d809d1489a..a9fe0b84d4ca 100644 --- a/test/parallel/test-tls-alpn-server-client.js +++ b/test/parallel/test-tls-alpn-server-client.js @@ -66,7 +66,7 @@ function runTest(clientsOptions, serverOptions, cb) { cb(results); } }); - }; + } } diff --git a/test/parallel/test-tls-multi-key.js b/test/parallel/test-tls-multi-key.js index 4c9fb4285f6d..17b409f284dc 100644 --- a/test/parallel/test-tls-multi-key.js +++ b/test/parallel/test-tls-multi-key.js @@ -35,8 +35,8 @@ var server = tls.createServer(options, function(conn) { rejectUnauthorized: false }, function() { ciphers.push(rsa.getCipher()); - ecdsa.destroy(); - rsa.destroy(); + ecdsa.end(); + rsa.end(); server.close(); }); }); diff --git a/test/parallel/test-tls-npn-server-client.js b/test/parallel/test-tls-npn-server-client.js index 211cfc7ed350..d74d65c8b03b 100644 --- a/test/parallel/test-tls-npn-server-client.js +++ b/test/parallel/test-tls-npn-server-client.js @@ -85,7 +85,7 @@ function startTest() { callback(); }); - }; + } connectClient(clientsOptions[0], function() { connectClient(clientsOptions[1], function() { diff --git a/test/parallel/test-tls-sni-option.js b/test/parallel/test-tls-sni-option.js index 510b929ae2a1..83e621333636 100644 --- a/test/parallel/test-tls-sni-option.js +++ b/test/parallel/test-tls-sni-option.js @@ -146,7 +146,7 @@ function startTest() { else connectClient(i + 1, callback); } - }; + } connectClient(0, function() { server.close(); diff --git a/test/parallel/test-tls-sni-server-client.js b/test/parallel/test-tls-sni-server-client.js index 8eb80b50e415..733713c8e72d 100644 --- a/test/parallel/test-tls-sni-server-client.js +++ b/test/parallel/test-tls-sni-server-client.js @@ -103,7 +103,7 @@ function startTest() { // Continue start(); }); - }; + } start(); } diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index 9fa087261e01..20e6138b268b 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -1569,6 +1569,6 @@ var throws = [ ]; for (var i = 0; i < throws.length; i++) { assert.throws(function() { url.format(throws[i]); }, TypeError); -}; +} assert(url.format('') === ''); assert(url.format({}) === ''); diff --git a/test/parallel/test-v8-stats.js b/test/parallel/test-v8-stats.js index eb5566fe2bc2..54140e4110fe 100644 --- a/test/parallel/test-v8-stats.js +++ b/test/parallel/test-v8-stats.js @@ -15,3 +15,22 @@ assert.deepEqual(Object.keys(s).sort(), keys); keys.forEach(function(key) { assert.equal(typeof s[key], 'number'); }); + + +const expectedHeapSpaces = [ + 'new_space', + 'old_space', + 'code_space', + 'map_space', + 'large_object_space' +]; +const heapSpaceStatistics = v8.getHeapSpaceStatistics(); +const actualHeapSpaceNames = heapSpaceStatistics.map(s => s.space_name); +assert.deepEqual(actualHeapSpaceNames.sort(), expectedHeapSpaces.sort()); +heapSpaceStatistics.forEach(heapSpace => { + assert.strictEqual(typeof heapSpace.space_name, 'string'); + assert.strictEqual(typeof heapSpace.space_size, 'number'); + assert.strictEqual(typeof heapSpace.space_used_size, 'number'); + assert.strictEqual(typeof heapSpace.space_available_size, 'number'); + assert.strictEqual(typeof heapSpace.physical_space_size, 'number'); +}); diff --git a/test/parallel/test-zlib-flush-drain.js b/test/parallel/test-zlib-flush-drain.js index f04dac9f0699..14a42e76cc38 100644 --- a/test/parallel/test-zlib-flush-drain.js +++ b/test/parallel/test-zlib-flush-drain.js @@ -33,7 +33,7 @@ deflater.flush(function(err) { }); deflater.on('drain', function() { - drainCount++;; + drainCount++; }); process.once('exit', function() { diff --git a/test/pummel/test-timers.js b/test/pummel/test-timers.js index d911beb6b092..3525c827a9e6 100644 --- a/test/pummel/test-timers.js +++ b/test/pummel/test-timers.js @@ -30,7 +30,7 @@ clearTimeout(id); setInterval(function() { interval_count += 1; - var endtime = new Date( ); + var endtime = new Date(); var diff = endtime - starttime; assert.ok(diff > 0); diff --git a/test/pummel/test-tls-server-large-request.js b/test/pummel/test-tls-server-large-request.js index d7663e936de7..cb740c63ed7d 100644 --- a/test/pummel/test-tls-server-large-request.js +++ b/test/pummel/test-tls-server-large-request.js @@ -24,7 +24,7 @@ var options = { function Mediator() { stream.Writable.call(this); this.buf = ''; -}; +} util.inherits(Mediator, stream.Writable); Mediator.prototype._write = function write(data, enc, cb) { diff --git a/test/sequential/test-child-process-fork-getconnections.js b/test/sequential/test-child-process-fork-getconnections.js index a7521f1635fb..f7bb9f5eea21 100644 --- a/test/sequential/test-child-process-fork-getconnections.js +++ b/test/sequential/test-child-process-fork-getconnections.js @@ -11,7 +11,7 @@ if (process.argv[2] === 'child') { process.on('message', function(m, socket) { function sendClosed(id) { process.send({ id: id, status: 'closed'}); - }; + } if (m.cmd === 'new') { assert(socket); @@ -82,7 +82,7 @@ if (process.argv[2] === 'child') { }); sent++; child.send({ id: i, cmd: 'close' }); - }; + } let closeEmitted = false; server.on('close', function() { diff --git a/test/sequential/test-cluster-disconnect-leak.js b/test/sequential/test-cluster-disconnect-leak.js index 33476dd427a6..a4916c95ba4e 100644 --- a/test/sequential/test-cluster-disconnect-leak.js +++ b/test/sequential/test-cluster-disconnect-leak.js @@ -1,47 +1,29 @@ 'use strict'; -// Flags: --expose-internals + +// Test fails in Node v5.4.0 and passes in v5.4.1 and newer. const common = require('../common'); -const assert = require('assert'); const net = require('net'); const cluster = require('cluster'); -const handles = require('internal/cluster').handles; -const os = require('os'); -if (common.isWindows) { - console.log('1..0 # Skipped: This test does not apply to Windows.'); - return; -} +const noop = () => {}; cluster.schedulingPolicy = cluster.SCHED_NONE; if (cluster.isMaster) { - const cpus = os.cpus().length; - const tries = cpus > 8 ? 128 : cpus * 16; - - const worker1 = cluster.fork(); - worker1.on('message', common.mustCall(() => { - worker1.disconnect(); - for (let i = 0; i < tries; ++ i) { - const w = cluster.fork(); - w.on('online', common.mustCall(w.disconnect)); - } - })); - - cluster.on('exit', common.mustCall((worker, code) => { - assert.strictEqual(code, 0, 'worker exited with error'); - }, tries + 1)); - - process.on('exit', () => { - assert.deepEqual(Object.keys(cluster.workers), []); - assert.strictEqual(Object.keys(handles).length, 0); - }); + const worker = cluster.fork(); + + // This is the important part of the test: Confirm that `disconnect` fires. + worker.on('disconnect', common.mustCall(noop)); + + // These are just some extra stuff we're checking for good measure... + worker.on('exit', common.mustCall(noop)); + cluster.on('exit', common.mustCall(noop)); + cluster.disconnect(); return; } -var server = net.createServer(); +const server = net.createServer(); -server.listen(common.PORT, function() { - process.send('listening'); -}); +server.listen(common.PORT); diff --git a/test/sequential/test-tcp-wrap-listen.js b/test/sequential/test-tcp-wrap-listen.js index 44254c3d3f39..d16069f25dbe 100644 --- a/test/sequential/test-tcp-wrap-listen.js +++ b/test/sequential/test-tcp-wrap-listen.js @@ -65,7 +65,7 @@ server.onconnection = function(err, client) { writeCount++; console.log('write ' + writeCount); maybeCloseClient(); - }; + } sliceCount++; } else { diff --git a/tools/license-builder.sh b/tools/license-builder.sh index bb350e5a8bc5..5d6b810e1234 100755 --- a/tools/license-builder.sh +++ b/tools/license-builder.sh @@ -33,7 +33,8 @@ addlicense "c-ares" "deps/cares" \ "$(sed -e '/^ \*\/$/,$d' -e '/^$/d' -e 's/^[/ ]\* *//' ${rootdir}/deps/cares/src/ares_init.c)" addlicense "HTTP Parser" "deps/http_parser" "$(cat deps/http_parser/LICENSE-MIT)" addlicense "ICU" "deps/icu" \ - "$(sed -e '1,/COPYRIGHT AND PERMISSION NOTICE/d' -e '/^
$//' ${rootdir}/deps/icu/license.html)" + "$(sed -e '1,/ICU License - ICU 1\.8\.1 and later/d' -e :a \ + -e 's/<[^>]*>//g;s/ / /g;s/ +$//;/