Skip to content
This repository was archived by the owner on Aug 13, 2018. It is now read-only.

Commit 6fe9a75

Browse files
committed
Do not use remote scripts (amo review comment)
1 parent 688941b commit 6fe9a75

File tree

10 files changed

+922
-3
lines changed

10 files changed

+922
-3
lines changed

lib/socket.io-parser/binary.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*global Blob,File*/
2+
3+
/**
4+
* Module requirements
5+
*/
6+
7+
var isArray = require('./isarray');
8+
var isBuf = require('./is-buffer');
9+
10+
/**
11+
* Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
12+
* Anything with blobs or files should be fed through removeBlobs before coming
13+
* here.
14+
*
15+
* @param {Object} packet - socket.io event packet
16+
* @return {Object} with deconstructed packet and list of buffers
17+
* @api public
18+
*/
19+
20+
exports.deconstructPacket = function(packet){
21+
var buffers = [];
22+
var packetData = packet.data;
23+
24+
function _deconstructPacket(data) {
25+
if (!data) return data;
26+
27+
if (isBuf(data)) {
28+
var placeholder = { _placeholder: true, num: buffers.length };
29+
buffers.push(data);
30+
return placeholder;
31+
} else if (isArray(data)) {
32+
var newData = new Array(data.length);
33+
for (var i = 0; i < data.length; i++) {
34+
newData[i] = _deconstructPacket(data[i]);
35+
}
36+
return newData;
37+
} else if ('object' == typeof data && !(data instanceof Date)) {
38+
var newData = {};
39+
for (var key in data) {
40+
newData[key] = _deconstructPacket(data[key]);
41+
}
42+
return newData;
43+
}
44+
return data;
45+
}
46+
47+
var pack = packet;
48+
pack.data = _deconstructPacket(packetData);
49+
pack.attachments = buffers.length; // number of binary 'attachments'
50+
return {packet: pack, buffers: buffers};
51+
};
52+
53+
/**
54+
* Reconstructs a binary packet from its placeholder packet and buffers
55+
*
56+
* @param {Object} packet - event packet with placeholders
57+
* @param {Array} buffers - binary buffers to put in placeholder positions
58+
* @return {Object} reconstructed packet
59+
* @api public
60+
*/
61+
62+
exports.reconstructPacket = function(packet, buffers) {
63+
var curPlaceHolder = 0;
64+
65+
function _reconstructPacket(data) {
66+
if (data && data._placeholder) {
67+
var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)
68+
return buf;
69+
} else if (isArray(data)) {
70+
for (var i = 0; i < data.length; i++) {
71+
data[i] = _reconstructPacket(data[i]);
72+
}
73+
return data;
74+
} else if (data && 'object' == typeof data) {
75+
for (var key in data) {
76+
data[key] = _reconstructPacket(data[key]);
77+
}
78+
return data;
79+
}
80+
return data;
81+
}
82+
83+
packet.data = _reconstructPacket(packet.data);
84+
packet.attachments = undefined; // no longer useful
85+
return packet;
86+
};
87+
88+
/**
89+
* Asynchronously removes Blobs or Files from data via
90+
* FileReader's readAsArrayBuffer method. Used before encoding
91+
* data as msgpack. Calls callback with the blobless data.
92+
*
93+
* @param {Object} data
94+
* @param {Function} callback
95+
* @api private
96+
*/
97+
98+
exports.removeBlobs = function(data, callback) {
99+
function _removeBlobs(obj, curKey, containingObject) {
100+
if (!obj) return obj;
101+
102+
// convert any blob
103+
if ((global.Blob && obj instanceof Blob) ||
104+
(global.File && obj instanceof File)) {
105+
pendingBlobs++;
106+
107+
// async filereader
108+
var fileReader = new FileReader();
109+
fileReader.onload = function() { // this.result == arraybuffer
110+
if (containingObject) {
111+
containingObject[curKey] = this.result;
112+
}
113+
else {
114+
bloblessData = this.result;
115+
}
116+
117+
// if nothing pending its callback time
118+
if(! --pendingBlobs) {
119+
callback(bloblessData);
120+
}
121+
};
122+
123+
fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
124+
} else if (isArray(obj)) { // handle array
125+
for (var i = 0; i < obj.length; i++) {
126+
_removeBlobs(obj[i], i, obj);
127+
}
128+
} else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object
129+
for (var key in obj) {
130+
_removeBlobs(obj[key], key, obj);
131+
}
132+
}
133+
}
134+
135+
var pendingBlobs = 0;
136+
var bloblessData = data;
137+
_removeBlobs(bloblessData);
138+
if (!pendingBlobs) {
139+
callback(bloblessData);
140+
}
141+
};
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
2+
/**
3+
* Expose `Emitter`.
4+
*/
5+
6+
module.exports = Emitter;
7+
8+
/**
9+
* Initialize a new `Emitter`.
10+
*
11+
* @api public
12+
*/
13+
14+
function Emitter(obj) {
15+
if (obj) return mixin(obj);
16+
};
17+
18+
/**
19+
* Mixin the emitter properties.
20+
*
21+
* @param {Object} obj
22+
* @return {Object}
23+
* @api private
24+
*/
25+
26+
function mixin(obj) {
27+
for (var key in Emitter.prototype) {
28+
obj[key] = Emitter.prototype[key];
29+
}
30+
return obj;
31+
}
32+
33+
/**
34+
* Listen on the given `event` with `fn`.
35+
*
36+
* @param {String} event
37+
* @param {Function} fn
38+
* @return {Emitter}
39+
* @api public
40+
*/
41+
42+
Emitter.prototype.on =
43+
Emitter.prototype.addEventListener = function(event, fn){
44+
this._callbacks = this._callbacks || {};
45+
(this._callbacks[event] = this._callbacks[event] || [])
46+
.push(fn);
47+
return this;
48+
};
49+
50+
/**
51+
* Adds an `event` listener that will be invoked a single
52+
* time then automatically removed.
53+
*
54+
* @param {String} event
55+
* @param {Function} fn
56+
* @return {Emitter}
57+
* @api public
58+
*/
59+
60+
Emitter.prototype.once = function(event, fn){
61+
var self = this;
62+
this._callbacks = this._callbacks || {};
63+
64+
function on() {
65+
self.off(event, on);
66+
fn.apply(this, arguments);
67+
}
68+
69+
on.fn = fn;
70+
this.on(event, on);
71+
return this;
72+
};
73+
74+
/**
75+
* Remove the given callback for `event` or all
76+
* registered callbacks.
77+
*
78+
* @param {String} event
79+
* @param {Function} fn
80+
* @return {Emitter}
81+
* @api public
82+
*/
83+
84+
Emitter.prototype.off =
85+
Emitter.prototype.removeListener =
86+
Emitter.prototype.removeAllListeners =
87+
Emitter.prototype.removeEventListener = function(event, fn){
88+
this._callbacks = this._callbacks || {};
89+
90+
// all
91+
if (0 == arguments.length) {
92+
this._callbacks = {};
93+
return this;
94+
}
95+
96+
// specific event
97+
var callbacks = this._callbacks[event];
98+
if (!callbacks) return this;
99+
100+
// remove all handlers
101+
if (1 == arguments.length) {
102+
delete this._callbacks[event];
103+
return this;
104+
}
105+
106+
// remove specific handler
107+
var cb;
108+
for (var i = 0; i < callbacks.length; i++) {
109+
cb = callbacks[i];
110+
if (cb === fn || cb.fn === fn) {
111+
callbacks.splice(i, 1);
112+
break;
113+
}
114+
}
115+
return this;
116+
};
117+
118+
/**
119+
* Emit `event` with the given args.
120+
*
121+
* @param {String} event
122+
* @param {Mixed} ...
123+
* @return {Emitter}
124+
*/
125+
126+
Emitter.prototype.emit = function(event){
127+
this._callbacks = this._callbacks || {};
128+
var args = [].slice.call(arguments, 1)
129+
, callbacks = this._callbacks[event];
130+
131+
if (callbacks) {
132+
callbacks = callbacks.slice(0);
133+
for (var i = 0, len = callbacks.length; i < len; ++i) {
134+
callbacks[i].apply(this, args);
135+
}
136+
}
137+
138+
return this;
139+
};
140+
141+
/**
142+
* Return array of callbacks for `event`.
143+
*
144+
* @param {String} event
145+
* @return {Array}
146+
* @api public
147+
*/
148+
149+
Emitter.prototype.listeners = function(event){
150+
this._callbacks = this._callbacks || {};
151+
return this._callbacks[event] || [];
152+
};
153+
154+
/**
155+
* Check if this emitter has `event` handlers.
156+
*
157+
* @param {String} event
158+
* @return {Boolean}
159+
* @api public
160+
*/
161+
162+
Emitter.prototype.hasListeners = function(event){
163+
return !! this.listeners(event).length;
164+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter)
2+
3+
Event emitter component.
4+
5+
## Installation
6+
7+
```
8+
$ component install component/emitter
9+
```
10+
11+
## API
12+
13+
### Emitter(obj)
14+
15+
The `Emitter` may also be used as a mixin. For example
16+
a "plain" object may become an emitter, or you may
17+
extend an existing prototype.
18+
19+
As an `Emitter` instance:
20+
21+
```js
22+
var Emitter = require('emitter');
23+
var emitter = new Emitter;
24+
emitter.emit('something');
25+
```
26+
27+
As a mixin:
28+
29+
```js
30+
var Emitter = require('emitter');
31+
var user = { name: 'tobi' };
32+
Emitter(user);
33+
34+
user.emit('im a user');
35+
```
36+
37+
As a prototype mixin:
38+
39+
```js
40+
var Emitter = require('emitter');
41+
Emitter(User.prototype);
42+
```
43+
44+
### Emitter#on(event, fn)
45+
46+
Register an `event` handler `fn`.
47+
48+
### Emitter#once(event, fn)
49+
50+
Register a single-shot `event` handler `fn`,
51+
removed immediately after it is invoked the
52+
first time.
53+
54+
### Emitter#off(event, fn)
55+
56+
* Pass `event` and `fn` to remove a listener.
57+
* Pass `event` to remove all listeners on that event.
58+
* Pass nothing to remove all listeners on all events.
59+
60+
### Emitter#emit(event, ...)
61+
62+
Emit an `event` with variable option args.
63+
64+
### Emitter#listeners(event)
65+
66+
Return an array of callbacks, or an empty array.
67+
68+
### Emitter#hasListeners(event)
69+
70+
Check if this emitter has `event` handlers.
71+
72+
## License
73+
74+
MIT

0 commit comments

Comments
 (0)