From 92c530da47111e59add9b2960fe5c34aee80828e Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Wed, 28 Feb 2018 13:36:08 +0100 Subject: [PATCH] [fix] Properly handle JSON.stringify errors (#84) JSON.stringify method throws when passed a circular object. --- index.js | 20 +++++++++++++++++--- test/parser.js | 20 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 90f9d3c..daa242c 100644 --- a/index.js +++ b/index.js @@ -113,6 +113,8 @@ exports.Decoder = Decoder; function Encoder() {} +var ERROR_PACKET = exports.ERROR + '"encode error"'; + /** * Encode a packet as a single string if non-binary, or as a * buffer sequence, depending on packet type. @@ -128,8 +130,7 @@ Encoder.prototype.encode = function(obj, callback){ if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { encodeAsBinary(obj, callback); - } - else { + } else { var encoding = encodeAsString(obj); callback([encoding]); } @@ -166,13 +167,26 @@ function encodeAsString(obj) { // json data if (null != obj.data) { - str += JSON.stringify(obj.data); + var payload = tryStringify(obj.data); + if (payload !== false) { + str += payload; + } else { + return ERROR_PACKET; + } } debug('encoded %j as %s', obj, str); return str; } +function tryStringify(str) { + try { + return JSON.stringify(str); + } catch(e){ + return false; + } +} + /** * Encode packet as 'buffer sequence' by removing blobs, and * deconstructing packet into object with placeholders and diff --git a/test/parser.js b/test/parser.js index 42179d2..652aa7f 100644 --- a/test/parser.js +++ b/test/parser.js @@ -1,8 +1,6 @@ var parser = require('../index.js'); var expect = require('expect.js'); var helpers = require('./helpers.js'); -var encode = parser.encode; -var decode = parser.decode; describe('parser', function(){ @@ -61,6 +59,24 @@ describe('parser', function(){ }); }); + it('properly handles circular objects', function() { + var a = {}; + a.b = a; + + var data = { + type: parser.EVENT, + data: a, + id: 1, + nsp: '/' + } + + var encoder = new parser.Encoder(); + + encoder.encode(data, function(encodedPackets) { + expect(encodedPackets[0]).to.be('4"encode error"'); + }); + }); + it('decodes a bad binary packet', function(){ try { var decoder = new parser.Decoder();