Skip to content

Commit d04aa1f

Browse files
committed
fix(hashes): IntegrityMetadata -> Hash
BREAKING CHANGE: `.isIntegrityMetadata` is now `.isHash`. Also, any references to `IntegrityMetadata` now refer to `Hash`.
1 parent 1926ac8 commit d04aa1f

File tree

6 files changed

+57
-59
lines changed

6 files changed

+57
-59
lines changed

Diff for: README.md

+26-28
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ ssri.checkData(fs.readFileSync('./my-file'), integrity) // => 'sha512'
6262
* Strict standard compliance.
6363
* `?foo` metadata option support.
6464
* Multiple entries for the same algorithm.
65-
* Object-based integrity metadata manipulation.
65+
* Object-based integrity hash manipulation.
6666
* Small footprint: no dependencies, concise implementation.
6767
* Full test coverage.
6868
* Customizable algorithm picker.
@@ -80,9 +80,9 @@ jump in if you'd like to, or even ask us questions if something isn't clear.
8080
#### <a name="parse"></a> `> ssri.parse(sri, [opts]) -> Integrity`
8181

8282
Parses `sri` into an `Integrity` data structure. `sri` can be an integrity
83-
string, an `IntegrityMetadata`-like with `digest` and `algorithm` fields and an
84-
optional `options` field, or an `Integrity`-like object. The resulting object
85-
will be an `Integrity` instance that has this shape:
83+
string, an `Hash`-like with `digest` and `algorithm` fields and an optional
84+
`options` field, or an `Integrity`-like object. The resulting object will be an
85+
`Integrity` instance that has this shape:
8686

8787
```javascript
8888
{
@@ -94,9 +94,9 @@ will be an `Integrity` instance that has this shape:
9494
}
9595
```
9696

97-
If `opts.single` is truthy, a single `IntegrityMetadata` object will be
98-
returned. That is, a single object that looks like `{algorithm, digest,
99-
options}`, as opposed to a larger object with multiple of these.
97+
If `opts.single` is truthy, a single `Hash` object will be returned. That is, a
98+
single object that looks like `{algorithm, digest, options}`, as opposed to a
99+
larger object with multiple of these.
100100

