From e9f580195619f715580d324c4bd4e8779312dd60 Mon Sep 17 00:00:00 2001 From: ProbablePrime Date: Thu, 8 Jun 2017 18:19:33 +0200 Subject: [PATCH 1/3] handle circular references --- package.json | 5 +++-- src/wire/Socket.spec.ts | 15 +++++++++++++++ src/wire/Socket.ts | 6 +++++- types/json-stringify-safe.d.ts | 10 ++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 types/json-stringify-safe.d.ts diff --git a/package.json b/package.json index 519c6e2..9cbe0b8 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mocha": "^3.0.2", "node-fetch": "^1.6.3", "nodemon": "^1.11.0", - "rimraf": "^2.6.0", + "rimraf": "^2.6.1", "sinon": "^2.2.0", "sinon-chai": "^2.8.0", "ts-node": "^2.0.0", @@ -70,6 +70,7 @@ "ws": "^1.1.1" }, "dependencies": { - "deepmerge": "^1.3.2" + "deepmerge": "^1.3.2", + "json-stringify-safe": "^5.0.1" } } diff --git a/src/wire/Socket.spec.ts b/src/wire/Socket.spec.ts index fa956f1..22517b4 100644 --- a/src/wire/Socket.spec.ts +++ b/src/wire/Socket.spec.ts @@ -226,6 +226,21 @@ describe('socket', () => { }); }); + it('handles circular references', () => { + ws.on('message', payload => { + expect(payload.params.bar).to.not.exist; + assertAndReplyTo(payload); + }); + const params: any = { + foo: 'bar', + }; + params.bar = params; + return socket.execute('hello', params) + .then(res => { + expect(res).to.equal('hi'); + }); + }); + it('emits a method sent to it', done => { ws.send(JSON.stringify(METHOD)); socket.on('method', (method: Method) => { diff --git a/src/wire/Socket.ts b/src/wire/Socket.ts index 78c756e..79f64dc 100644 --- a/src/wire/Socket.ts +++ b/src/wire/Socket.ts @@ -7,6 +7,8 @@ import { resolveOn } from '../util'; import { Method, Packet, PacketState, Reply } from './packets'; import { ExponentialReconnectionPolicy, IReconnectionPolicy } from './reconnection'; +import stringify = require('json-stringify-safe'); //tslint:disable-line + /** * Close codes that are deemed to be recoverable by the reconnection policy */ @@ -339,7 +341,9 @@ export class InteractiveSocket extends EventEmitter { } private sendRaw(packet: any) { - const data = JSON.stringify(packet); + // The last argument here replaces + // any circular references with nothing, effectively truncating them + const data = stringify(packet, null, 0, () => {/** */}); const payload = data; this.emit('send', payload); diff --git a/types/json-stringify-safe.d.ts b/types/json-stringify-safe.d.ts new file mode 100644 index 0000000..4ff9e08 --- /dev/null +++ b/types/json-stringify-safe.d.ts @@ -0,0 +1,10 @@ +declare module 'json-stringify-safe' { + function stringify( + obj: object, + replacer?: (number | string)[] | null, + space?: string | number, + decycler: (key:string, value: any) => any + ): string + + export = stringify; +} From 3ee76174519ec1ae3c3ad4c226366d2b358c035c Mon Sep 17 00:00:00 2001 From: ProbablePrime Date: Thu, 8 Jun 2017 18:47:12 +0200 Subject: [PATCH 2/3] tweaks --- src/wire/Socket.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wire/Socket.spec.ts b/src/wire/Socket.spec.ts index 22517b4..18ccd23 100644 --- a/src/wire/Socket.spec.ts +++ b/src/wire/Socket.spec.ts @@ -227,14 +227,14 @@ describe('socket', () => { }); it('handles circular references', () => { - ws.on('message', payload => { - expect(payload.params.bar).to.not.exist; - assertAndReplyTo(payload); - }); const params: any = { foo: 'bar', }; params.bar = params; + ws.on('message', payload => { + assertAndReplyTo(payload); + }); + return socket.execute('hello', params) .then(res => { expect(res).to.equal('hi'); From f30e000687a81baae50f973875e3ada35202a1d7 Mon Sep 17 00:00:00 2001 From: ProbablePrime Date: Thu, 8 Jun 2017 18:49:17 +0200 Subject: [PATCH 3/3] adjust comments less waffle --- src/wire/Socket.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wire/Socket.ts b/src/wire/Socket.ts index 79f64dc..5aa8acb 100644 --- a/src/wire/Socket.ts +++ b/src/wire/Socket.ts @@ -341,8 +341,7 @@ export class InteractiveSocket extends EventEmitter { } private sendRaw(packet: any) { - // The last argument here replaces - // any circular references with nothing, effectively truncating them + // Replace circular references with nothing. const data = stringify(packet, null, 0, () => {/** */}); const payload = data;