Skip to content

Commit 61dccf8

Browse files
committed
perf: remove spread of defaultOpts
1 parent 61d92a1 commit 61dccf8

File tree

1 file changed

+22
-43
lines changed

1 file changed

+22
-43
lines changed

lib/index.js

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ const defaultOpts = {
2222
strict: false,
2323
}
2424

25-
const ssriOpts = (opts = {}) => ({ ...defaultOpts, ...opts })
26-
2725
const getOptString = options => !options || !options.length
2826
? ''
2927
: `?${options.join('?')}`
@@ -44,27 +42,21 @@ class IntegrityStream extends MiniPass {
4442
this[_getOptions]()
4543

4644
// options used for calculating stream. can't be changed.
47-
const { algorithms = defaultOpts.algorithms } = opts
45+
const algorithms = opts?.algorithms || defaultOpts.algorithms
4846
this.algorithms = Array.from(
4947
new Set(algorithms.concat(this.algorithm ? [this.algorithm] : []))
5048
)
5149
this.hashes = this.algorithms.map(crypto.createHash)
5250
}
5351

5452
[_getOptions] () {
55-
const {
56-
integrity,
57-
size,
58-
options,
59-
} = { ...defaultOpts, ...this.opts }
60-
6153
// For verification
62-
this.sri = integrity ? parse(integrity, this.opts) : null
63-
this.expectedSize = size
54+
this.sri = this.opts?.integrity ? parse(this.opts?.integrity, this.opts) : null
55+
this.expectedSize = this.opts?.size
6456
this.goodSri = this.sri ? !!Object.keys(this.sri).length : false
6557
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(this.opts) : null
6658
this.digests = this.goodSri ? this.sri[this.algorithm] : null
67-
this.optString = getOptString(options)
59+
this.optString = getOptString(this.opts?.options)
6860
}
6961

