Browse Source

repl: fix stack trace column number in strict mode

On strict mode, "'use strict'; void 0; " is added as prefix
in order to prevent "use strict" as the result value
for let/const statements. It causes wrong column number in
stack trace.

PR-URL: https://github.com/nodejs/node/pull/5416
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
process-exit-stdio-flushing
Prince J Wesley 9 years ago
committed by Roman Reiss
parent
commit
40d57b714e
  1. 6
      lib/repl.js
  2. 23
      test/parallel/test-repl.js

6
lib/repl.js

@ -228,7 +228,7 @@ function REPLServer(prompt,
(self.replMode === exports.REPL_MODE_STRICT || retry)) { (self.replMode === exports.REPL_MODE_STRICT || retry)) {
// "void 0" keeps the repl from returning "use strict" as the // "void 0" keeps the repl from returning "use strict" as the
// result value for let/const statements. // result value for let/const statements.
code = `'use strict'; void 0; ${code}`; code = `'use strict'; void 0;\n${code}`;
} }
var script = vm.createScript(code, { var script = vm.createScript(code, {
filename: file, filename: file,
@ -287,6 +287,10 @@ function REPLServer(prompt,
debug('domain error'); debug('domain error');
const top = replMap.get(self); const top = replMap.get(self);
internalUtil.decorateErrorStack(e); internalUtil.decorateErrorStack(e);
if (e.stack && self.replMode === exports.REPL_MODE_STRICT) {
e.stack = e.stack.replace(/(\s+at\s+repl:)(\d+)/,
(_, pre, line) => pre + (line - 1));
}
top.outputStream.write((e.stack || e) + '\n'); top.outputStream.write((e.stack || e) + '\n');
top.lineParser.reset(); top.lineParser.reset();
top.bufferedCommand = ''; top.bufferedCommand = '';

23
test/parallel/test-repl.js

@ -15,7 +15,7 @@ const prompt_npm = 'npm should be run outside of the ' +
'node repl, in your normal shell.\n' + 'node repl, in your normal shell.\n' +
'(Press Control-D to exit.)\n'; '(Press Control-D to exit.)\n';
const expect_npm = prompt_npm + prompt_unix; const expect_npm = prompt_npm + prompt_unix;
var server_tcp, server_unix, client_tcp, client_unix, timer; var server_tcp, server_unix, client_tcp, client_unix, timer, replServer;
// absolute path to test/fixtures/a.js // absolute path to test/fixtures/a.js
@ -48,9 +48,17 @@ function clean_up() {
clearTimeout(timer); clearTimeout(timer);
} }
function strict_mode_error_test() {
send_expect([
{ client: client_unix, send: 'ref = 1',
expect: /^ReferenceError:\sref\sis\snot\sdefined\n\s+at\srepl:1:5/ },
]);
}
function error_test() { function error_test() {
// The other stuff is done so reuse unix socket // The other stuff is done so reuse unix socket
var read_buffer = ''; var read_buffer = '';
var run_strict_test = true;
client_unix.removeAllListeners('data'); client_unix.removeAllListeners('data');
client_unix.on('data', function(data) { client_unix.on('data', function(data) {
@ -72,6 +80,10 @@ function error_test() {
read_buffer = ''; read_buffer = '';
if (client_unix.list && client_unix.list.length > 0) { if (client_unix.list && client_unix.list.length > 0) {
send_expect(client_unix.list); send_expect(client_unix.list);
} else if (run_strict_test) {
replServer.replMode = repl.REPL_MODE_STRICT;
run_strict_test = false;
strict_mode_error_test();
} else { } else {
console.error('End of Error test, running TCP test.'); console.error('End of Error test, running TCP test.');
tcp_test(); tcp_test();
@ -83,6 +95,10 @@ function error_test() {
read_buffer = ''; read_buffer = '';
if (client_unix.list && client_unix.list.length > 0) { if (client_unix.list && client_unix.list.length > 0) {
send_expect(client_unix.list); send_expect(client_unix.list);
} else if (run_strict_test) {
replServer.replMode = repl.REPL_MODE_STRICT;
run_strict_test = false;
strict_mode_error_test();
} else { } else {
console.error('End of Error test, running TCP test.\n'); console.error('End of Error test, running TCP test.\n');
tcp_test(); tcp_test();
@ -381,12 +397,13 @@ function unix_test() {
socket.end(); socket.end();
}); });
repl.start({ replServer = repl.start({
prompt: prompt_unix, prompt: prompt_unix,
input: socket, input: socket,
output: socket, output: socket,
useGlobal: true useGlobal: true
}).context.message = message; });
replServer.context.message = message;
}); });
server_unix.on('listening', function() { server_unix.on('listening', function() {

Loading…
Cancel
Save