@@ -58,6 +58,20 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
5858 ) ;
5959 } ;
6060
61+ const definePropertyInterceptors : ( ( o : unknown , p : PropertyKey ) => void | never ) [ ] = [ ] ;
62+
63+ {
64+ const defineProperty_original = Object . defineProperty ;
65+
66+ Object . defineProperty = ( o , p , attributes ) => {
67+ definePropertyInterceptors . forEach ( definePropertyInterceptor => {
68+ definePropertyInterceptor ( o , p ) ;
69+ } ) ;
70+
71+ return defineProperty_original ( o , p , attributes ) ;
72+ } ;
73+ }
74+
6175 for ( const apiName of [
6276 "fetch" ,
6377 "XMLHttpRequest" ,
@@ -141,6 +155,12 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
141155 } )
142156 } )
143157 } ) ;
158+
159+ definePropertyInterceptors . push ( ( o , p ) => {
160+ if ( o === prototype && p === propertyName ) {
161+ throw createWriteError ( { target, apiName } ) ;
162+ }
163+ } ) ;
144164 }
145165
146166 {
@@ -150,14 +170,27 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
150170 }
151171 }
152172
153- Object . defineProperty ( crypto , "subtle" , {
154- configurable : false ,
155- enumerable : true ,
156- get : ( ) => subtle ,
157- set : ( ) => {
158- throw createWriteError ( { target : "window.crypto.subtle" , apiName } ) ;
159- }
160- } ) ;
173+ {
174+ const o = crypto ;
175+ const p = "subtle" ;
176+ const createWriteError_local = ( ) =>
177+ createWriteError ( { target : "window.crypto.subtle" , apiName } ) ;
178+
179+ Object . defineProperty ( o , p , {
180+ configurable : false ,
181+ enumerable : true ,
182+ get : ( ) => subtle ,
183+ set : ( ) => {
184+ throw createWriteError_local ( ) ;
185+ }
186+ } ) ;
187+
188+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
189+ if ( o_ === o && p_ === p ) {
190+ throw createWriteError_local ( ) ;
191+ }
192+ } ) ;
193+ }
161194
162195 continue ;
163196 }
@@ -167,16 +200,30 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
167200 break service_worker;
168201 }
169202
170- const name_ = "serviceWorker" ;
203+ const o = window . navigator ;
204+ const p = "serviceWorker" ;
205+
206+ const original = o ?. [ p ] ;
171207
172- const original = navigator [ name_ ] ;
208+ if ( ! original ) {
209+ break service_worker;
210+ }
211+
212+ const createWriteError_local = ( ) =>
213+ createWriteError ( { target : `window.navigator.${ p } ` , apiName } ) ;
173214
174- Object . defineProperty ( navigator , name_ , {
215+ Object . defineProperty ( o , p , {
175216 configurable : false ,
176217 enumerable : true ,
177218 get : ( ) => original ,
178219 set : ( ) => {
179- throw createWriteError ( { target : `window.navigator.${ name_ } ` , apiName } ) ;
220+ throw createWriteError_local ( ) ;
221+ }
222+ } ) ;
223+
224+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
225+ if ( o_ === o && p_ === p ) {
226+ throw createWriteError_local ( ) ;
180227 }
181228 } ) ;
182229
@@ -191,18 +238,14 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
191238 const pName = "call" ;
192239
193240 {
194- const defineProperty_original = Object . defineProperty ;
195-
196- Object . defineProperty = ( o , p , attributes ) => {
241+ definePropertyInterceptors . push ( ( o , p ) => {
197242 if ( typeof o === "function" && o !== Function . prototype && p === pName ) {
198243 throw createWriteError ( {
199244 target : `<some function> 's .${ pName } () behavior` ,
200245 apiName
201246 } ) ;
202247 }
203-
204- return defineProperty_original ( o , p , attributes ) ;
205- } ;
248+ } ) ;
206249 }
207250
208251 Object . defineProperties = ( o , properties ) => {
@@ -215,15 +258,27 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
215258 {
216259 const original = Function . prototype [ pName ] ;
217260
218- Object . defineProperty ( Function . prototype , pName , {
261+ const o = Function . prototype ;
262+ const p = pName ;
263+
264+ const createWriteError_local = ( ) =>
265+ createWriteError ( {
266+ target : `window.Function.prototype.${ p } ` ,
267+ apiName
268+ } ) ;
269+
270+ Object . defineProperty ( o , p , {
219271 configurable : false ,
220272 enumerable : true ,
221273 get : ( ) => original ,
222274 set : ( ) => {
223- throw createWriteError ( {
224- target : `window.Function.prototype.${ pName } ` ,
225- apiName
226- } ) ;
275+ throw createWriteError_local ( ) ;
276+ }
277+ } ) ;
278+
279+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
280+ if ( o === o_ && p === p_ ) {
281+ throw createWriteError_local ( ) ;
227282 }
228283 } ) ;
229284 }
@@ -263,27 +318,37 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
263318 continue ;
264319 }
265320
266- const target = `window.${ apiName } .prototype.${ propertyName } ` ;
321+ const o = original . prototype ;
322+ const p = propertyName ;
267323
268- Object . defineProperty ( original . prototype , propertyName , {
324+ const createWriteError_local = ( ) =>
325+ createWriteError ( { target : `window.${ apiName } .prototype.${ p } ` , apiName } ) ;
326+
327+ Object . defineProperty ( o , p , {
269328 enumerable : pd . enumerable ,
270329 configurable : false ,
271330 ...( "value" in pd
272331 ? {
273332 get : ( ) => pd . value ,
274333 set : ( ) => {
275- throw createWriteError ( { target , apiName } ) ;
334+ throw createWriteError_local ( ) ;
276335 }
277336 }
278337 : {
279338 get : pd . get ,
280339 set :
281340 pd . set ??
282341 ( ( ) => {
283- throw createWriteError ( { target , apiName } ) ;
342+ throw createWriteError_local ( ) ;
284343 } )
285344 } )
286345 } ) ;
346+
347+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
348+ if ( o_ === o && p_ === p ) {
349+ throw createWriteError_local ( ) ;
350+ }
351+ } ) ;
287352 }
288353
289354 for ( const symbol of Object . getOwnPropertySymbols ( original . prototype ) ) {
@@ -295,27 +360,40 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
295360 continue ;
296361 }
297362
298- const target = `window.${ apiName } .prototype[Symbol.${ symbol . toString ( ) } ]` ;
363+ const o = original . prototype ;
364+ const p = symbol ;
365+
366+ const createWriteError_local = ( ) =>
367+ createWriteError ( {
368+ target : `window.${ apiName } .prototype[Symbol.${ p . toString ( ) } ]` ,
369+ apiName
370+ } ) ;
299371
300- Object . defineProperty ( original . prototype , symbol , {
372+ Object . defineProperty ( o , p , {
301373 enumerable : pd . enumerable ,
302374 configurable : false ,
303375 ...( "value" in pd
304376 ? {
305377 get : ( ) => pd . value ,
306378 set : ( ) => {
307- throw createWriteError ( { target , apiName } ) ;
379+ throw createWriteError_local ( ) ;
308380 }
309381 }
310382 : {
311383 get : pd . get ,
312384 set :
313385 pd . set ??
314386 ( ( ) => {
315- throw createWriteError ( { target , apiName } ) ;
387+ throw createWriteError_local ( ) ;
316388 } )
317389 } )
318390 } ) ;
391+
392+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
393+ if ( o_ === o && p_ === p ) {
394+ throw createWriteError_local ( ) ;
395+ }
396+ } ) ;
319397 }
320398
321399 for ( const propertyName of Object . getOwnPropertyNames ( original ) ) {
@@ -327,27 +405,37 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
327405 continue ;
328406 }
329407
330- const target = `window.${ apiName } .${ propertyName } ` ;
408+ const o = original ;
409+ const p = propertyName ;
331410
332- Object . defineProperty ( original , propertyName , {
411+ const createWriteError_local = ( ) =>
412+ createWriteError ( { target : `window.${ apiName } .${ propertyName } ` , apiName } ) ;
413+
414+ Object . defineProperty ( o , p , {
333415 enumerable : pd . enumerable ,
334416 configurable : false ,
335417 ...( "value" in pd
336418 ? {
337419 get : ( ) => pd . value ,
338420 set : ( ) => {
339- throw createWriteError ( { target , apiName } ) ;
421+ throw createWriteError_local ( ) ;
340422 }
341423 }
342424 : {
343425 get : pd . get ,
344426 set :
345427 pd . set ??
346428 ( ( ) => {
347- throw createWriteError ( { target , apiName } ) ;
429+ throw createWriteError_local ( ) ;
348430 } )
349431 } )
350432 } ) ;
433+
434+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
435+ if ( o_ === o && p_ === p ) {
436+ throw createWriteError_local ( ) ;
437+ }
438+ } ) ;
351439 }
352440
353441 if ( Symbol . iterator in original . prototype ) {
@@ -363,38 +451,65 @@ function freezeBrowserRuntime(params: { excludedApiNames: ApiName[] }) {
363451 continue ;
364452 }
365453
366- const target = `new ${ apiName } ()[Symbol.iterator]().__proto__.${ propertyName } ` ;
454+ const o = iterator_prototype ;
455+ const p = propertyName ;
367456
368- Object . defineProperty ( iterator_prototype , propertyName , {
457+ const createWriteError_local = ( ) =>
458+ createWriteError ( {
459+ target : `new ${ apiName } ()[Symbol.iterator]().__proto__.${ propertyName } ` ,
460+ apiName
461+ } ) ;
462+
463+ Object . defineProperty ( o , p , {
369464 enumerable : pd . enumerable ,
370465 configurable : false ,
371466 ...( "value" in pd
372467 ? {
373468 get : ( ) => pd . value ,
374469 set : ( ) => {
375- throw createWriteError ( { target , apiName } ) ;
470+ throw createWriteError_local ( ) ;
376471 }
377472 }
378473 : {
379474 get : pd . get ,
380475 set :
381476 pd . set ??
382477 ( ( ) => {
383- throw createWriteError ( { target , apiName } ) ;
478+ throw createWriteError_local ( ) ;
384479 } )
385480 } )
386481 } ) ;
482+
483+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
484+ if ( o_ === o && p_ === p ) {
485+ throw createWriteError_local ( ) ;
486+ }
487+ } ) ;
387488 }
388489 }
389490 }
390491
391- Object . defineProperty ( window , apiName , {
392- configurable : false ,
393- enumerable : true ,
394- get : ( ) => original ,
395- set : ( ) => {
396- throw createWriteError ( { target : `window.${ apiName } ` , apiName } ) ;
397- }
398- } ) ;
492+ {
493+ const o = window ;
494+ const p = apiName ;
495+
496+ const createWriteError_local = ( ) =>
497+ createWriteError ( { target : `window.${ apiName } ` , apiName } ) ;
498+
499+ Object . defineProperty ( o , p , {
500+ configurable : false ,
501+ enumerable : true ,
502+ get : ( ) => original ,
503+ set : ( ) => {
504+ throw createWriteError_local ( ) ;
505+ }
506+ } ) ;
507+
508+ definePropertyInterceptors . push ( ( o_ , p_ ) => {
509+ if ( o_ === o && p_ === p ) {
510+ throw createWriteError_local ( ) ;
511+ }
512+ } ) ;
513+ }
399514 }
400515}
0 commit comments