@@ -29,19 +29,33 @@ class IntegrityStream extends MiniPass {
29
29
this . #getOptions( )
30
30
31
31
// options used for calculating stream. can't be changed.
32
- const algorithms = opts ?. algorithms || DEFAULT_ALGORITHMS
33
- this . algorithms = Array . from (
34
- new Set ( algorithms . concat ( this . algorithm ? [ this . algorithm ] : [ ] ) )
35
- )
32
+ if ( opts ?. algorithms ) {
33
+ this . algorithms = [ ...opts . algorithms ]
34
+ } else {
35
+ this . algorithms = [ ...DEFAULT_ALGORITHMS ]
36
+ }
37
+ if ( this . algorithm !== null && ! this . algorithms . includes ( this . algorithm ) ) {
38
+ this . algorithms . push ( this . algorithm )
39
+ }
40
+
36
41
this . hashes = this . algorithms . map ( crypto . createHash )
37
42
}
38
43
39
44
#getOptions ( ) {
40
45
// For verification
41
46
this . sri = this . opts ?. integrity ? parse ( this . opts ?. integrity , this . opts ) : null
42
47
this . expectedSize = this . opts ?. size
43
- this . goodSri = this . sri ? ! ! Object . keys ( this . sri ) . length : false
44
- this . algorithm = this . goodSri ? this . sri . pickAlgorithm ( this . opts ) : null
48
+
49
+ if ( ! this . sri ) {
50
+ this . algorithm = null
51
+ } else if ( this . sri . isHash ) {
52
+ this . goodSri = true
53
+ this . algorithm = this . sri . algorithm
54
+ } else {
55
+ this . goodSri = ! this . sri . isEmpty ( )
56
+ this . algorithm = this . sri . pickAlgorithm ( this . opts )
57
+ }
58
+
45
59
this . digests = this . goodSri ? this . sri [ this . algorithm ] : null
46
60
this . optString = getOptString ( this . opts ?. options )
47
61
}
@@ -159,6 +173,29 @@ class Hash {
159
173
return this . toString ( )
160
174
}
161
175
176
+ match ( integrity , opts ) {
177
+ const other = parse ( integrity , opts )
178
+ if ( ! other ) {
179
+ return false
180
+ }
181
+ if ( other . isIntegrity ) {
182
+ const algo = other . pickAlgorithm ( opts , [ this . algorithm ] )
183
+
184
+ if ( ! algo ) {
185
+ return false
186
+ }
187
+
188
+ const foundHash = other [ algo ] . find ( hash => hash . digest === this . digest )
189
+
190
+ if ( foundHash ) {
191
+ return foundHash
192
+ }
193
+
194
+ return false
195
+ }
196
+ return other . digest === this . digest ? other : false
197
+ }
198
+
162
199
toString ( opts ) {
163
200
if ( opts ?. strict ) {
164
201
// Strict mode enforces the standard as close to the foot of the
@@ -285,8 +322,9 @@ class Integrity {
285
322
if ( ! other ) {
286
323
return false
287
324
}
288
- const algo = other . pickAlgorithm ( opts )
325
+ const algo = other . pickAlgorithm ( opts , Object . keys ( this ) )
289
326
return (
327
+ ! ! algo &&
290
328
this [ algo ] &&
291
329
other [ algo ] &&
292
330
this [ algo ] . find ( hash =>
@@ -297,12 +335,22 @@ class Integrity {
297
335
) || false
298
336
}
299
337
300
- pickAlgorithm ( opts ) {
338
+ // Pick the highest priority algorithm present, optionally also limited to a
339
+ // set of hashes found in another integrity. When limiting it may return
340
+ // nothing.
341
+ pickAlgorithm ( opts , hashes ) {
301
342
const pickAlgorithm = opts ?. pickAlgorithm || getPrioritizedHash
302
- const keys = Object . keys ( this )
303
- return keys . reduce ( ( acc , algo ) => {
304
- return pickAlgorithm ( acc , algo ) || acc
343
+ const keys = Object . keys ( this ) . filter ( k => {
344
+ if ( hashes ?. length ) {
345
+ return hashes . includes ( k )
346
+ }
347
+ return true
305
348
} )
349
+ if ( keys . length ) {
350
+ return keys . reduce ( ( acc , algo ) => pickAlgorithm ( acc , algo ) || acc )
351
+ }
352
+ // no intersection between this and hashes,
353
+ return null
306
354
}
307
355
}
308
356
@@ -365,7 +413,7 @@ function fromHex (hexDigest, algorithm, opts) {
365
413
366
414
module . exports . fromData = fromData
367
415
function fromData ( data , opts ) {
368
- const algorithms = opts ?. algorithms || DEFAULT_ALGORITHMS
416
+ const algorithms = opts ?. algorithms || [ ... DEFAULT_ALGORITHMS ]
369
417
const optString = getOptString ( opts ?. options )
370
418
return algorithms . reduce ( ( acc , algo ) => {
371
419
const digest = crypto . createHash ( algo ) . update ( data ) . digest ( 'base64' )
@@ -399,7 +447,7 @@ function fromStream (stream, opts) {
399
447
sri = s
400
448
} )
401
449
istream . on ( 'end' , ( ) => resolve ( sri ) )
402
- istream . on ( 'data' , ( ) => { } )
450
+ istream . resume ( )
403
451
} )
404
452
}
405
453
@@ -466,7 +514,7 @@ function checkStream (stream, sri, opts) {
466
514
verified = s
467
515
} )
468
516
checker . on ( 'end' , ( ) => resolve ( verified ) )
469
- checker . on ( 'data' , ( ) => { } )
517
+ checker . resume ( )
470
518
} )
471
519
}
472
520
@@ -477,7 +525,7 @@ function integrityStream (opts = Object.create(null)) {
477
525
478
526
module . exports . create = createIntegrity
479
527
function createIntegrity ( opts ) {
480
- const algorithms = opts ?. algorithms || DEFAULT_ALGORITHMS
528
+ const algorithms = opts ?. algorithms || [ ... DEFAULT_ALGORITHMS ]
481
529
const optString = getOptString ( opts ?. options )
482
530
483
531
const hashes = algorithms . map ( crypto . createHash )
@@ -512,7 +560,7 @@ function createIntegrity (opts) {
512
560
}
513
561
}
514
562
515
- const NODE_HASHES = new Set ( crypto . getHashes ( ) )
563
+ const NODE_HASHES = crypto . getHashes ( )
516
564
517
565
// This is a Best Effort™ at a reasonable priority for hash algos
518
566
const DEFAULT_PRIORITY = [
@@ -522,7 +570,7 @@ const DEFAULT_PRIORITY = [
522
570
'sha3' ,
523
571
'sha3-256' , 'sha3-384' , 'sha3-512' ,
524
572
'sha3_256' , 'sha3_384' , 'sha3_512' ,
525
- ] . filter ( algo => NODE_HASHES . has ( algo ) )
573
+ ] . filter ( algo => NODE_HASHES . includes ( algo ) )
526
574
527
575
function getPrioritizedHash ( algo1 , algo2 ) {
528
576
/* eslint-disable-next-line max-len */
0 commit comments