Skip to content

Commit 3bbf2d6

Browse files
authored
[Fix] babel's "loose mode" class transform enbrittles BufferList (#428)
```js Object.defineProperty(Object.prototype, util.inspect.custom, { set(v) { throw 'this should not happen inside readable-stream'; } }); ``` With this change, I believe the output will use [[Define]] instead of [[Set]] for https://github.com/nodejs/node/blob/c101251a95cc82142bee4637f8db6cc360a06d82/lib/internal/streams/buffer_list.js#L167, and thus no longer fail when Object.prototype is modified.
1 parent 7783afa commit 3bbf2d6

26 files changed

+1458
-1044
lines changed

.babelrc

-6
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,5 @@
1313
],
1414
"debug": true
1515
}]
16-
],
17-
"plugins": [
18-
// Included in the preset, but we can't specify per-plugin options there
19-
["@babel/plugin-transform-classes", {
20-
"loose": true
21-
}]
2216
]
2317
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ npm install --save readable-stream
1515

1616
This package is a mirror of the streams implementations in Node.js.
1717

18-
Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v10.18.1/docs/api/stream.html).
18+
Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v10.19.0/docs/api/stream.html).
1919

2020
If you want to guarantee a stable streams base, regardless of what version of
2121
Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).

lib/internal/streams/buffer_list.js

+164-145
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
66

77
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
88

9+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10+
11+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
12+
13+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
14+
915
var _require = require('buffer'),
1016
Buffer = _require.Buffer;
1117

