Skip to content

Commit

Permalink
fix: faster toString for integrity (#75)
Browse files Browse the repository at this point in the history
Note that the ordering of hashes in the result varies slightly.
  • Loading branch information
H4ad committed Apr 3, 2023
1 parent 6e6877d commit a316b12
Showing 1 changed file with 48 additions and 6 deletions.
54 changes: 48 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const crypto = require('crypto')
const MiniPass = require('minipass')

const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512']
const SPEC_ALGORITHMS = ['sha512', 'sha384', 'sha256']
const DEFAULT_ALGORITHMS = ['sha512']

// TODO: this should really be a hardcoded list of algorithms we support,
Expand Down Expand Up @@ -186,6 +186,39 @@ class Hash {
}
}

function integrityHashToString (toString, sep, opts, hashes) {
const toStringIsNotEmpty = toString !== ''

let shouldAddFirstSep = false
let complement = ''

const lastIndex = hashes.length - 1

for (let i = 0; i < lastIndex; i++) {
const hashString = Hash.prototype.toString.call(hashes[i], opts)

if (hashString) {
shouldAddFirstSep = true

complement += hashString
complement += sep
}
}

const finalHashString = Hash.prototype.toString.call(hashes[lastIndex], opts)

if (finalHashString) {
shouldAddFirstSep = true
complement += finalHashString
}

if (toStringIsNotEmpty && shouldAddFirstSep) {
return toString + sep + complement
}

return toString + complement
}

class Integrity {
get isIntegrity () {
return true
Expand All @@ -201,15 +234,24 @@ class Integrity {

toString (opts) {
let sep = opts?.sep || ' '
let toString = ''

if (opts?.strict) {
// Entries must be separated by whitespace, according to spec.
sep = sep.replace(/\S+/g, ' ')

for (const hash of SPEC_ALGORITHMS) {
if (this[hash]) {
toString = integrityHashToString(toString, sep, opts, this[hash])
}
}
} else {
for (const hash of Object.keys(this)) {
toString = integrityHashToString(toString, sep, opts, this[hash])
}
}
return Object.keys(this).map(k => {
return this[k].map(hash => {
return Hash.prototype.toString.call(hash, opts)
}).filter(x => x.length).join(sep)
}).filter(x => x.length).join(sep)

return toString
}

concat (integrity, opts) {
Expand Down

0 comments on commit a316b12

Please sign in to comment.