Skip to content

Commit 11a15d2

Browse files
test
1 parent 37aad11 commit 11a15d2

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

packages/socket.io-parser/lib/index.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,40 @@ interface DecoderReservedEvents {
135135
decoded: (packet: Packet) => void;
136136
}
137137

138+
type JSONReviver = (this: any, key: string, value: any) => any;
139+
140+
export interface DecoderOptions {
141+
/**
142+
* Custom reviver to pass down to JSON.stringify()
143+
*/
144+
reviver?: JSONReviver;
145+
/**
146+
* Maximum number of attachments per packet.
147+
* @default 3
148+
*/
149+
maxAttachments?: number;
150+
}
151+
138152
/**
139153
* A socket.io Decoder instance
140154
*
141155
* @return {Object} decoder
142156
*/
143157
export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
144158
private reconstructor: BinaryReconstructor;
159+
private opts: Required<DecoderOptions>;
145160

146161
/**
147162
* Decoder constructor
148163
*
149-
* @param {function} reviver - custom reviver to pass down to JSON.stringify
164+
* @param {function|DecoderOptions} opts - custom reviver to pass down to JSON.stringify or an options object
150165
*/
151-
constructor(private reviver?: (this: any, key: string, value: any) => any) {
166+
constructor(opts?: DecoderOptions | JSONReviver) {
152167
super();
168+
this.opts = Object.assign({
169+
reviver: undefined,
170+
maxAttachments: 3
171+
}, typeof opts === "function" ? { reviver: opts } : opts);
153172
}
154173

155174
/**
@@ -225,6 +244,9 @@ export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
225244
throw new Error("Illegal attachments");
226245
}
227246
p.attachments = Number(buf);
247+
if (p.attachments > this.opts.maxAttachments) {
248+
throw new Error("too many attachments");
249+
}
228250
}
229251

230252
// look up namespace (if any)
@@ -271,7 +293,7 @@ export class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
271293

272294
private tryParse(str) {
273295
try {
274-
return JSON.parse(str, this.reviver);
296+
return JSON.parse(str, this.opts.reviver);
275297
} catch (e) {
276298
return false;
277299
}

packages/socket.io-parser/test/parser.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,52 @@ describe("socket.io-parser", () => {
107107
}
108108
});
109109

110+
it("throws an error when receiving too many attachments", () => {
111+
const decoder = new Decoder({ maxAttachments: 2 });
112+
113+
expect(() => {
114+
decoder.add(
115+
'53-["hello",{"_placeholder":true,"num":0},{"_placeholder":true,"num":1},{"_placeholder":true,"num":2}]',
116+
);
117+
}).to.throwException(/^too many attachments$/);
118+
});
119+
120+
it("decodes with a custom reviver", (done) => {
121+
const decoder = new Decoder((key, value) => {
122+
if (key === "a") {
123+
return value.toUpperCase();
124+
} else {
125+
return value;
126+
}
127+
});
128+
129+
decoder.on("decoded", (packet) => {
130+
expect(packet.data).to.eql(["b", { a: "VAL" }]);
131+
done();
132+
});
133+
134+
decoder.add('2["b",{"a":"val"}]');
135+
});
136+
137+
it("decodes with a custom reviver (options object)", (done) => {
138+
const decoder = new Decoder({
139+
reviver: (key, value) => {
140+
if (key === "a") {
141+
return value.toUpperCase();
142+
} else {
143+
return value;
144+
}
145+
},
146+
});
147+
148+
decoder.on("decoded", (packet) => {
149+
expect(packet.data).to.eql(["b", { a: "VAL" }]);
150+
done();
151+
});
152+
153+
decoder.add('2["b",{"a":"val"}]');
154+
});
155+
110156
it("throw an error upon parsing error", () => {
111157
const isInvalidPayload = (str) =>
112158
expect(() => new Decoder().add(str)).to.throwException(

0 commit comments

Comments
 (0)