socket.io-parser
4.2.44.2.6
~
Modified (13 files)
Index: package/LICENSE
===================================================================
--- package/LICENSE
+++ package/LICENSE
@@ -1,7 +1,7 @@
(The MIT License)
-Copyright (c) 2014 Guillermo Rauch <[email protected]>
+Copyright (c) 2014-present Guillermo Rauch and Socket.IO contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the 'Software'), to deal in
the Software without restriction, including without limitation the rights to Index: package/build/cjs/binary.js
===================================================================
--- package/build/cjs/binary.js
+++ package/build/cjs/binary.js
@@ -1,7 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-exports.reconstructPacket = exports.deconstructPacket = void 0;
+exports.deconstructPacket = deconstructPacket;
+exports.reconstructPacket = reconstructPacket;
const is_binary_js_1 = require("./is-binary.js");
/**
* Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.
*
@@ -16,9 +17,8 @@
pack.data = _deconstructPacket(packetData, buffers);
pack.attachments = buffers.length; // number of binary 'attachments'
return { packet: pack, buffers: buffers };
}
-exports.deconstructPacket = deconstructPacket;
function _deconstructPacket(data, buffers) {
if (!data)
return data;
if ((0, is_binary_js_1.isBinary)(data)) {
@@ -56,9 +56,8 @@
packet.data = _reconstructPacket(packet.data, buffers);
delete packet.attachments; // no longer useful
return packet;
}
-exports.reconstructPacket = reconstructPacket;
function _reconstructPacket(data, buffers) {
if (!data)
return data;
if (data && data._placeholder === true) { Index: package/build/cjs/index.js
===================================================================
--- package/build/cjs/index.js
+++ package/build/cjs/index.js
@@ -1,7 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Decoder = exports.Encoder = exports.PacketType = exports.protocol = void 0;
+exports.isPacketValid = isPacketValid;
const component_emitter_1 = require("@socket.io/component-emitter");
const binary_js_1 = require("./binary.js");
const is_binary_js_1 = require("./is-binary.js");
const debug_1 = require("debug"); // debug()
@@ -9,13 +10,13 @@
/**
* These strings must not be used as event names, as they have a special meaning.
*/
const RESERVED_EVENTS = [
- "connect",
- "connect_error",
- "disconnect",
- "disconnecting",
- "newListener",
+ "connect", // used on the client side
+ "connect_error", // used on the client side
+ "disconnect", // used on both sides
+ "disconnecting", // used on the server side
+ "newListener", // used by the Node.js EventEmitter
"removeListener", // used by the Node.js EventEmitter
];
/**
* Protocol version.
@@ -31,9 +32,9 @@
PacketType[PacketType["ACK"] = 3] = "ACK";
PacketType[PacketType["CONNECT_ERROR"] = 4] = "CONNECT_ERROR";
PacketType[PacketType["BINARY_EVENT"] = 5] = "BINARY_EVENT";
PacketType[PacketType["BINARY_ACK"] = 6] = "BINARY_ACK";
-})(PacketType = exports.PacketType || (exports.PacketType = {}));
+})(PacketType || (exports.PacketType = PacketType = {}));
/**
* A socket.io Encoder instance
*/
class Encoder {
@@ -107,26 +108,23 @@
return buffers; // write all the buffers
}
}
exports.Encoder = Encoder;
-// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
-function isObject(value) {
- return Object.prototype.toString.call(value) === "[object Object]";
-}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
class Decoder extends component_emitter_1.Emitter {
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver) {
+ constructor(opts) {
super();
- this.reviver = reviver;
+ this.opts = Object.assign({
+ reviver: undefined,
+ maxAttachments: 10,
+ }, typeof opts === "function" ? { reviver: opts } : opts);
}
/**
* Decodes an encoded packet string into packet JSON.
*
@@ -195,9 +193,16 @@
const buf = str.substring(start, i);
if (buf != Number(buf) || str.charAt(i) !== "-") {
throw new Error("Illegal attachments");
}
- p.attachments = Number(buf);
+ const n = Number(buf);
+ if (!isInteger(n) || n < 0) {
+ throw new Error("Illegal attachments");
+ }
+ else if (n > this.opts.maxAttachments) {
+ throw new Error("too many attachments");
+ }
+ p.attachments = n;
}
// look up namespace (if any)
if ("/" === str.charAt(i + 1)) {
const start = i + 1;
@@ -242,9 +247,9 @@
return p;
}
tryParse(str) {
try {
- return JSON.parse(str, this.reviver);
+ return JSON.parse(str, this.opts.reviver);
}
catch (e) {
return false;
}
@@ -318,4 +323,45 @@
this.reconPack = null;
this.buffers = [];
}
}
+function isNamespaceValid(nsp) {
+ return typeof nsp === "string";
+}
+// see https://caniuse.com/mdn-javascript_builtins_number_isinteger
+const isInteger = Number.isInteger ||
+ function (value) {
+ return (typeof value === "number" &&
+ isFinite(value) &&
+ Math.floor(value) === value);
+ };
+function isAckIdValid(id) {
+ return id === undefined || isInteger(id);
+}
+// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
+function isObject(value) {
+ return Object.prototype.toString.call(value) === "[object Object]";
+}
+function isDataValid(type, payload) {
+ switch (type) {
+ case PacketType.CONNECT:
+ return payload === undefined || isObject(payload);
+ case PacketType.DISCONNECT:
+ return payload === undefined;
+ case PacketType.EVENT:
+ return (Array.isArray(payload) &&
+ (typeof payload[0] === "number" ||
+ (typeof payload[0] === "string" &&
+ RESERVED_EVENTS.indexOf(payload[0]) === -1)));
+ case PacketType.ACK:
+ return Array.isArray(payload);
+ case PacketType.CONNECT_ERROR:
+ return typeof payload === "string" || isObject(payload);
+ default:
+ return false;
+ }
+}
+function isPacketValid(packet) {
+ return (isNamespaceValid(packet.nsp) &&
+ isAckIdValid(packet.id) &&
+ isDataValid(packet.type, packet.data));
+} Index: package/build/esm-debug/index.js
===================================================================
--- package/build/esm-debug/index.js
+++ package/build/esm-debug/index.js
@@ -6,13 +6,13 @@
/**
* These strings must not be used as event names, as they have a special meaning.
*/
const RESERVED_EVENTS = [
- "connect",
- "connect_error",
- "disconnect",
- "disconnecting",
- "newListener",
+ "connect", // used on the client side
+ "connect_error", // used on the client side
+ "disconnect", // used on both sides
+ "disconnecting", // used on the server side
+ "newListener", // used by the Node.js EventEmitter
"removeListener", // used by the Node.js EventEmitter
];
/**
* Protocol version.
@@ -103,26 +103,23 @@
buffers.unshift(pack); // add packet info to beginning of data list
return buffers; // write all the buffers
}
}
-// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
-function isObject(value) {
- return Object.prototype.toString.call(value) === "[object Object]";
-}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export class Decoder extends Emitter {
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver) {
+ constructor(opts) {
super();
- this.reviver = reviver;
+ this.opts = Object.assign({
+ reviver: undefined,
+ maxAttachments: 10,
+ }, typeof opts === "function" ? { reviver: opts } : opts);
}
/**
* Decodes an encoded packet string into packet JSON.
*
@@ -191,9 +188,16 @@
const buf = str.substring(start, i);
if (buf != Number(buf) || str.charAt(i) !== "-") {
throw new Error("Illegal attachments");
}
- p.attachments = Number(buf);
+ const n = Number(buf);
+ if (!isInteger(n) || n < 0) {
+ throw new Error("Illegal attachments");
+ }
+ else if (n > this.opts.maxAttachments) {
+ throw new Error("too many attachments");
+ }
+ p.attachments = n;
}
// look up namespace (if any)
if ("/" === str.charAt(i + 1)) {
const start = i + 1;
@@ -238,9 +242,9 @@
return p;
}
tryParse(str) {
try {
- return JSON.parse(str, this.reviver);
+ return JSON.parse(str, this.opts.reviver);
}
catch (e) {
return false;
}
@@ -313,4 +317,45 @@
this.reconPack = null;
this.buffers = [];
}
}
+function isNamespaceValid(nsp) {
+ return typeof nsp === "string";
+}
+// see https://caniuse.com/mdn-javascript_builtins_number_isinteger
+const isInteger = Number.isInteger ||
+ function (value) {
+ return (typeof value === "number" &&
+ isFinite(value) &&
+ Math.floor(value) === value);
+ };
+function isAckIdValid(id) {
+ return id === undefined || isInteger(id);
+}
+// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
+function isObject(value) {
+ return Object.prototype.toString.call(value) === "[object Object]";
+}
+function isDataValid(type, payload) {
+ switch (type) {
+ case PacketType.CONNECT:
+ return payload === undefined || isObject(payload);
+ case PacketType.DISCONNECT:
+ return payload === undefined;
+ case PacketType.EVENT:
+ return (Array.isArray(payload) &&
+ (typeof payload[0] === "number" ||
+ (typeof payload[0] === "string" &&
+ RESERVED_EVENTS.indexOf(payload[0]) === -1)));
+ case PacketType.ACK:
+ return Array.isArray(payload);
+ case PacketType.CONNECT_ERROR:
+ return typeof payload === "string" || isObject(payload);
+ default:
+ return false;
+ }
+}
+export function isPacketValid(packet) {
+ return (isNamespaceValid(packet.nsp) &&
+ isAckIdValid(packet.id) &&
+ isDataValid(packet.type, packet.data));
+} Index: package/build/esm/index.js
===================================================================
--- package/build/esm/index.js
+++ package/build/esm/index.js
@@ -4,13 +4,13 @@
/**
* These strings must not be used as event names, as they have a special meaning.
*/
const RESERVED_EVENTS = [
- "connect",
- "connect_error",
- "disconnect",
- "disconnecting",
- "newListener",
+ "connect", // used on the client side
+ "connect_error", // used on the client side
+ "disconnect", // used on both sides
+ "disconnecting", // used on the server side
+ "newListener", // used by the Node.js EventEmitter
"removeListener", // used by the Node.js EventEmitter
];
/**
* Protocol version.
@@ -99,26 +99,23 @@
buffers.unshift(pack); // add packet info to beginning of data list
return buffers; // write all the buffers
}
}
-// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
-function isObject(value) {
- return Object.prototype.toString.call(value) === "[object Object]";
-}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export class Decoder extends Emitter {
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver) {
+ constructor(opts) {
super();
- this.reviver = reviver;
+ this.opts = Object.assign({
+ reviver: undefined,
+ maxAttachments: 10,
+ }, typeof opts === "function" ? { reviver: opts } : opts);
}
/**
* Decodes an encoded packet string into packet JSON.
*
@@ -187,9 +184,16 @@
const buf = str.substring(start, i);
if (buf != Number(buf) || str.charAt(i) !== "-") {
throw new Error("Illegal attachments");
}
- p.attachments = Number(buf);
+ const n = Number(buf);
+ if (!isInteger(n) || n < 0) {
+ throw new Error("Illegal attachments");
+ }
+ else if (n > this.opts.maxAttachments) {
+ throw new Error("too many attachments");
+ }
+ p.attachments = n;
}
// look up namespace (if any)
if ("/" === str.charAt(i + 1)) {
const start = i + 1;
@@ -233,9 +237,9 @@
return p;
}
tryParse(str) {
try {
- return JSON.parse(str, this.reviver);
+ return JSON.parse(str, this.opts.reviver);
}
catch (e) {
return false;
}
@@ -308,4 +312,45 @@
this.reconPack = null;
this.buffers = [];
}
}
+function isNamespaceValid(nsp) {
+ return typeof nsp === "string";
+}
+// see https://caniuse.com/mdn-javascript_builtins_number_isinteger
+const isInteger = Number.isInteger ||
+ function (value) {
+ return (typeof value === "number" &&
+ isFinite(value) &&
+ Math.floor(value) === value);
+ };
+function isAckIdValid(id) {
+ return id === undefined || isInteger(id);
+}
+// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
+function isObject(value) {
+ return Object.prototype.toString.call(value) === "[object Object]";
+}
+function isDataValid(type, payload) {
+ switch (type) {
+ case PacketType.CONNECT:
+ return payload === undefined || isObject(payload);
+ case PacketType.DISCONNECT:
+ return payload === undefined;
+ case PacketType.EVENT:
+ return (Array.isArray(payload) &&
+ (typeof payload[0] === "number" ||
+ (typeof payload[0] === "string" &&
+ RESERVED_EVENTS.indexOf(payload[0]) === -1)));
+ case PacketType.ACK:
+ return Array.isArray(payload);
+ case PacketType.CONNECT_ERROR:
+ return typeof payload === "string" || isObject(payload);
+ default:
+ return false;
+ }
+}
+export function isPacketValid(packet) {
+ return (isNamespaceValid(packet.nsp) &&
+ isAckIdValid(packet.id) &&
+ isDataValid(packet.type, packet.data));
+} Index: package/build/cjs/is-binary.js
===================================================================
--- package/build/cjs/is-binary.js
+++ package/build/cjs/is-binary.js
@@ -1,7 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-exports.hasBinary = exports.isBinary = void 0;
+exports.isBinary = isBinary;
+exports.hasBinary = hasBinary;
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
const isView = (obj) => {
return typeof ArrayBuffer.isView === "function"
? ArrayBuffer.isView(obj)
@@ -23,9 +24,8 @@
return ((withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))) ||
(withNativeBlob && obj instanceof Blob) ||
(withNativeFile && obj instanceof File));
}
-exports.isBinary = isBinary;
function hasBinary(obj, toJSON) {
if (!obj || typeof obj !== "object") {
return false;
}
@@ -51,5 +51,4 @@
}
}
return false;
}
-exports.hasBinary = hasBinary; Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,12 +1,16 @@
{
"name": "socket.io-parser",
- "version": "4.2.4",
+ "version": "4.2.6",
"description": "socket.io protocol parser",
+ "homepage": "https://github.com/socketio/socket.io/tree/main/packages/socket.io-client#readme",
"repository": {
"type": "git",
- "url": "https://github.com/socketio/socket.io-parser.git"
+ "url": "git+https://github.com/socketio/socket.io.git"
},
+ "bugs": {
+ "url": "https://github.com/socketio/socket.io/issues"
+ },
"files": [
"build/"
],
"main": "./build/cjs/index.js",
@@ -14,35 +18,17 @@
"types": "./build/esm/index.d.ts",
"exports": {
"import": {
"node": "./build/esm-debug/index.js",
+ "development": "./build/esm-debug/index.js",
"default": "./build/esm/index.js"
},
"require": "./build/cjs/index.js"
},
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
- "debug": "~4.3.1"
+ "debug": "~4.4.1"
},
- "devDependencies": {
- "@babel/core": "~7.9.6",
- "@babel/preset-env": "~7.9.6",
- "@babel/register": "^7.18.9",
- "@types/debug": "^4.1.5",
- "@types/node": "^14.11.1",
- "@wdio/cli": "^7.26.0",
- "@wdio/local-runner": "^7.26.0",
- "@wdio/mocha-framework": "^7.26.0",
- "@wdio/sauce-service": "^7.26.0",
- "@wdio/spec-reporter": "^7.26.0",
- "benchmark": "2.1.2",
- "expect.js": "0.3.1",
- "mocha": "^10.1.0",
- "prettier": "^2.1.2",
- "rimraf": "^3.0.2",
- "typescript": "^4.0.3",
- "wdio-geckodriver-service": "^4.0.0"
- },
"scripts": {
"compile": "rimraf ./build && tsc && tsc -p tsconfig.esm.json && ./postcompile.sh",
"test": "npm run format:check && npm run compile && if test \"$BROWSERS\" = \"1\" ; then npm run test:browser; else npm run test:node; fi",
"test:node": "mocha --reporter dot --bail test/index.js", Index: package/build/cjs/index.d.ts
===================================================================
--- package/build/cjs/index.d.ts
+++ package/build/cjs/index.d.ts
@@ -52,22 +52,32 @@
}
interface DecoderReservedEvents {
decoded: (packet: Packet) => void;
}
+type JSONReviver = (this: any, key: string, value: any) => any;
+export interface DecoderOptions {
+ /**
+ * Custom reviver to pass down to JSON.parse()
+ */
+ reviver?: JSONReviver;
+ /**
+ * Maximum number of binary attachments per packet
+ * @default 10
+ */
+ maxAttachments?: number;
+}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export declare class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
- private reviver?;
private reconstructor;
+ private opts;
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver?: (this: any, key: string, value: any) => any);
+ constructor(opts?: DecoderOptions | JSONReviver);
/**
* Decodes an encoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
@@ -86,5 +96,6 @@
* Deallocates a parser's resources
*/
destroy(): void;
}
+export declare function isPacketValid(packet: Packet): boolean;
export {}; Index: package/build/esm-debug/index.d.ts
===================================================================
--- package/build/esm-debug/index.d.ts
+++ package/build/esm-debug/index.d.ts
@@ -52,22 +52,32 @@
}
interface DecoderReservedEvents {
decoded: (packet: Packet) => void;
}
+type JSONReviver = (this: any, key: string, value: any) => any;
+export interface DecoderOptions {
+ /**
+ * Custom reviver to pass down to JSON.parse()
+ */
+ reviver?: JSONReviver;
+ /**
+ * Maximum number of binary attachments per packet
+ * @default 10
+ */
+ maxAttachments?: number;
+}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export declare class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
- private reviver?;
private reconstructor;
+ private opts;
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver?: (this: any, key: string, value: any) => any);
+ constructor(opts?: DecoderOptions | JSONReviver);
/**
* Decodes an encoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
@@ -86,5 +96,6 @@
* Deallocates a parser's resources
*/
destroy(): void;
}
+export declare function isPacketValid(packet: Packet): boolean;
export {}; Index: package/build/esm/index.d.ts
===================================================================
--- package/build/esm/index.d.ts
+++ package/build/esm/index.d.ts
@@ -52,22 +52,32 @@
}
interface DecoderReservedEvents {
decoded: (packet: Packet) => void;
}
+type JSONReviver = (this: any, key: string, value: any) => any;
+export interface DecoderOptions {
+ /**
+ * Custom reviver to pass down to JSON.parse()
+ */
+ reviver?: JSONReviver;
+ /**
+ * Maximum number of binary attachments per packet
+ * @default 10
+ */
+ maxAttachments?: number;
+}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
*/
export declare class Decoder extends Emitter<{}, {}, DecoderReservedEvents> {
- private reviver?;
private reconstructor;
+ private opts;
/**
* Decoder constructor
- *
- * @param {function} reviver - custom reviver to pass down to JSON.stringify
*/
- constructor(reviver?: (this: any, key: string, value: any) => any);
+ constructor(opts?: DecoderOptions | JSONReviver);
/**
* Decodes an encoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
@@ -86,5 +96,6 @@
* Deallocates a parser's resources
*/
destroy(): void;
}
+export declare function isPacketValid(packet: Packet): boolean;
export {}; Index: package/build/cjs/is-binary.d.ts
===================================================================
--- package/build/cjs/is-binary.d.ts
+++ package/build/cjs/is-binary.d.ts
@@ -3,5 +3,5 @@
*
* @private
*/
export declare function isBinary(obj: any): boolean;
-export declare function hasBinary(obj: any, toJSON?: boolean): any;
+export declare function hasBinary(obj: any, toJSON?: boolean): boolean; Index: package/build/esm-debug/is-binary.d.ts
===================================================================
--- package/build/esm-debug/is-binary.d.ts
+++ package/build/esm-debug/is-binary.d.ts
@@ -3,5 +3,5 @@
*
* @private
*/
export declare function isBinary(obj: any): boolean;
-export declare function hasBinary(obj: any, toJSON?: boolean): any;
+export declare function hasBinary(obj: any, toJSON?: boolean): boolean; Index: package/build/esm/is-binary.d.ts
===================================================================
--- package/build/esm/is-binary.d.ts
+++ package/build/esm/is-binary.d.ts
@@ -3,5 +3,5 @@
*
* @private
*/
export declare function isBinary(obj: any): boolean;
-export declare function hasBinary(obj: any, toJSON?: boolean): any;
+export declare function hasBinary(obj: any, toJSON?: boolean): boolean;