From 307b79d2be12ad7fc16016a52469b76186a61e02 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 31 Dec 2020 12:49:44 +0100 Subject: [PATCH] tls: refactor to avoid unsafe array iteration PR-URL: https://github.com/nodejs/node/pull/36772 Reviewed-By: Rich Trott --- lib/_tls_common.js | 25 +++++++++++++------------ lib/internal/tls.js | 5 +++-- lib/tls.js | 11 +++++++---- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/_tls_common.js b/lib/_tls_common.js index 616b7b47f46dac..7cda18be31de30 100644 --- a/lib/_tls_common.js +++ b/lib/_tls_common.js @@ -24,6 +24,7 @@ const { ArrayIsArray, ArrayPrototypeFilter, + ArrayPrototypeForEach, ArrayPrototypeJoin, ArrayPrototypePush, ObjectCreate, @@ -142,18 +143,18 @@ function processCiphers(ciphers) { return { cipherList, cipherSuites }; } -function addCACerts(context, ...certs) { - for (const cert of certs) { +function addCACerts(context, certs) { + ArrayPrototypeForEach(certs, (cert) => { validateKeyOrCertOption('ca', cert); context.addCACert(cert); - } + }); } -function setCerts(context, ...certs) { - for (const cert of certs) { +function setCerts(context, certs) { + ArrayPrototypeForEach(certs, (cert) => { validateKeyOrCertOption('cert', cert); context.setCert(cert); - } + }); } exports.createSecureContext = function createSecureContext(options) { @@ -196,18 +197,18 @@ exports.createSecureContext = function createSecureContext(options) { // change the checks to !== undefined checks. if (ca) { if (ArrayIsArray(ca)) - addCACerts(c.context, ...ca); - else addCACerts(c.context, ca); + else + addCACerts(c.context, [ca]); } else { c.context.addRootCerts(); } if (cert) { if (ArrayIsArray(cert)) - setCerts(c.context, ...cert); - else setCerts(c.context, cert); + else + setCerts(c.context, [cert]); } // Set the key after the cert. @@ -318,7 +319,7 @@ exports.createSecureContext = function createSecureContext(options) { if (pfx !== undefined) { if (ArrayIsArray(pfx)) { - for (const val of pfx) { + ArrayPrototypeForEach(pfx, (val) => { const raw = val.buf ? val.buf : val; const pass = val.passphrase || passphrase; if (pass !== undefined) { @@ -326,7 +327,7 @@ exports.createSecureContext = function createSecureContext(options) { } else { c.context.loadPKCS12(toBuf(raw)); } - } + }); } else if (passphrase) { c.context.loadPKCS12(toBuf(pfx), toBuf(passphrase)); } else { diff --git a/lib/internal/tls.js b/lib/internal/tls.js index da40f635286bfe..57366839c170ae 100644 --- a/lib/internal/tls.js +++ b/lib/internal/tls.js @@ -2,6 +2,7 @@ const { ArrayIsArray, + ArrayPrototypeForEach, ArrayPrototypePush, StringPrototypeIndexOf, StringPrototypeSlice, @@ -13,7 +14,7 @@ const { // C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org function parseCertString(s) { const out = ObjectCreate(null); - for (const part of StringPrototypeSplit(s, '\n')) { + ArrayPrototypeForEach(StringPrototypeSplit(s, '\n'), (part) => { const sepIndex = StringPrototypeIndexOf(part, '='); if (sepIndex > 0) { const key = StringPrototypeSlice(part, 0, sepIndex); @@ -27,7 +28,7 @@ function parseCertString(s) { out[key] = value; } } - } + }); return out; } diff --git a/lib/tls.js b/lib/tls.js index 7ee9ae49f03a68..49c7d245171b10 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -24,6 +24,7 @@ const { Array, ArrayIsArray, + ArrayPrototypeForEach, ArrayPrototypeIncludes, ArrayPrototypeJoin, ArrayPrototypePush, @@ -31,6 +32,7 @@ const { ArrayPrototypeSome, ObjectDefineProperty, ObjectFreeze, + ReflectConstruct, RegExpPrototypeTest, StringFromCharCode, StringPrototypeCharCodeAt, @@ -214,7 +216,7 @@ function check(hostParts, pattern, wildcards) { if (patternParts.length <= 2) return false; - const [prefix, suffix] = patternSubdomainParts; + const { 0: prefix, 1: suffix } = patternSubdomainParts; if (prefix.length + suffix.length > hostSubdomain.length) return false; @@ -239,7 +241,8 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { hostname = '' + hostname; if (altNames) { - for (const name of StringPrototypeSplit(altNames, ', ')) { + const splitAltNames = StringPrototypeSplit(altNames, ', '); + ArrayPrototypeForEach(splitAltNames, (name) => { if (StringPrototypeStartsWith(name, 'DNS:')) { ArrayPrototypePush(dnsNames, StringPrototypeSlice(name, 4)); } else if (StringPrototypeStartsWith(name, 'URI:')) { @@ -264,7 +267,7 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { } else if (StringPrototypeStartsWith(name, 'IP Address:')) { ArrayPrototypePush(ips, canonicalizeIP(StringPrototypeSlice(name, 11))); } - } + }); } let valid = false; @@ -359,7 +362,7 @@ exports.connect = _tls_wrap.connect; exports.createSecurePair = internalUtil.deprecate( function createSecurePair(...args) { - return new SecurePair(...args); + return ReflectConstruct(SecurePair, args); }, 'tls.createSecurePair() is deprecated. Please use ' + 'tls.TLSSocket instead.', 'DEP0064');