http: refactor to avoid unsafe array iteration

PR-URL: https://github.com/nodejs/node/pull/37124
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Antoine du Hamel
2021-01-29 14:53:16 +01:00
committed by Rich Trott
parent e30e035dcd
commit 4a113be836
3 changed files with 21 additions and 13 deletions

View File

@@ -201,8 +201,9 @@ function maybeEnableKeylog(eventName) {
agent.emit('keylog', keylog, this);
};
// Existing sockets will start listening on keylog now.
for (const socket of ObjectValues(this.sockets)) {
socket.on('keylog', this[kOnKeylog]);
const sockets = ObjectValues(this.sockets);
for (let i = 0; i < sockets.length; i++) {
sockets[i].on('keylog', this[kOnKeylog]);
}
}
}
@@ -426,7 +427,9 @@ Agent.prototype.removeSocket = function removeSocket(s, options) {
if (!s.writable)
ArrayPrototypePush(sets, this.freeSockets);
for (const sockets of sets) {
for (let sk = 0; sk < sets.length; sk++) {
const sockets = sets[sk];
if (sockets[name]) {
const index = ArrayPrototypeIndexOf(sockets[name], s);
if (index !== -1) {
@@ -492,10 +495,14 @@ Agent.prototype.reuseSocket = function reuseSocket(socket, req) {
};
Agent.prototype.destroy = function destroy() {
for (const set of [this.freeSockets, this.sockets]) {
for (const key of ObjectKeys(set)) {
for (const setName of set[key]) {
setName.destroy();
const sets = [this.freeSockets, this.sockets];
for (let s = 0; s < sets.length; s++) {
const set = sets[s];
const keys = ObjectKeys(set);
for (let v = 0; v < keys.length; v++) {
const setName = set[keys[v]];
for (let n = 0; n < setName.length; n++) {
setName[n].destroy();
}
}
}

View File

@@ -23,6 +23,7 @@
const {
ArrayIsArray,
ArrayPrototypeForEach,
ArrayPrototypeJoin,
ArrayPrototypePush,
ArrayPrototypeUnshift,
@@ -390,9 +391,9 @@ function _storeHeader(firstLine, headers) {
}
} else if (ArrayIsArray(headers)) {
if (headers.length && ArrayIsArray(headers[0])) {
for (const entry of headers) {
processHeader(this, state, entry[0], entry[1], true);
}
ArrayPrototypeForEach(headers, (entry) =>
processHeader(this, state, entry[0], entry[1], true)
);
} else {
if (headers.length % 2 !== 0) {
throw new ERR_INVALID_ARG_VALUE('headers', headers);

View File

@@ -23,6 +23,7 @@
const {
ArrayIsArray,
ArrayPrototypeForEach,
ArrayPrototypePush,
ArrayPrototypeShift,
Error,
@@ -417,9 +418,8 @@ Server.prototype[EE.captureRejectionSymbol] = function(err, event, ...args) {
const [ , res] = args;
if (!res.headersSent && !res.writableEnded) {
// Don't leak headers.
for (const name of res.getHeaderNames()) {
res.removeHeader(name);
}
ArrayPrototypeForEach(res.getHeaderNames(),
(name) => res.removeHeader(name));
res.statusCode = 500;
res.end(STATUS_CODES[500]);
} else {