101101
If `opts.strict` is truthy, the resulting object will be filtered such that
102102
it strictly follows the Subresource Integrity spec, throwing away any entries
@@ -116,7 +116,7 @@ ssri.parse('sha512-9KhgCRIx/AmzC8xqYJTZRrnO8OW2Pxyl2DIMZSBOr0oDvtEFyht3xpp71j/r/
116116

117117
This function is identical to [`Integrity#toString()`](#integrity-to-string),
118118
except it can be used on _any_ object that [`parse`](#parse) can handle -- that
119-
is, a string, an `IntegrityMetadata`-like, or an `Integrity`-like.
119+
is, a string, an `Hash`-like, or an `Integrity`-like.
120120

121121
The `opts.sep` option defines the string to use when joining multiple entries
122122
together. To be spec-compliant, this _must_ be whitespace. The default is a
@@ -132,7 +132,7 @@ parsing rules. See [`ssri.parse`](#parse).
132132
ssri.stringify('\n\rsha512-foo\n\t\tsha384-bar')
133133
// -> 'sha512-foo sha384-bar'
134134

135-
// IntegrityMetadata-like: only a single entry.
135+
// Hash-like: only a single entry.
136136
ssri.stringify({
137137
algorithm: 'sha512',
138138
digest:'9KhgCRIx/AmzC8xqYJTZRrnO8OW2Pxyl2DIMZSBOr0oDvtEFyht3xpp71j/r/pAe1DM+JI/A+line3jUBgzQ7A==',
@@ -157,8 +157,8 @@ ssri.stringify({
157157

158158
#### <a name="integrity-concat"></a> `> Integrity#concat(otherIntegrity, [opts]) -> Integrity`
159159

160-
Concatenates an `Integrity` object with another IntegrityLike, or a string
161-
representing integrity metadata.
160+
Concatenates an `Integrity` object with another IntegrityLike, or an integrity
161+
string.
162162

163163
This is functionally equivalent to concatenating the string format of both
164164
integrity arguments, and calling [`ssri.parse`](#ssri-parse) on the new string.
@@ -183,7 +183,7 @@ desktopIntegrity.concat(mobileIntegrity)
183183

184184
#### <a name="integrity-to-string"></a> `> Integrity#toString([opts]) -> String`
185185

186-
Returns the string representation of an `Integrity` object. All metadata entries
186+
Returns the string representation of an `Integrity` object. All hash entries
187187
will be concatenated in the string by `opts.sep`, which defaults to `' '`.
188188

189189
If you want to serialize an object that didn't from from an `ssri` function,
@@ -219,9 +219,9 @@ ssri.parse('sha1-WEakDigEST sha512-yzd8ELD1piyANiWnmdnpCL5F52f10UfUdEkHywVZeqTt0
219219

220220
#### <a name="integrity-hex-digest"></a> `> Integrity#hexDigest() -> String`
221221

222-
`Integrity` is assumed to be either a single-hash `Integrity` instance, or an
223-
`IntegrityMetadata` instance. Returns its `digest`, converted to a hex
224-
representation of the base64 data.
222+
`Integrity` is assumed to be either a single-hash `Integrity` instance, or a
223+
`Hash` instance. Returns its `digest`, converted to a hex representation of the
224+
base64 data.
225225

226226
##### Example
227227

@@ -240,15 +240,15 @@ algorithm + '-' + Buffer.from(hexDigest, 'hex').toString('base64')
240240
```
241241

242242
`opts.options` may optionally be passed in: it must be an array of option
243-
strings that will be added to all generated integrity metadata generated by
243+
strings that will be added to all generated integrity hashes generated by
244244
`fromData`. This is a loosely-specified feature of SRIs, and currently has no
245245
specified semantics besides being `?`-separated. Use at your own risk, and
246246
probably avoid if your integrity strings are meant to be used with browsers.
247247

248248
If `opts.strict` is true, the integrity object will be created using strict
249249
parsing rules. See [`ssri.parse`](#parse).
250250

251-
If `opts.single` is true, a single `IntegrityMetadata` object will be returned.
251+
If `opts.single` is true, a single `Hash` object will be returned.
252252

253253
##### Example
254254

@@ -261,13 +261,13 @@ ssri.fromHex('75e69d6de79f', 'sha1').toString() // 'sha1-deadbeef'
261261
Creates an `Integrity` object from either string or `Buffer` data, calculating
262262
all the requested hashes and adding any specified options to the object.
263263

264-
`opts.algorithms` determines which algorithms to generate metadata for. All
264+
`opts.algorithms` determines which algorithms to generate hashes for. All
265265
results will be included in a single `Integrity` object. The default value for
266266
`opts.algorithms` is `['sha512']`. All algorithm strings must be hashes listed
267267
in `crypto.getHashes()` for the host Node.js platform.
268268

269269
`opts.options` may optionally be passed in: it must be an array of option
270-
strings that will be added to all generated integrity metadata generated by
270+
strings that will be added to all generated integrity hashes generated by
271271
`fromData`. This is a loosely-specified feature of SRIs, and currently has no
272272
specified semantics besides being `?`-separated. Use at your own risk, and
273273
probably avoid if your integrity strings are meant to be used with browsers.
@@ -312,7 +312,7 @@ ssri.fromStream(fs.createReadStream('index.js'), {
312312
}) // succeeds
313313
```
314314

315-
#### <a name="check-data"></a> `> ssri.checkData(data, sri, [opts]) -> IntegrityMetadata|false`
315+
#### <a name="check-data"></a> `> ssri.checkData(data, sri, [opts]) -> Hash|false`
316316

317317
Verifies `data` integrity against an `sri` argument. `data` may be either a
318318
`String` or a `Buffer`, and `sri` can be any subresource integrity
@@ -334,14 +334,14 @@ ssri.checkData(data, 'sha256-l981iLWj8kurw4UbNy8Lpxqdzd7UOxS50Glhv8FwfZ0')
334334
ssri.checkData(data, 'sha1-BaDDigEST') // -> false
335335
```
336336

337-
#### <a name="check-stream"></a> `> ssri.checkStream(stream, sri, [opts]) -> Promise<IntegrityMetadata>`
337+
#### <a name="check-stream"></a> `> ssri.checkStream(stream, sri, [opts]) -> Promise<Hash>`
338338

339339
Verifies the contents of `stream` against an `sri` argument. `stream` will be
340340
consumed in its entirety by this process. `sri` can be any subresource integrity
341341
representation that [`ssri.parse`](#parse) can handle.
342342

343343
`checkStream` will return a Promise that either resolves to the
344-
`IntegrityMetadata` that succeeded verification, or, if the verification fails
344+
`Hash` that succeeded verification, or, if the verification fails
345345
or an error happens with `stream`, the Promise will be rejected.
346346

347347
If the Promise is rejected because verification failed, the returned error will
@@ -373,7 +373,7 @@ ssri.checkStream(
373373
ssri.checkStream(
374374
fs.createReadStream('index.js'),
375375
'sha256-l981iLWj8kurw4UbNy8Lpxqdzd7UOxS50Glhv8FwfZ0'
376-
) // -> Promise<IntegrityMetadata>
376+
) // -> Promise<Hash>
377377

378378
ssri.checkStream(
379379
fs.createReadStream('index.js'),
@@ -392,15 +392,13 @@ data, respectively.
392392
If `opts.algorithms` is passed in, the listed algorithms will be calculated when
393393
generating the final `Integrity` instance. The default is `['sha512']`.
394394

395-
If `opts.single` is passed in, a single `IntegrityMetadata` instance will be
396-
returned.
395+
If `opts.single` is passed in, a single `Hash` instance will be returned.
397396

398397
If `opts.integrity` is passed in, it should be an `integrity` value understood
399398
by [`parse`](#parse) that the stream will check the data against. If
400399
verification succeeds, the integrity stream will emit a `verified` event whose
401-
value is a single `IntegrityMetadata` object that is the one that succeeded
402-
verification. If verification fails, the stream will error with an
403-
`EBADCHECKSUM` error code.
400+
value is a single `Hash` object that is the one that succeeded verification. If
401+
verification fails, the stream will error with an `EBADCHECKSUM` error code.
404402

405403
If `opts.size` is given, it will be matched against the stream size. An error
406404
with `err.code` `EBADSIZE` will be emitted by the stream if the expected size

Diff for: index.js

+21-21
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/
1010
const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/]+(?:=?=?))([?\x21-\x7E]*)$/
1111
const VCHAR_REGEX = /^[\x21-\x7E]+$/
1212

13-
class IntegrityMetadata {
14-
get isIntegrityMetadata () { return true }
15-
constructor (metadata, opts) {
13+
class Hash {
14+
get isHash () { return true }
15+
constructor (hash, opts) {
1616
const strict = !!(opts && opts.strict)
17-
this.source = metadata.trim()
18-
// 3.1. Integrity metadata
17+
this.source = hash.trim()
18+
// 3.1. Integrity metadata (called "Hash" by ssri)
1919
// https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description
2020
const match = this.source.match(
2121
strict
@@ -71,8 +71,8 @@ class Integrity {
7171
sep = sep.replace(/\S+/g, ' ')
7272
}
7373
return Object.keys(this).map(k => {
74-
return this[k].map(meta => {
75-
return IntegrityMetadata.prototype.toString.call(meta, opts)
74+
return this[k].map(hash => {
75+
return Hash.prototype.toString.call(hash, opts)
7676
}).filter(x => x.length).join(sep)
7777
}).filter(x => x.length).join(sep)
7878
}
@@ -111,14 +111,14 @@ function _parse (integrity, opts) {
111111
// 3.4.3. Parse metadata
112112
// https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
113113
if (opts.single) {
114-
return new IntegrityMetadata(integrity, opts)
114+
return new Hash(integrity, opts)
115115
}
116116
return integrity.trim().split(/\s+/).reduce((acc, string) => {
117-
const metadata = new IntegrityMetadata(string, opts)
118-
if (metadata.algorithm && metadata.digest) {
119-
const algo = metadata.algorithm
117+
const hash = new Hash(string, opts)
118+
if (hash.algorithm && hash.digest) {
119+
const algo = hash.algorithm
120120
if (!acc[algo]) { acc[algo] = [] }
121-
acc[algo].push(metadata)
121+
acc[algo].push(hash)
122122
}
123123
return acc
124124
}, new Integrity())
@@ -127,7 +127,7 @@ function _parse (integrity, opts) {
127127
module.exports.stringify = stringify
128128
function stringify (obj, opts) {
129129
if (obj.algorithm && obj.digest) {
130-
return IntegrityMetadata.prototype.toString.call(obj, opts)
130+
return Hash.prototype.toString.call(obj, opts)
131131
} else if (typeof obj === 'string') {
132132
return stringify(parse(obj, opts), opts)
133133
} else {
@@ -156,14 +156,14 @@ function fromData (data, opts) {
156156
: ''
157157
return algorithms.reduce((acc, algo) => {
158158
const digest = crypto.createHash(algo).update(data).digest('base64')
159-
const meta = new IntegrityMetadata(
159+
const hash = new Hash(
160160
`${algo}-${digest}${optString}`,
161161
opts
162162
)
163-
if (meta.algorithm && meta.digest) {
164-
const algo = meta.algorithm
163+
if (hash.algorithm && hash.digest) {
164+
const algo = hash.algorithm
165165
if (!acc[algo]) { acc[algo] = [] }
166-
acc[algo].push(meta)
166+
acc[algo].push(hash)
167167
}
168168
return acc
169169
}, new Integrity())
@@ -192,7 +192,7 @@ function checkData (data, sri, opts) {
192192
const algorithm = sri.pickAlgorithm(opts)
193193
const digests = sri[algorithm]
194194
const digest = crypto.createHash(algorithm).update(data).digest('base64')
195-
return digests.find(meta => meta.digest === digest) || false
195+
return digests.find(hash => hash.digest === digest) || false
196196
}
197197

198198
module.exports.checkStream = checkStream
@@ -243,9 +243,9 @@ function integrityStream (opts) {
243243
const match = (
244244
// Integrity verification mode
245245
opts.integrity &&
246-
digests.find(meta => {
247-
return newSri[algorithm].find(newmeta => {
248-
return meta.digest === newmeta.digest
246+
digests.find(hash => {
247+
return newSri[algorithm].find(newhash => {
248+
return hash.digest === newhash.digest
249249
})
250250
})
251251
)

Diff for: test/check.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ test('checkData', t => {
3939
digest: hash(TEST_DATA, 'sha512')
4040
}),
4141
meta,
42-
'Accepts IntegrityMetadata-like SRI'
42+
'Accepts Hash-like SRI'
4343
)
4444
t.deepEqual(
4545
ssri.checkData(TEST_DATA.toString('utf8'), sri),
@@ -110,7 +110,7 @@ test('checkStream', t => {
110110
digest: hash(TEST_DATA, 'sha512')
111111
})
112112
}).then(res => {
113-
t.deepEqual(res, meta, 'Accepts IntegrityMetadata-like SRI')
113+
t.deepEqual(res, meta, 'Accepts Hash-like SRI')
114114
return ssri.checkStream(
115115
fileStream(),
116116
`sha512-nope sha512-${hash(TEST_DATA, 'sha512')}`

Diff for: test/integrity.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ test('concat()', t => {
3434
t.equal(
3535
sri.concat({digest: 'bar', algorithm: 'sha384'}).toString(),
3636
'sha512-foo sha384-bar',
37-
'concatenates with an IntegrityMetadata-like'
37+
'concatenates with an Hash-like'
3838
)
3939
t.equal(
4040
sri.concat({
@@ -97,12 +97,12 @@ test('hexDigest()', t => {
9797
t.done()
9898
})
9999

100-
test('isIntegrity and isIntegrityMetadata', t => {
100+
test('isIntegrity and isHash', t => {
101101
const sri = ssri.parse('sha512-bar')
102102
t.ok(sri.isIntegrity, 'full sri has !!.isIntegrity')
103103
t.ok(
104-
sri['sha512'][0].isIntegrityMetadata,
105-
'sri hash has !!.isIntegrityMetadata'
104+
sri['sha512'][0].isHash,
105+
'sri hash has !!.isHash'
106106
)
107107
t.done()
108108
})

Diff for: test/parse.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ test('parses single-entry integrity string', t => {
2626
t.done()
2727
})
2828

29-
test('can parse single-entry string directly into IntegrityMetadata', t => {
29+
test('can parse single-entry string directly into Hash', t => {
3030
const sha = hash(TEST_DATA, 'sha512')
3131
const integrity = `sha512-${sha}`
3232
t.deepEqual(ssri.parse(integrity, {single: true}), {
3333
source: integrity,
3434
digest: sha,
3535
algorithm: 'sha512',
3636
options: []
37-
}, 'single entry parsed into single IntegrityMetadata instance')
37+
}, 'single entry parsed into single Hash instance')
3838
t.done()
3939
})
4040

41-
test('accepts IntegrityMetadata-likes as input', t => {
41+
test('accepts Hash-likes as input', t => {
4242
const algorithm = 'sha512'
4343
const digest = hash(TEST_DATA, 'sha512')
4444
const sriLike = {

Diff for: test/stringify.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ test('serializes Integrity-likes', t => {
3535
t.done()
3636
})
3737

38-
test('serializes IntegrityMetadata-likes', t => {
38+
test('serializes Hash-likes', t => {
3939
const sriLike = {
4040
digest: 'foo',
4141
algorithm: 'sha512'

0 commit comments

Comments
 (0)