diff --git a/lib/internal/inspect-protocol.js b/lib/internal/inspect-protocol.js index aeb60f2..75c6e0a 100644 --- a/lib/internal/inspect-protocol.js +++ b/lib/internal/inspect-protocol.js @@ -150,7 +150,7 @@ function decodeFrameHybi17(data) { default: // Nothing. We already have the right size. } - if ((dataAvailable - payloadOffset) < 0) return notComplete; + if ((dataAvailable - payloadOffset - payloadLength) < 0) return notComplete; const payloadEnd = payloadOffset + payloadLength; return { @@ -175,17 +175,29 @@ class Client extends EventEmitter { this._unprocessed = Buffer.concat([this._unprocessed, chunk]); while (this._unprocessed.length > 2) { - const { closed, payload, rest } = decodeFrameHybi17(this._unprocessed); + const { closed, payload: payloadBuffer, rest } = decodeFrameHybi17(this._unprocessed); this._unprocessed = rest; if (closed) { this.reset(); return; } - if (payload === null) break; + if (payloadBuffer === null) break; + + const payloadStr = payloadBuffer.toString(); + debuglog('< %s', payloadStr); + if (payloadStr[0] !== '{' || payloadStr[payloadStr.length - 1] !== '}') { + throw new Error(`Payload does not look like JSON: ${payloadStr}`); + } + let payload; + try { + payload = JSON.parse(payloadStr); + } catch (parseError) { + parseError.string = payloadStr; + throw parseError; + } - debuglog('< %s', payload); - const { id, method, params, result, error } = JSON.parse(payload.toString()); + const { id, method, params, result, error } = payload; if (id) { const handler = this._pending[id]; if (handler) { @@ -196,7 +208,7 @@ class Client extends EventEmitter { this.emit('debugEvent', method, params); this.emit(method, params); } else { - throw new Error(`Unsupported response: ${payload.toString()}`); + throw new Error(`Unsupported response: ${payloadStr}`); } } } diff --git a/test/cli/profile.test.js b/test/cli/profile.test.js new file mode 100644 index 0000000..673b946 --- /dev/null +++ b/test/cli/profile.test.js @@ -0,0 +1,26 @@ +'use strict'; +const { test } = require('tap'); + +const startCLI = require('./start-cli'); + +test('profiles', (t) => { + const cli = startCLI(['examples/empty.js']); + + function onFatal(error) { + cli.quit(); + throw error; + } + + return cli.waitFor(/break/) + .then(() => cli.waitForPrompt()) + .then(() => cli.command('exec console.profile()')) + .then(() => { + t.match(cli.output, 'undefined'); + }) + .then(() => cli.command('exec console.profileEnd()')) + .then(() => { + t.match(cli.output, 'undefined'); + }) + .then(() => cli.quit()) + .then(null, onFatal); +});