11'use strict' ;
22
33const {
4- SafeMap ,
5- SafeWeakMap ,
4+ Map ,
5+ MapPrototype ,
66 Object,
77 RegExpPrototype,
8+ SafeMap,
89 uncurryThis
910} = primordials ;
1011const {
@@ -21,16 +22,13 @@ const debug = require('internal/util/debuglog').debuglog('policy');
2122const SRI = require ( 'internal/policy/sri' ) ;
2223const crypto = require ( 'crypto' ) ;
2324const { Buffer } = require ( 'buffer' ) ;
24- const { URL } = require ( 'url' ) ;
25+ const { URL } = require ( 'internal/ url' ) ;
2526const { createHash, timingSafeEqual } = crypto ;
2627const HashUpdate = uncurryThis ( crypto . Hash . prototype . update ) ;
2728const HashDigest = uncurryThis ( crypto . Hash . prototype . digest ) ;
2829const BufferEquals = uncurryThis ( Buffer . prototype . equals ) ;
2930const BufferToString = uncurryThis ( Buffer . prototype . toString ) ;
3031const { entries } = Object ;
31- const kIntegrities = new SafeWeakMap ( ) ;
32- const kDependencies = new SafeWeakMap ( ) ;
33- const kReactions = new SafeWeakMap ( ) ;
3432const kRelativeURLStringPattern = / ^ \. { 0 , 2 } \/ / ;
3533const { getOptionValue } = require ( 'internal/options' ) ;
3634const shouldAbortOnUncaughtException =
@@ -54,13 +52,12 @@ function REACTION_LOG(error) {
5452}
5553
5654class Manifest {
55+ #integrities = new SafeMap ( ) ;
56+ #dependencies = new SafeMap ( ) ;
57+ #reaction = null ;
5758 constructor ( obj , manifestURL ) {
58- const integrities = {
59- __proto__ : null ,
60- } ;
61- const dependencies = {
62- __proto__ : null ,
63- } ;
59+ const integrities = this . #integrities;
60+ const dependencies = this . #dependencies;
6461 let reaction = REACTION_THROW ;
6562
6663 if ( obj . onerror ) {
@@ -75,23 +72,33 @@ class Manifest {
7572 }
7673 }
7774
78- kReactions . set ( this , reaction ) ;
75+ this . #reaction = reaction ;
7976 const manifestEntries = entries ( obj . resources ) ;
8077
78+ const parsedURLs = new SafeMap ( ) ;
8179 for ( var i = 0 ; i < manifestEntries . length ; i ++ ) {
82- let url = manifestEntries [ i ] [ 0 ] ;
83- const originalURL = url ;
84- if ( RegExpPrototype . test ( kRelativeURLStringPattern , url ) ) {
85- url = new URL ( url , manifestURL ) . href ;
80+ let resourceHREF = manifestEntries [ i ] [ 0 ] ;
81+ const originalHREF = resourceHREF ;
82+ let resourceURL ;
83+ if ( parsedURLs . has ( resourceHREF ) ) {
84+ resourceURL = parsedURLs . get ( resourceHREF ) ;
85+ resourceHREF = resourceURL . href ;
86+ } else if (
87+ RegExpPrototype . test ( kRelativeURLStringPattern , resourceHREF )
88+ ) {
89+ resourceURL = new URL ( resourceHREF , manifestURL ) ;
90+ resourceHREF = resourceURL . href ;
91+ parsedURLs . set ( originalHREF , resourceURL ) ;
92+ parsedURLs . set ( resourceHREF , resourceURL ) ;
8693 }
8794 let integrity = manifestEntries [ i ] [ 1 ] . integrity ;
8895 if ( ! integrity ) integrity = null ;
8996 if ( integrity != null ) {
90- debug ( `Manifest contains integrity for url ${ originalURL } ` ) ;
97+ debug ( `Manifest contains integrity for url ${ originalHREF } ` ) ;
9198 if ( typeof integrity === 'string' ) {
9299 const sri = Object . freeze ( SRI . parse ( integrity ) ) ;
93- if ( url in integrities ) {
94- const old = integrities [ url ] ;
100+ if ( integrities . has ( resourceHREF ) ) {
101+ const old = integrities . get ( resourceHREF ) ;
95102 let mismatch = false ;
96103
97104 if ( old . length !== sri . length ) {
@@ -112,14 +119,16 @@ class Manifest {
112119 }
113120
114121 if ( mismatch ) {
115- throw new ERR_MANIFEST_INTEGRITY_MISMATCH ( url ) ;
122+ throw new ERR_MANIFEST_INTEGRITY_MISMATCH ( resourceURL ) ;
116123 }
117124 }
118- integrities [ url ] = sri ;
125+ integrities . set ( resourceHREF , sri ) ;
119126 } else if ( integrity === true ) {
120- integrities [ url ] = true ;
127+ integrities . set ( resourceHREF , true ) ;
121128 } else {
122- throw new ERR_MANIFEST_INVALID_RESOURCE_FIELD ( url , 'integrity' ) ;
129+ throw new ERR_MANIFEST_INVALID_RESOURCE_FIELD (
130+ resourceHREF ,
131+ 'integrity' ) ;
123132 }
124133 }
125134
@@ -128,50 +137,72 @@ class Manifest {
128137 dependencyMap = { } ;
129138 }
130139 if ( typeof dependencyMap === 'object' && ! Array . isArray ( dependencyMap ) ) {
131- dependencies [ url ] = new SafeMap ( Object . entries ( dependencyMap ) . map (
132- ( [ from , to ] ) => {
140+ /**
141+ * @returns {true | URL }
142+ */
143+ const dependencyRedirectList = ( toSpecifier ) => {
144+ if ( toSpecifier in dependencyMap !== true ) {
145+ return null ;
146+ } else {
147+ const to = dependencyMap [ toSpecifier ] ;
133148 if ( to === true ) {
134- return [ from , to ] ;
149+ return true ;
135150 }
136- if ( canBeRequiredByUsers ( to ) ) {
137- return [ from , `node:${ to } ` ] ;
151+ if ( parsedURLs . has ( to ) ) {
152+ return parsedURLs . get ( to ) ;
153+ } else if ( canBeRequiredByUsers ( to ) ) {
154+ const href = `node:${ to } ` ;
155+ const resolvedURL = new URL ( href ) ;
156+ parsedURLs . set ( to , resolvedURL ) ;
157+ parsedURLs . set ( href , resolvedURL ) ;
158+ return resolvedURL ;
138159 } else if ( RegExpPrototype . test ( kRelativeURLStringPattern , to ) ) {
139- return [ from , new URL ( to , manifestURL ) . href ] ;
160+ const resolvedURL = new URL ( to , manifestURL ) ;
161+ const href = resourceURL . href ;
162+ parsedURLs . set ( to , resolvedURL ) ;
163+ parsedURLs . set ( href , resolvedURL ) ;
164+ return resolvedURL ;
140165 }
141- return [ from , new URL ( to ) . href ] ;
142- } )
143- ) ;
166+ const resolvedURL = new URL ( to ) ;
167+ const href = resourceURL . href ;
168+ parsedURLs . set ( to , resolvedURL ) ;
169+ parsedURLs . set ( href , resolvedURL ) ;
170+ return resolvedURL ;
171+ }
172+ } ;
173+ dependencies . set ( resourceHREF , dependencyRedirectList ) ;
144174 } else if ( dependencyMap === true ) {
145- dependencies [ url ] = true ;
175+ const arbitraryDependencies = ( ) => true ;
176+ dependencies . set ( resourceHREF , arbitraryDependencies ) ;
146177 } else {
147- throw new ERR_MANIFEST_INVALID_RESOURCE_FIELD ( url , 'dependencies' ) ;
178+ throw new ERR_MANIFEST_INVALID_RESOURCE_FIELD (
179+ resourceHREF ,
180+ 'dependencies' ) ;
148181 }
149182 }
150- Object . freeze ( integrities ) ;
151- kIntegrities . set ( this , integrities ) ;
152- Object . freeze ( dependencies ) ;
153- kDependencies . set ( this , dependencies ) ;
154183 Object . freeze ( this ) ;
155184 }
156185
157- getRedirects ( requester ) {
158- const dependencies = kDependencies . get ( this ) ;
159- if ( dependencies && requester in dependencies ) {
186+ getRedirector ( requester ) {
187+ requester = `${ requester } ` ;
188+ const dependencies = this . #dependencies;
189+ if ( dependencies . has ( requester ) ) {
160190 return {
161- map : dependencies [ requester ] ,
162- reaction : kReactions . get ( this )
191+ resolve : ( to ) => dependencies . get ( requester ) ( ` ${ to } ` ) ,
192+ reaction : this . #reaction
163193 } ;
164194 }
165195 return null ;
166196 }
167197
168198 assertIntegrity ( url , content ) {
169- debug ( `Checking integrity of ${ url } ` ) ;
170- const integrities = kIntegrities . get ( this ) ;
171- const realIntegrities = new SafeMap ( ) ;
199+ const href = `${ url } ` ;
200+ debug ( `Checking integrity of ${ href } ` ) ;
201+ const integrities = this . #integrities;
202+ const realIntegrities = new Map ( ) ;
172203
173- if ( integrities && url in integrities ) {
174- const integrityEntries = integrities [ url ] ;
204+ if ( integrities . has ( href ) ) {
205+ const integrityEntries = integrities . get ( href ) ;
175206 if ( integrityEntries === true ) return true ;
176207 // Avoid clobbered Symbol.iterator
177208 for ( var i = 0 ; i < integrityEntries . length ; i ++ ) {
@@ -186,11 +217,15 @@ class Manifest {
186217 timingSafeEqual ( digest , expected ) ) {
187218 return true ;
188219 }
189- realIntegrities . set ( algorithm , BufferToString ( digest , 'base64' ) ) ;
220+ MapPrototype . set (
221+ realIntegrities ,
222+ algorithm ,
223+ BufferToString ( digest , 'base64' )
224+ ) ;
190225 }
191226 }
192227 const error = new ERR_MANIFEST_ASSERT_INTEGRITY ( url , realIntegrities ) ;
193- kReactions . get ( this ) ( error ) ;
228+ this . #reaction ( error ) ;
194229 }
195230}
196231
0 commit comments