@@ -22,170 +28,183 @@ module.exports =
2228
/*#__PURE__*/
2329
function () {
2430
function BufferList() {
31+
_classCallCheck(this, BufferList);
32+
2533
this.head = null;
2634
this.tail = null;
2735
this.length = 0;
2836
}
2937

30-
var _proto = BufferList.prototype;
31-
32-
_proto.push = function push(v) {
33-
var entry = {
34-
data: v,
35-
next: null
36-
};
37-
if (this.length > 0) this.tail.next = entry;else this.head = entry;
38-
this.tail = entry;
39-
++this.length;
40-
};
41-
42-
_proto.unshift = function unshift(v) {
43-
var entry = {
44-
data: v,
45-
next: this.head
46-
};
47-
if (this.length === 0) this.tail = entry;
48-
this.head = entry;
49-
++this.length;
50-
};
51-
52-
_proto.shift = function shift() {
53-
if (this.length === 0) return;
54-
var ret = this.head.data;
55-
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
56-
--this.length;
57-
return ret;
58-
};
59-
60-
_proto.clear = function clear() {
61-
this.head = this.tail = null;
62-
this.length = 0;
63-
};
64-
65-
_proto.join = function join(s) {
66-
if (this.length === 0) return '';
67-
var p = this.head;
68-
var ret = '' + p.data;
69-
70-
while (p = p.next) {
71-
ret += s + p.data;
38+
_createClass(BufferList, [{
39+
key: "push",
40+
value: function push(v) {
41+
var entry = {
42+
data: v,
43+
next: null
44+
};
45+
if (this.length > 0) this.tail.next = entry;else this.head = entry;
46+
this.tail = entry;
47+
++this.length;
7248
}
73-
74-
return ret;
75-
};
76-
77-
_proto.concat = function concat(n) {
78-
if (this.length === 0) return Buffer.alloc(0);
79-
var ret = Buffer.allocUnsafe(n >>> 0);
80-
var p = this.head;
81-
var i = 0;
82-
83-
while (p) {
84-
copyBuffer(p.data, ret, i);
85-
i += p.data.length;
86-
p = p.next;
49+
}, {
50+
key: "unshift",
51+
value: function unshift(v) {
52+
var entry = {
53+
data: v,
54+
next: this.head
55+
};
56+
if (this.length === 0) this.tail = entry;
57+
this.head = entry;
58+
++this.length;
8759
}
88-
89-
return ret;
90-
} // Consumes a specified amount of bytes or characters from the buffered data.
91-
;
92-
93-
_proto.consume = function consume(n, hasStrings) {
94-
var ret;
95-
96-
if (n < this.head.data.length) {
97-
// `slice` is the same for buffers and strings.
98-
ret = this.head.data.slice(0, n);
99-
this.head.data = this.head.data.slice(n);
100-
} else if (n === this.head.data.length) {
101-
// First chunk is a perfect match.
102-
ret = this.shift();
103-
} else {
104-
// Result spans more than one buffer.
105-
ret = hasStrings ? this._getString(n) : this._getBuffer(n);
60+
}, {
61+
key: "shift",
62+
value: function shift() {
63+
if (this.length === 0) return;
64+
var ret = this.head.data;
65+
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
66+
--this.length;
67+
return ret;
68+
}
69+
}, {
70+
key: "clear",
71+
value: function clear() {
72+
this.head = this.tail = null;
73+
this.length = 0;
10674
}
75+
}, {
76+
key: "join",
77+
value: function join(s) {
78+
if (this.length === 0) return '';
79+
var p = this.head;
80+
var ret = '' + p.data;
81+
82+
while (p = p.next) {
83+
ret += s + p.data;
84+
}
10785

108-
return ret;
109-
};
110-
111-
_proto.first = function first() {
112-
return this.head.data;
113-
} // Consumes a specified amount of characters from the buffered data.
114-
;
115-
116-
_proto._getString = function _getString(n) {
117-
var p = this.head;
118-
var c = 1;
119-
var ret = p.data;
120-
n -= ret.length;
121-
122-
while (p = p.next) {
123-
var str = p.data;
124-
var nb = n > str.length ? str.length : n;
125-
if (nb === str.length) ret += str;else ret += str.slice(0, n);
126-
n -= nb;
127-
128-
if (n === 0) {
129-
if (nb === str.length) {
130-
++c;
131-
if (p.next) this.head = p.next;else this.head = this.tail = null;
132-
} else {
133-
this.head = p;
134-
p.data = str.slice(nb);
135-
}
86+
return ret;
87+
}
88+
}, {
89+
key: "concat",
90+
value: function concat(n) {
91+
if (this.length === 0) return Buffer.alloc(0);
92+
var ret = Buffer.allocUnsafe(n >>> 0);
93+
var p = this.head;
94+
var i = 0;
95+
96+
while (p) {
97+
copyBuffer(p.data, ret, i);
98+
i += p.data.length;
99+
p = p.next;
100+
}
136101

137-
break;
102+
return ret;
103+
} // Consumes a specified amount of bytes or characters from the buffered data.
104+
105+
}, {
106+
key: "consume",
107+
value: function consume(n, hasStrings) {
108+
var ret;
109+
110+
if (n < this.head.data.length) {
111+
// `slice` is the same for buffers and strings.
112+
ret = this.head.data.slice(0, n);
113+
this.head.data = this.head.data.slice(n);
114+
} else if (n === this.head.data.length) {
115+
// First chunk is a perfect match.
116+
ret = this.shift();
117+
} else {
118+
// Result spans more than one buffer.
119+
ret = hasStrings ? this._getString(n) : this._getBuffer(n);
138120
}
139121

140-
++c;
122+
return ret;
141123
}
124+
}, {
125+
key: "first",
126+
value: function first() {
127+
return this.head.data;
128+
} // Consumes a specified amount of characters from the buffered data.
129+
130+
}, {
131+
key: "_getString",
132+
value: function _getString(n) {
133+
var p = this.head;
134+
var c = 1;
135+
var ret = p.data;
136+
n -= ret.length;
137+
138+
while (p = p.next) {
139+
var str = p.data;
140+
var nb = n > str.length ? str.length : n;
141+
if (nb === str.length) ret += str;else ret += str.slice(0, n);
142+
n -= nb;
143+
144+
if (n === 0) {
145+
if (nb === str.length) {
146+
++c;
147+
if (p.next) this.head = p.next;else this.head = this.tail = null;
148+
} else {
149+
this.head = p;
150+
p.data = str.slice(nb);
151+
}
152+
153+
break;
154+
}
142155

143-
this.length -= c;
144-
return ret;
145-
} // Consumes a specified amount of bytes from the buffered data.
146-
;
147-
148-
_proto._getBuffer = function _getBuffer(n) {
149-
var ret = Buffer.allocUnsafe(n);
150-
var p = this.head;
151-
var c = 1;
152-
p.data.copy(ret);
153-
n -= p.data.length;
154-
155-
while (p = p.next) {
156-
var buf = p.data;
157-
var nb = n > buf.length ? buf.length : n;
158-
buf.copy(ret, ret.length - n, 0, nb);
159-
n -= nb;
160-
161-
if (n === 0) {
162-
if (nb === buf.length) {
163-
++c;
164-
if (p.next) this.head = p.next;else this.head = this.tail = null;
165-
} else {
166-
this.head = p;
167-
p.data = buf.slice(nb);
156+
++c;
157+
}
158+
159+
this.length -= c;
160+
return ret;
161+
} // Consumes a specified amount of bytes from the buffered data.
162+
163+
}, {
164+
key: "_getBuffer",
165+
value: function _getBuffer(n) {
166+
var ret = Buffer.allocUnsafe(n);
167+
var p = this.head;
168+
var c = 1;
169+
p.data.copy(ret);
170+
n -= p.data.length;
171+
172+
while (p = p.next) {
173+
var buf = p.data;
174+
var nb = n > buf.length ? buf.length : n;
175+
buf.copy(ret, ret.length - n, 0, nb);
176+
n -= nb;
177+
178+
if (n === 0) {
179+
if (nb === buf.length) {
180+
++c;
181+
if (p.next) this.head = p.next;else this.head = this.tail = null;
182+
} else {
183+
this.head = p;
184+
p.data = buf.slice(nb);
185+
}
186+
187+
break;
168188
}
169189

170-
break;
190+
++c;
171191
}
172192

173-
++c;
193+
this.length -= c;
194+
return ret;
195+
} // Make sure the linked list only shows the minimal necessary information.
196+
197+
}, {
198+
key: custom,
199+
value: function value(_, options) {
200+
return inspect(this, _objectSpread({}, options, {
201+
// Only inspect one level.
202+
depth: 0,
203+
// It should not recurse.
204+
customInspect: false
205+
}));
174206
}
175-
176-
this.length -= c;
177-
return ret;
178-
} // Make sure the linked list only shows the minimal necessary information.
179-
;
180-
181-
_proto[custom] = function (_, options) {
182-
return inspect(this, _objectSpread({}, options, {
183-
// Only inspect one level.
184-
depth: 0,
185-
// It should not recurse.
186-
customInspect: false
187-
}));
188-
};
207+
}]);
189208

190209
return BufferList;
191210
}();

0 commit comments

Comments
 (0)