From a59ca5288a7e41d4810b9dbbd39f0e42891cbf4a Mon Sep 17 00:00:00 2001 From: XadillaX Date: Tue, 20 Jun 2017 18:49:03 +0800 Subject: [PATCH 1/7] repl: fix crash with large buffer tab completion If the buffer or array is too large to completion, make a dummy smallest substitute object for it and emit a warning. Fixes: https://github.com/nodejs/node/issues/3136 --- lib/repl.js | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index c6c51fd2e69426..ebbcea8f4ac45c 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -57,6 +57,7 @@ const Module = require('module'); const domain = require('domain'); const debug = util.debuglog('repl'); const errors = require('internal/errors'); +const Buffer = require('buffer').Buffer; const parentModule = module; const replMap = new WeakMap(); @@ -689,8 +690,26 @@ function intFilter(item) { return /^[A-Za-z_$]/.test(item); } -function filteredOwnPropertyNames(obj) { +const DEFAULT_PROPERTIES = { + ARRAY: Object.getOwnPropertyNames([]).filter(intFilter), + BUFFER: Object.getOwnPropertyNames(Buffer.alloc(1)).filter(intFilter) +}; + +function mayBeLargeObject(obj) { + return (Array.isArray(obj) || Buffer.isBuffer(obj)); +} + +function filteredOwnPropertyNames(obj, warning) { if (!obj) return []; + if (mayBeLargeObject(obj) && obj.length > 1e6) { + warning.message = + 'Instance is too large that the completion may missing ' + + 'some customized properties.'; + warning.type = 'REPLWarning'; + return Array.isArray(obj) ? + DEFAULT_PROPERTIES.ARRAY : + DEFAULT_PROPERTIES.BUFFER; + } return Object.getOwnPropertyNames(obj).filter(intFilter); } @@ -732,10 +751,12 @@ function complete(line, callback) { } } + var self = this; var completions; // list of completion lists, one for each inheritance "level" var completionGroups = []; + var warning = {}; var completeOn, i, group, c; @@ -843,9 +864,11 @@ function complete(line, callback) { if (this.useGlobal || vm.isContext(this.context)) { var contextProto = this.context; while (contextProto = Object.getPrototypeOf(contextProto)) { - completionGroups.push(filteredOwnPropertyNames(contextProto)); + completionGroups.push( + filteredOwnPropertyNames(contextProto, warning)); } - completionGroups.push(filteredOwnPropertyNames(this.context)); + completionGroups.push( + filteredOwnPropertyNames(this.context, warning)); addStandardGlobals(completionGroups, filter); completionGroupsLoaded(); } else { @@ -871,7 +894,7 @@ function complete(line, callback) { if (obj != null) { if (typeof obj === 'object' || typeof obj === 'function') { try { - memberGroups.push(filteredOwnPropertyNames(obj)); + memberGroups.push(filteredOwnPropertyNames(obj, warning)); } catch (ex) { // Probably a Proxy object without `getOwnPropertyNames` trap. // We simply ignore it here, as we don't want to break the @@ -889,7 +912,7 @@ function complete(line, callback) { p = obj.constructor ? obj.constructor.prototype : null; } while (p !== null) { - memberGroups.push(filteredOwnPropertyNames(p)); + memberGroups.push(filteredOwnPropertyNames(p, warning)); p = Object.getPrototypeOf(p); // Circular refs possible? Let's guard against that. sentinel--; @@ -928,6 +951,16 @@ function complete(line, callback) { function completionGroupsLoaded(err) { if (err) throw err; + if (warning.type) { + self._writeToOutput('\r\n'); + process.emitWarning( + warning.message, + warning.type, + undefined, + undefined, + true); + } + // Filter, sort (within each group), uniq and merge the completion groups. if (completionGroups.length && filter) { var newCompletionGroups = []; From c08093e3e3ef8238bd09d0ff60d46ac67a2d7449 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Tue, 20 Jun 2017 22:56:41 +0800 Subject: [PATCH 2/7] update after reviewing --- lib/repl.js | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index ebbcea8f4ac45c..1461b9df35a63d 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -699,13 +699,18 @@ function mayBeLargeObject(obj) { return (Array.isArray(obj) || Buffer.isBuffer(obj)); } -function filteredOwnPropertyNames(obj, warning) { +function filteredOwnPropertyNames(obj) { if (!obj) return []; if (mayBeLargeObject(obj) && obj.length > 1e6) { - warning.message = + process.stdout.write('\r\n'); + process.emitWarning( 'Instance is too large that the completion may missing ' + - 'some customized properties.'; - warning.type = 'REPLWarning'; + 'some customized properties.', + 'REPLWarning', + undefined, + undefined, + true); + return Array.isArray(obj) ? DEFAULT_PROPERTIES.ARRAY : DEFAULT_PROPERTIES.BUFFER; @@ -751,12 +756,10 @@ function complete(line, callback) { } } - var self = this; var completions; // list of completion lists, one for each inheritance "level" var completionGroups = []; - var warning = {}; var completeOn, i, group, c; @@ -864,11 +867,9 @@ function complete(line, callback) { if (this.useGlobal || vm.isContext(this.context)) { var contextProto = this.context; while (contextProto = Object.getPrototypeOf(contextProto)) { - completionGroups.push( - filteredOwnPropertyNames(contextProto, warning)); + completionGroups.push(filteredOwnPropertyNames(contextProto)); } - completionGroups.push( - filteredOwnPropertyNames(this.context, warning)); + completionGroups.push(filteredOwnPropertyNames(this.context)); addStandardGlobals(completionGroups, filter); completionGroupsLoaded(); } else { @@ -894,7 +895,7 @@ function complete(line, callback) { if (obj != null) { if (typeof obj === 'object' || typeof obj === 'function') { try { - memberGroups.push(filteredOwnPropertyNames(obj, warning)); + memberGroups.push(filteredOwnPropertyNames(obj)); } catch (ex) { // Probably a Proxy object without `getOwnPropertyNames` trap. // We simply ignore it here, as we don't want to break the @@ -912,7 +913,7 @@ function complete(line, callback) { p = obj.constructor ? obj.constructor.prototype : null; } while (p !== null) { - memberGroups.push(filteredOwnPropertyNames(p, warning)); + memberGroups.push(filteredOwnPropertyNames(p)); p = Object.getPrototypeOf(p); // Circular refs possible? Let's guard against that. sentinel--; @@ -951,16 +952,6 @@ function complete(line, callback) { function completionGroupsLoaded(err) { if (err) throw err; - if (warning.type) { - self._writeToOutput('\r\n'); - process.emitWarning( - warning.message, - warning.type, - undefined, - undefined, - true); - } - // Filter, sort (within each group), uniq and merge the completion groups. if (completionGroups.length && filter) { var newCompletionGroups = []; From 402070d53926d79e858c179398f696358bf51bd4 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Tue, 20 Jun 2017 23:17:25 +0800 Subject: [PATCH 3/7] add some test cases --- test/parallel/test-repl-tab-complete.js | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 6df0d81f8d7cc0..6a30098d39b973 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -23,6 +23,7 @@ const common = require('../common'); const assert = require('assert'); +const Buffer = require('buffer').Buffer; // We have to change the directory to ../fixtures before requiring repl // in order to make the tests for completion of node_modules work properly @@ -305,6 +306,34 @@ testMe.complete('.b', common.mustCall((error, data) => { assert.deepStrictEqual(data, [['break'], 'b']); })); +// tab completion for large buffer +[ Array, Buffer ].forEach((type) => { + putIn.run(['.clear']); + + if (type === Array) { + putIn.run(['var ele = []; for (let i = 0; i < 1e7; i++) ele.push(i);']); + } else { + putIn.run(['var ele = Buffer.alloc(1e8)']); + } + + common.hijackStderr(common.mustCall((err) => { + process.nextTick(function() { + assert.ok(/REPLWarning: Instance is too large that the/.test(err)); + }); + })); + testMe.complete('ele.', common.mustCall((err, data) => { + common.restoreStderr(); + assert.ifError(err); + + const ele = (type === Array) ? [] : Buffer.alloc(1); + + data[0].forEach((key) => { + if (!key) return; + assert.notStrictEqual(ele[key.substr(4)], undefined); + }); + })); +}); + const testNonGlobal = repl.start({ input: putIn, output: putIn, From 59649f38418c9e6cfcefca8abea0acb8d93ce9b0 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Tue, 20 Jun 2017 23:32:59 +0800 Subject: [PATCH 4/7] use this._writeToOutput to instead of process.stdout.write --- lib/repl.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 1461b9df35a63d..1e6063cc79203d 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -702,7 +702,7 @@ function mayBeLargeObject(obj) { function filteredOwnPropertyNames(obj) { if (!obj) return []; if (mayBeLargeObject(obj) && obj.length > 1e6) { - process.stdout.write('\r\n'); + this._writeToOutput('\r\n'); process.emitWarning( 'Instance is too large that the completion may missing ' + 'some customized properties.', @@ -756,6 +756,7 @@ function complete(line, callback) { } } + var self = this; var completions; // list of completion lists, one for each inheritance "level" @@ -867,9 +868,11 @@ function complete(line, callback) { if (this.useGlobal || vm.isContext(this.context)) { var contextProto = this.context; while (contextProto = Object.getPrototypeOf(contextProto)) { - completionGroups.push(filteredOwnPropertyNames(contextProto)); + completionGroups.push( + filteredOwnPropertyNames.call(this, contextProto)); } - completionGroups.push(filteredOwnPropertyNames(this.context)); + completionGroups.push( + filteredOwnPropertyNames.call(this, this.context)); addStandardGlobals(completionGroups, filter); completionGroupsLoaded(); } else { @@ -895,7 +898,7 @@ function complete(line, callback) { if (obj != null) { if (typeof obj === 'object' || typeof obj === 'function') { try { - memberGroups.push(filteredOwnPropertyNames(obj)); + memberGroups.push(filteredOwnPropertyNames.call(self, obj)); } catch (ex) { // Probably a Proxy object without `getOwnPropertyNames` trap. // We simply ignore it here, as we don't want to break the @@ -913,7 +916,7 @@ function complete(line, callback) { p = obj.constructor ? obj.constructor.prototype : null; } while (p !== null) { - memberGroups.push(filteredOwnPropertyNames(p)); + memberGroups.push(filteredOwnPropertyNames.call(self, p)); p = Object.getPrototypeOf(p); // Circular refs possible? Let's guard against that. sentinel--; From 876ab6ef2e292e0f52ec484e2ccc73d684b7f646 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Wed, 21 Jun 2017 10:45:04 +0800 Subject: [PATCH 5/7] update after reviewing again --- lib/repl.js | 17 ++++++++--------- test/parallel/test-repl-tab-complete.js | 7 ++++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 1e6063cc79203d..11832508414180 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -690,7 +690,7 @@ function intFilter(item) { return /^[A-Za-z_$]/.test(item); } -const DEFAULT_PROPERTIES = { +const defaultProperties = { ARRAY: Object.getOwnPropertyNames([]).filter(intFilter), BUFFER: Object.getOwnPropertyNames(Buffer.alloc(1)).filter(intFilter) }; @@ -704,16 +704,16 @@ function filteredOwnPropertyNames(obj) { if (mayBeLargeObject(obj) && obj.length > 1e6) { this._writeToOutput('\r\n'); process.emitWarning( - 'Instance is too large that the completion may missing ' + - 'some customized properties.', + 'Instance is too large so the completion may missing some custom ' + + 'properties.', 'REPLWarning', undefined, undefined, true); return Array.isArray(obj) ? - DEFAULT_PROPERTIES.ARRAY : - DEFAULT_PROPERTIES.BUFFER; + defaultProperties.ARRAY : + defaultProperties.BUFFER; } return Object.getOwnPropertyNames(obj).filter(intFilter); } @@ -756,7 +756,6 @@ function complete(line, callback) { } } - var self = this; var completions; // list of completion lists, one for each inheritance "level" @@ -892,13 +891,13 @@ function complete(line, callback) { } } else { const evalExpr = `try { ${expr} } catch (e) {}`; - this.eval(evalExpr, this.context, 'repl', function doEval(e, obj) { + this.eval(evalExpr, this.context, 'repl', (e, obj) => { // if (e) console.log(e); if (obj != null) { if (typeof obj === 'object' || typeof obj === 'function') { try { - memberGroups.push(filteredOwnPropertyNames.call(self, obj)); + memberGroups.push(filteredOwnPropertyNames.call(this, obj)); } catch (ex) { // Probably a Proxy object without `getOwnPropertyNames` trap. // We simply ignore it here, as we don't want to break the @@ -916,7 +915,7 @@ function complete(line, callback) { p = obj.constructor ? obj.constructor.prototype : null; } while (p !== null) { - memberGroups.push(filteredOwnPropertyNames.call(self, p)); + memberGroups.push(filteredOwnPropertyNames.call(this, p)); p = Object.getPrototypeOf(p); // Circular refs possible? Let's guard against that. sentinel--; diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 6a30098d39b973..dbd3473604518e 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -23,7 +23,6 @@ const common = require('../common'); const assert = require('assert'); -const Buffer = require('buffer').Buffer; // We have to change the directory to ../fixtures before requiring repl // in order to make the tests for completion of node_modules work properly @@ -307,6 +306,8 @@ testMe.complete('.b', common.mustCall((error, data) => { })); // tab completion for large buffer +const warningRegEx = + /\(node:\d+\) REPLWarning: Instance is too large so the completion may missing some custom properties\./; [ Array, Buffer ].forEach((type) => { putIn.run(['.clear']); @@ -317,8 +318,8 @@ testMe.complete('.b', common.mustCall((error, data) => { } common.hijackStderr(common.mustCall((err) => { - process.nextTick(function() { - assert.ok(/REPLWarning: Instance is too large that the/.test(err)); + process.nextTick(() => { + assert.ok(warningRegEx.test(err)); }); })); testMe.complete('ele.', common.mustCall((err, data) => { From 11db6628323f885ed356cdae5d7b7a7ff4eba6b6 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Wed, 21 Jun 2017 15:08:09 +0800 Subject: [PATCH 6/7] update after @TimothyGu's reviewing --- lib/repl.js | 58 +++++++++++++++++++++---- test/parallel/test-repl-tab-complete.js | 40 +++++++++++++++-- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 11832508414180..309634760aa68b 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -690,18 +690,60 @@ function intFilter(item) { return /^[A-Za-z_$]/.test(item); } -const defaultProperties = { - ARRAY: Object.getOwnPropertyNames([]).filter(intFilter), - BUFFER: Object.getOwnPropertyNames(Buffer.alloc(1)).filter(intFilter) -}; +const defaultProperties = [ + [ Array, Object.getOwnPropertyNames([]).filter(intFilter) ], + [ Buffer, Object.getOwnPropertyNames(Buffer.alloc(0)).filter(intFilter) ], + + [ Uint8Array, + Object.getOwnPropertyNames(new Uint8Array()).filter(intFilter) ], + [ Uint16Array, + Object.getOwnPropertyNames(new Uint16Array()).filter(intFilter) ], + [ Uint32Array, + Object.getOwnPropertyNames(new Uint32Array()).filter(intFilter) ], + [ + Uint8ClampedArray, + Object.getOwnPropertyNames(new Uint8ClampedArray()).filter(intFilter) ], + [ Int8Array, + Object.getOwnPropertyNames(new Int8Array()).filter(intFilter) ], + [ Int16Array, + Object.getOwnPropertyNames(new Int16Array()).filter(intFilter) ], + [ Int32Array, + Object.getOwnPropertyNames(new Int32Array()).filter(intFilter) ], + [ Float32Array, + Object.getOwnPropertyNames(new Float32Array()).filter(intFilter) ], + [ Float64Array, + Object.getOwnPropertyNames(new Float64Array()).filter(intFilter) ] +]; +const ARRAY_LENGTH_THRESHOLD = 1e6; function mayBeLargeObject(obj) { - return (Array.isArray(obj) || Buffer.isBuffer(obj)); + // `Buffer.prototype` passes the `Buffer.isBuffer` and + // `instanceof Uint8Array`. + // + // Refs: https://github.com/nodejs/node/pull/11961 + if (obj === Buffer.prototype) return null; + + for (const type of defaultProperties) { + var typeMatch; + if (type[0] === Array) { + typeMatch = Array.isArray(obj); + } else if (type[0] === Buffer) { + typeMatch = Buffer.isBuffer(obj); + } else { + typeMatch = obj instanceof type[0]; + } + + if (typeMatch) { + return obj.length > ARRAY_LENGTH_THRESHOLD ? type[1] : null; + } + } + return null; } function filteredOwnPropertyNames(obj) { if (!obj) return []; - if (mayBeLargeObject(obj) && obj.length > 1e6) { + const fakeProperties = mayBeLargeObject(obj); + if (fakeProperties !== null) { this._writeToOutput('\r\n'); process.emitWarning( 'Instance is too large so the completion may missing some custom ' + @@ -711,9 +753,7 @@ function filteredOwnPropertyNames(obj) { undefined, true); - return Array.isArray(obj) ? - defaultProperties.ARRAY : - defaultProperties.BUFFER; + return fakeProperties; } return Object.getOwnPropertyNames(obj).filter(intFilter); } diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index dbd3473604518e..3734f55efc7467 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -308,13 +308,33 @@ testMe.complete('.b', common.mustCall((error, data) => { // tab completion for large buffer const warningRegEx = /\(node:\d+\) REPLWarning: Instance is too large so the completion may missing some custom properties\./; -[ Array, Buffer ].forEach((type) => { +[ + Array, + Buffer, + + Uint8Array, + Uint16Array, + Uint32Array, + + Uint8ClampedArray, + Int8Array, + Int16Array, + Int32Array, + Float32Array, + Float64Array, +].forEach((type) => { putIn.run(['.clear']); if (type === Array) { - putIn.run(['var ele = []; for (let i = 0; i < 1e7; i++) ele.push(i);']); + putIn.run([ + 'var ele = [];', + 'for (let i = 0; i < 1e6 + 1; i++) ele[i] = 0;', + 'ele.biu = 1;' + ]); + } else if (type === Buffer) { + putIn.run(['var ele = Buffer.alloc(1e6 + 1); ele.biu = 1;']); } else { - putIn.run(['var ele = Buffer.alloc(1e8)']); + putIn.run([`var ele = new ${type.name}(1e6 + 1); ele.biu = 1;`]); } common.hijackStderr(common.mustCall((err) => { @@ -326,15 +346,27 @@ const warningRegEx = common.restoreStderr(); assert.ifError(err); - const ele = (type === Array) ? [] : Buffer.alloc(1); + const ele = (type === Array) ? + [] : + (type === Buffer ? + Buffer.alloc(0) : + new type(0)); data[0].forEach((key) => { if (!key) return; assert.notStrictEqual(ele[key.substr(4)], undefined); }); + + // no `biu` + assert.strictEqual(data.indexOf('ele.biu'), -1); })); }); +// check Buffer.prototype.length not crashing. +// Refs: Refs: https://github.com/nodejs/node/pull/11961 +putIn.run['.clear']; +testMe.complete('Buffer.prototype.', common.mustCall()); + const testNonGlobal = repl.start({ input: putIn, output: putIn, From 573e25295137d0c9e7f3f620b8f2f9dfaef525d0 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Wed, 21 Jun 2017 19:30:26 +0800 Subject: [PATCH 7/7] update after reviewing again --- lib/repl.js | 53 ++++--------------------- test/parallel/test-repl-tab-complete.js | 9 +++-- 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 309634760aa68b..83d64b0548db15 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -57,7 +57,6 @@ const Module = require('module'); const domain = require('domain'); const debug = util.debuglog('repl'); const errors = require('internal/errors'); -const Buffer = require('buffer').Buffer; const parentModule = module; const replMap = new WeakMap(); @@ -690,53 +689,15 @@ function intFilter(item) { return /^[A-Za-z_$]/.test(item); } -const defaultProperties = [ - [ Array, Object.getOwnPropertyNames([]).filter(intFilter) ], - [ Buffer, Object.getOwnPropertyNames(Buffer.alloc(0)).filter(intFilter) ], - - [ Uint8Array, - Object.getOwnPropertyNames(new Uint8Array()).filter(intFilter) ], - [ Uint16Array, - Object.getOwnPropertyNames(new Uint16Array()).filter(intFilter) ], - [ Uint32Array, - Object.getOwnPropertyNames(new Uint32Array()).filter(intFilter) ], - [ - Uint8ClampedArray, - Object.getOwnPropertyNames(new Uint8ClampedArray()).filter(intFilter) ], - [ Int8Array, - Object.getOwnPropertyNames(new Int8Array()).filter(intFilter) ], - [ Int16Array, - Object.getOwnPropertyNames(new Int16Array()).filter(intFilter) ], - [ Int32Array, - Object.getOwnPropertyNames(new Int32Array()).filter(intFilter) ], - [ Float32Array, - Object.getOwnPropertyNames(new Float32Array()).filter(intFilter) ], - [ Float64Array, - Object.getOwnPropertyNames(new Float64Array()).filter(intFilter) ] -]; const ARRAY_LENGTH_THRESHOLD = 1e6; function mayBeLargeObject(obj) { - // `Buffer.prototype` passes the `Buffer.isBuffer` and - // `instanceof Uint8Array`. - // - // Refs: https://github.com/nodejs/node/pull/11961 - if (obj === Buffer.prototype) return null; - - for (const type of defaultProperties) { - var typeMatch; - if (type[0] === Array) { - typeMatch = Array.isArray(obj); - } else if (type[0] === Buffer) { - typeMatch = Buffer.isBuffer(obj); - } else { - typeMatch = obj instanceof type[0]; - } - - if (typeMatch) { - return obj.length > ARRAY_LENGTH_THRESHOLD ? type[1] : null; - } + if (Array.isArray(obj)) { + return obj.length > ARRAY_LENGTH_THRESHOLD ? ['length'] : null; + } else if (utilBinding.isTypedArray(obj)) { + return obj.length > ARRAY_LENGTH_THRESHOLD ? [] : null; } + return null; } @@ -746,8 +707,8 @@ function filteredOwnPropertyNames(obj) { if (fakeProperties !== null) { this._writeToOutput('\r\n'); process.emitWarning( - 'Instance is too large so the completion may missing some custom ' + - 'properties.', + 'The current array, Buffer or TypedArray has too many entries. ' + + 'Certain properties may be missing from completion output.', 'REPLWarning', undefined, undefined, diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 3734f55efc7467..f1bc2d40096f2f 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -306,8 +306,11 @@ testMe.complete('.b', common.mustCall((error, data) => { })); // tab completion for large buffer -const warningRegEx = - /\(node:\d+\) REPLWarning: Instance is too large so the completion may missing some custom properties\./; +const warningRegEx = new RegExp( + '\\(node:\\d+\\) REPLWarning: The current array, Buffer or TypedArray has ' + + 'too many entries\\. Certain properties may be missing from completion ' + + 'output\\.'); + [ Array, Buffer, @@ -363,7 +366,7 @@ const warningRegEx = }); // check Buffer.prototype.length not crashing. -// Refs: Refs: https://github.com/nodejs/node/pull/11961 +// Refs: https://github.com/nodejs/node/pull/11961 putIn.run['.clear']; testMe.complete('Buffer.prototype.', common.mustCall());