Skip to content

Commit 4a963e5

Browse files
committed
fix: IntegrityStream responds to mutating opts object mid-stream
This allows us to start a stream, then get the integrity value mid-way through, and THEN update the options with the expected integrity.
1 parent 0e78fd7 commit 4a963e5

File tree

2 files changed

+74
-8
lines changed

2 files changed

+74
-8
lines changed

index.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,27 @@ class IntegrityStream extends MiniPass {
3737
this[_getOptions]()
3838

3939
// options used for calculating stream. can't be changed.
40+
const { algorithms = defaultOpts.algorithms } = opts
4041
this.algorithms = Array.from(
41-
new Set(opts.algorithms.concat(this.algorithm ? [this.algorithm] : []))
42+
new Set(algorithms.concat(this.algorithm ? [this.algorithm] : []))
4243
)
4344
this.hashes = this.algorithms.map(crypto.createHash)
4445
}
4546

4647
[_getOptions] () {
47-
const opts = this.opts
48+
const {
49+
integrity,
50+
size,
51+
options
52+
} = { ...defaultOpts, ...this.opts }
53+
4854
// For verification
49-
this.sri = opts.integrity ? parse(opts.integrity, opts) : null
50-
this.expectedSize = opts.size
55+
this.sri = integrity ? parse(integrity, this.opts) : null
56+
this.expectedSize = size
5157
this.goodSri = this.sri ? !!Object.keys(this.sri).length : false
52-
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(opts) : null
58+
this.algorithm = this.goodSri ? this.sri.pickAlgorithm(this.opts) : null
5359
this.digests = this.goodSri ? this.sri[this.algorithm] : null
54-
this.optString = getOptString(opts.options)
60+
this.optString = getOptString(options)
5561
}
5662

5763
emit (ev, data) {
@@ -393,8 +399,8 @@ function checkStream (stream, sri, opts) {
393399
}
394400

395401
module.exports.integrityStream = integrityStream
396-
function integrityStream (opts) {
397-
return new IntegrityStream(ssriOpts(opts))
402+
function integrityStream (opts = {}) {
403+
return new IntegrityStream(opts)
398404
}
399405

400406
module.exports.create = createIntegrity

test/mutable-opts-resilience.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const ssri = require('../')
2+
const t = require('tap')
3+
4+
const data = 'hello world'
5+
const expectIntegrity = ssri.fromData(data, { algorithms: ['sha512'] })
6+
const expectSize = data.length
7+
8+
t.test('support adding bad integrity later', t => {
9+
const opts = {}
10+
const stream = ssri.integrityStream(opts)
11+
opts.integrity = ssri.parse('sha512-deepbeets')
12+
return t.rejects(stream.end(data).collect(), {
13+
code: 'EINTEGRITY'
14+
})
15+
})
16+
17+
t.test('support adding bad integrity string later', t => {
18+
const opts = {}
19+
const stream = ssri.integrityStream(opts)
20+
opts.integrity = 'sha512-deepbeets'
21+
return t.rejects(stream.end(data).collect(), {
22+
code: 'EINTEGRITY'
23+
})
24+
})
25+
26+
t.test('support adding bad size later', t => {
27+
const opts = {}
28+
const stream = ssri.integrityStream(opts)
29+
opts.size = 2
30+
return t.rejects(stream.end(data).collect(), {
31+
code: 'EBADSIZE'
32+
})
33+
})
34+
35+
t.test('support adding good integrity later', t => {
36+
const opts = {}
37+
const stream = ssri.integrityStream(opts)
38+
opts.integrity = expectIntegrity
39+
return stream.end(data).on('verified', match => {
40+
t.same(match, expectIntegrity.sha512[0])
41+
}).collect()
42+
})
43+
44+
t.test('support adding good integrity string later', t => {
45+
const opts = {}
46+
const stream = ssri.integrityStream(opts)
47+
opts.integrity = String(expectIntegrity)
48+
return stream.end(data).on('verified', match => {
49+
t.same(match, expectIntegrity.sha512[0])
50+
}).collect()
51+
})
52+
53+
t.test('support adding good size later', t => {
54+
const opts = {}
55+
const stream = ssri.integrityStream(opts)
56+
opts.size = expectSize
57+
return stream.end(data).on('size', size => {
58+
t.same(size, expectSize)
59+
}).collect()
60+
})

0 commit comments

Comments
 (0)