Skip to content

Commit 049b89e

Browse files
committed
feat(fromHex): ssri.fromHex to make it easier to generate them from hex valus
1 parent 1b29e6f commit 049b89e

3 files changed

Lines changed: 59 additions & 5 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) hashes.
2323
* [`Integrity#pickAlgorithm`](#integrity-pick-algorithm)
2424
* [`IntegrityMetadata#hexDigest`](#integrity-metadata-hex-digest)
2525
* Integrity Generation
26+
* [`fromHex`](#from-hex)
2627
* [`fromData`](#from-data)
2728
* [`fromStream`](#from-stream)
2829
* Integrity Verification
@@ -227,6 +228,33 @@ to a hex representation of the base64 data.
227228
ssri.parse('sha1-deadbeef', {single: true}).hexDigest() // '75e69d6de79f'
228229
```
229230

231+
#### <a name="from-hex"></a> `> ssri.fromHex(hexDigest, algorithm, [opts]) -> Integrity`
232+
233+
Creates an `Integrity` object with a single entry, based on a hex-formatted
234+
hash. This is a utility function to help convert existing shasums to the
235+
Integrity format, and is roughly equivalent to something like:
236+
237+
```javascript
238+
algorithm + '-' + Buffer.from(hexDigest, 'hex').toString('base64')
239+
```
240+
241+
`opts.options` may optionally be passed in: it must be an array of option
242+
strings that will be added to all generated integrity metadata generated by
243+
`fromData`. This is a loosely-specified feature of SRIs, and currently has no
244+
specified semantics besides being `?`-separated. Use at your own risk, and
245+
probably avoid if your integrity strings are meant to be used with browsers.
246+
247+
If `opts.strict` is true, the integrity object will be created using strict
248+
parsing rules. See [`ssri.parse`](#parse).
249+
250+
If `opts.single` is true, a single `IntegrityMetadata` object will be returned.
251+
252+
##### Example
253+
254+
```javascript
255+
ssri.fromHex('75e69d6de79f', 'sha1').toString() // 'sha1-deadbeef'
256+
```
257+
230258
#### <a name="from-data"></a> `> ssri.fromData(data, [opts]) -> Integrity`
231259

232260
Creates an `Integrity` object from either string or `Buffer` data, calculating

index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ class IntegrityMetadata {
3131
this.options = rawOpts ? rawOpts.slice(1).split('?') : []
3232
}
3333
hexDigest () {
34-
return this.digest && (
35-
Buffer.from
36-
? Buffer.from(this.digest, 'base64')
37-
: new Buffer(this.digest, 'base64')
38-
).toString('hex')
34+
return this.digest && bufFrom(this.digest, 'base64').toString('hex')
3935
}
4036
toString (opts) {
4137
if (opts && opts.strict) {
@@ -136,6 +132,18 @@ function stringify (obj, opts) {
136132
}
137133
}
138134

135+
module.exports.fromHex = fromHex
136+
function fromHex (hexDigest, algorithm, opts) {
137+
const optString = (opts && opts.options && opts.options.length)
138+
? `?${opts.options.join('?')}`
139+
: ''
140+
return parse(
141+
`${algorithm}-${
142+
bufFrom(hexDigest, 'hex').toString('base64')
143+
}${optString}`, opts
144+
)
145+
}
146+
139147
module.exports.fromData = fromData
140148
function fromData (data, opts) {
141149
opts = opts || {}
@@ -254,3 +262,7 @@ function getPrioritizedHash (algo1, algo2) {
254262
? algo1
255263
: algo2
256264
}
265+
266+
function bufFrom (data, enc) {
267+
return Buffer.from ? Buffer.from(data, enc) : new Buffer(data, enc)
268+
}

test/from.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ function fileStream () {
1616
return fs.createReadStream(__filename)
1717
}
1818

19+
test('fromHex', t => {
20+
t.equal(
21+
ssri.fromHex('deadbeef', 'sha1').toString(),
22+
`sha1-3q2+7w==`,
23+
'created an Integrity object from a given hex + sha'
24+
)
25+
t.equal(
26+
ssri.fromHex('deadbeef', 'sha512', {options: ['a', 'b', 'c']}).toString(),
27+
`sha512-3q2+7w==?a?b?c`,
28+
'options added to entry'
29+
)
30+
t.done()
31+
})
32+
1933
test('fromData', t => {
2034
t.equal(
2135
ssri.fromData(TEST_DATA).toString(),

0 commit comments

Comments
 (0)