Skip to content

Commit

Permalink
fix: IntegrityStream responds to mutating opts object mid-stream
Browse files Browse the repository at this point in the history
This allows us to start a stream, then get the integrity value mid-way
through, and THEN update the options with the expected integrity.
  • Loading branch information
isaacs committed Feb 17, 2020
1 parent 0e78fd7 commit 4a963e5
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
22 changes: 14 additions & 8 deletions index.js
Expand Up @@ -37,21 +37,27 @@ class IntegrityStream extends MiniPass {
this[_getOptions]()

// options used for calculating stream. can't be changed.
const { algorithms = defaultOpts.algorithms } = opts
this.algorithms = Array.from(
new Set(opts.algorithms.concat(this.algorithm ? [this.algorithm] : []))
new Set(algorithms.concat(this.algorithm ? [this.algorithm] : []))
)
this.hashes = this.algorithms.map(crypto.createHash)
}

[_getOptions] () {
const opts = this.opts
const {
integrity,
size,
options
} = { ...defaultOpts, ...this.opts }

// For verification
this.sri = opts.integrity ? parse(opts.integrity, opts) : null
this.expectedSize = opts.size
this.sri = integrity ? parse(integrity, this.opts) : null
this.expectedSize = size
this.goodSri = this.sri ? !!Object.keys(this.sri).length : false
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(opts) : null
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(this.opts) : null
this.digests = this.goodSri ? this.sri[this.algorithm] : null
this.optString = getOptString(opts.options)
this.optString = getOptString(options)
}

emit (ev, data) {
Expand Down Expand Up @@ -393,8 +399,8 @@ function checkStream (stream, sri, opts) {
}

module.exports.integrityStream = integrityStream
function integrityStream (opts) {
return new IntegrityStream(ssriOpts(opts))
function integrityStream (opts = {}) {
return new IntegrityStream(opts)
}

module.exports.create = createIntegrity
Expand Down
60 changes: 60 additions & 0 deletions test/mutable-opts-resilience.js
@@ -0,0 +1,60 @@
const ssri = require('../')
const t = require('tap')

const data = 'hello world'
const expectIntegrity = ssri.fromData(data, { algorithms: ['sha512'] })
const expectSize = data.length

t.test('support adding bad integrity later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.integrity = ssri.parse('sha512-deepbeets')
return t.rejects(stream.end(data).collect(), {
code: 'EINTEGRITY'
})
})

t.test('support adding bad integrity string later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.integrity = 'sha512-deepbeets'
return t.rejects(stream.end(data).collect(), {
code: 'EINTEGRITY'
})
})

t.test('support adding bad size later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.size = 2
return t.rejects(stream.end(data).collect(), {
code: 'EBADSIZE'
})
})

t.test('support adding good integrity later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.integrity = expectIntegrity
return stream.end(data).on('verified', match => {
t.same(match, expectIntegrity.sha512[0])
}).collect()
})

t.test('support adding good integrity string later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.integrity = String(expectIntegrity)
return stream.end(data).on('verified', match => {
t.same(match, expectIntegrity.sha512[0])
}).collect()
})

t.test('support adding good size later', t => {
const opts = {}
const stream = ssri.integrityStream(opts)
opts.size = expectSize
return stream.end(data).on('size', size => {
t.same(size, expectSize)
}).collect()
})

0 comments on commit 4a963e5

Please sign in to comment.