7062
on (ev, handler) {
@@ -141,8 +133,7 @@ class Hash {
141133
}
142134

143135
constructor (hash, opts) {
144-
opts = ssriOpts(opts)
145-
const strict = !!opts.strict
136+
const strict = opts?.strict
146137
this.source = hash.trim()
147138

148139
// set default values so that we make V8 happy to
@@ -161,7 +152,7 @@ class Hash {
161152
if (!match) {
162153
return
163154
}
164-
if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) {
155+
if (strict && !SPEC_ALGORITHMS.includes(match[1])) {
165156
return
166157
}
167158
this.algorithm = match[1]
@@ -182,14 +173,13 @@ class Hash {
182173
}
183174

184175
toString (opts) {
185-
opts = ssriOpts(opts)
186-
if (opts.strict) {
176+
if (opts?.strict) {
187177
// Strict mode enforces the standard as close to the foot of the
188178
// letter as it can.
189179
if (!(
190180
// The spec has very restricted productions for algorithms.
191181
// https://www.w3.org/TR/CSP2/#source-list-syntax
192-
SPEC_ALGORITHMS.some(x => x === this.algorithm) &&
182+
SPEC_ALGORITHMS.includes(this.algorithm) &&
193183
// Usually, if someone insists on using a "different" base64, we
194184
// leave it as-is, since there's multiple standards, and the
195185
// specified is not a URL-safe variant.
@@ -224,9 +214,8 @@ class Integrity {
224214
}
225215

226216
toString (opts) {
227-
opts = ssriOpts(opts)
228-
let sep = opts.sep || ' '
229-
if (opts.strict) {
217+
let sep = opts?.sep || ' '
218+
if (opts?.strict) {
230219
// Entries must be separated by whitespace, according to spec.
231220
sep = sep.replace(/\S+/g, ' ')
232221
}
@@ -238,7 +227,6 @@ class Integrity {
238227
}
239228

240229
concat (integrity, opts) {
241-
opts = ssriOpts(opts)
242230
const other = typeof integrity === 'string'
243231
? integrity
244232
: stringify(integrity, opts)
@@ -252,7 +240,6 @@ class Integrity {
252240
// add additional hashes to an integrity value, but prevent
253241
// *changing* an existing integrity hash.
254242
merge (integrity, opts) {
255-
opts = ssriOpts(opts)
256243
const other = parse(integrity, opts)
257244
for (const algo in other) {
258245
if (this[algo]) {
@@ -268,7 +255,6 @@ class Integrity {
268255
}
269256

270257
match (integrity, opts) {
271-
opts = ssriOpts(opts)
272258
const other = parse(integrity, opts)
273259
if (!other) {
274260
return false
@@ -286,8 +272,7 @@ class Integrity {
286272
}
287273

288274
pickAlgorithm (opts) {
289-
opts = ssriOpts(opts)
290-
const pickAlgorithm = opts.pickAlgorithm
275+
const pickAlgorithm = opts?.pickAlgorithm || defaultOpts.pickAlgorithm;
291276
const keys = Object.keys(this)
292277
return keys.reduce((acc, algo) => {
293278
return pickAlgorithm(acc, algo) || acc
@@ -300,7 +285,6 @@ function parse (sri, opts) {
300285
if (!sri) {
301286
return null
302287
}
303-
opts = ssriOpts(opts)
304288
if (typeof sri === 'string') {
305289
return _parse(sri, opts)
306290
} else if (sri.algorithm && sri.digest) {
@@ -315,7 +299,7 @@ function parse (sri, opts) {
315299
function _parse (integrity, opts) {
316300
// 3.4.3. Parse metadata
317301
// https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
318-
if (opts.single) {
302+
if (opts?.single) {
319303
return new Hash(integrity, opts)
320304
}
321305
const hashes = integrity.trim().split(/\s+/).reduce((acc, string) => {
@@ -334,7 +318,6 @@ function _parse (integrity, opts) {
334318

335319
module.exports.stringify = stringify
336320
function stringify (obj, opts) {
337-
opts = ssriOpts(opts)
338321
if (obj.algorithm && obj.digest) {
339322
return Hash.prototype.toString.call(obj, opts)
340323
} else if (typeof obj === 'string') {
@@ -346,8 +329,7 @@ function stringify (obj, opts) {
346329

347330
module.exports.fromHex = fromHex
348331
function fromHex (hexDigest, algorithm, opts) {
349-
opts = ssriOpts(opts)
350-
const optString = getOptString(opts.options)
332+
const optString = getOptString(opts?.options)
351333
return parse(
352334
`${algorithm}-${
353335
Buffer.from(hexDigest, 'hex').toString('base64')
@@ -357,9 +339,8 @@ function fromHex (hexDigest, algorithm, opts) {
357339

358340
module.exports.fromData = fromData
359341
function fromData (data, opts) {
360-
opts = ssriOpts(opts)
361-
const algorithms = opts.algorithms
362-
const optString = getOptString(opts.options)
342+
const algorithms = opts?.algorithms || defaultOpts.algorithms
343+
const optString = getOptString(opts?.options)
363344
return algorithms.reduce((acc, algo) => {
364345
const digest = crypto.createHash(algo).update(data).digest('base64')
365346
const hash = new Hash(
@@ -382,7 +363,6 @@ function fromData (data, opts) {
382363

383364
module.exports.fromStream = fromStream
384365
function fromStream (stream, opts) {
385-
opts = ssriOpts(opts)
386366
const istream = integrityStream(opts)
387367
return new Promise((resolve, reject) => {
388368
stream.pipe(istream)
@@ -399,10 +379,9 @@ function fromStream (stream, opts) {
399379

400380
module.exports.checkData = checkData
401381
function checkData (data, sri, opts) {
402-
opts = ssriOpts(opts)
403382
sri = parse(sri, opts)
404383
if (!sri || !Object.keys(sri).length) {
405-
if (opts.error) {
384+
if (opts?.error) {
406385
throw Object.assign(
407386
new Error('No valid integrity hashes to check against'), {
408387
code: 'EINTEGRITY',
@@ -416,7 +395,8 @@ function checkData (data, sri, opts) {
416395
const digest = crypto.createHash(algorithm).update(data).digest('base64')
417396
const newSri = parse({ algorithm, digest })
418397
const match = newSri.match(sri, opts)
419-
if (match || !opts.error) {
398+
opts = opts || Object.create(null)
399+
if (match || !(opts.error)) {
420400
return match
421401
} else if (typeof opts.size === 'number' && (data.length !== opts.size)) {
422402
/* eslint-disable-next-line max-len */
@@ -440,7 +420,7 @@ function checkData (data, sri, opts) {
440420

441421
module.exports.checkStream = checkStream
442422
function checkStream (stream, sri, opts) {
443-
opts = ssriOpts(opts)
423+
opts = opts || Object.create(null)
444424
opts.integrity = sri
445425
sri = parse(sri, opts)
446426
if (!sri || !Object.keys(sri).length) {
@@ -465,15 +445,14 @@ function checkStream (stream, sri, opts) {
465445
}
466446

467447
module.exports.integrityStream = integrityStream
468-
function integrityStream (opts = {}) {
448+
function integrityStream (opts = Object.create(null)) {
469449
return new IntegrityStream(opts)
470450
}
471451

472452
module.exports.create = createIntegrity
473453
function createIntegrity (opts) {
474-
opts = ssriOpts(opts)
475-
const algorithms = opts.algorithms
476-
const optString = getOptString(opts.options)
454+
const algorithms = opts?.algorithms || defaultOpts.algorithms
455+
const optString = getOptString(opts?.options)
477456

478457
const hashes = algorithms.map(crypto.createHash)
479458

0 commit comments

Comments
 (0)