11if ( "MediaSource" in window ) {
2+ let mediaBlocker ;
23 let notify = allowed => {
34 let request = {
45 id : "noscript-media" ,
@@ -22,12 +23,40 @@ if ("MediaSource" in window) {
2223 error ( e ) ;
2324 }
2425 } ;
26+ if ( "SecurityPolicyViolationEvent" in window ) {
27+ // "Modern" browsers
28+ let createPlaceholders = ( ) => {
29+ let request = notify ( false ) ;
30+ for ( let me of document . querySelectorAll ( "video,audio" ) ) {
31+ if ( ! ( me . src || me . currentSrc ) || me . src . startsWith ( "blob" ) ) {
32+ createPlaceholder ( me , request ) ;
33+ }
34+ }
35+ }
36+ let processedURIs = new Set ( ) ;
37+ addEventListener ( "securitypolicyviolation" , e => {
38+ let { blockedURI, violatedDirective} = e ;
39+ if ( ! ( e . isTrusted && violatedDirective . startsWith ( "media-src" ) ) ) return ;
40+ if ( mediaBlocker === undefined && / ^ d a t a \b / . test ( blockedURI ) ) { // Firefox 81 reports just "data"
41+ debug ( "mediaBlocker set via CSP listener." )
42+ mediaBlocker = true ;
43+ e . stopImmediatePropagation ( ) ;
44+ return ;
45+ }
46+ if ( blockedURI . startsWith ( "blob" ) &&
47+ ! processedURIs . has ( blockedURI ) ) {
48+ processedURIs . add ( blockedURI ) ;
49+ setTimeout ( createPlaceholders , 0 ) ;
50+ }
51+ } , true ) ;
52+ }
2553
2654 if ( typeof exportFunction === "function" ) {
27- // Mozilla
28- let mediablocker = true ;
55+ // Fallback: Mozilla does not seem to trigger CSP media-src http: for blob: URIs assigned in MSE
56+ window . wrappedJSObject . document . createElement ( "video" ) . src = "data:" ; // triggers early mediaBlocker initialization via CSP
2957 ns . on ( "capabilities" , e => {
3058 mediaBlocker = ! ns . allows ( "media" ) ;
59+ if ( mediaBlocker ) debug ( "mediaBlocker set via fetched policy." )
3160 } ) ;
3261
3362 let unpatched = new Map ( ) ;
@@ -55,37 +84,23 @@ if ("MediaSource" in window) {
5584 if ( mediaBlocker ) {
5685 let exposedMime = `${ mime } (MSE)` ;
5786 setTimeout ( ( ) => {
58- let me = Array . from ( document . querySelectorAll ( "video,audio" ) )
59- . find ( e => e . srcObject === ms || urls && urls . has ( e . src ) ) ;
60- if ( me ) createPlaceholder ( me , request ) ;
87+ try {
88+ let allMedia = [ ...document . querySelectorAll ( "video,audio" ) ] ;
89+ let me = allMedia . find ( e => e . srcObject === ms ||
90+ urls && ( urls . has ( e . currentSrc ) || urls . has ( e . src ) ) ) ||
91+ // throwing may cause src not to be assigned at all:
92+ allMedia . find ( e => ! ( e . src || e . currentSrc || e . srcObject ) ) ;
93+ if ( me ) createPlaceholder ( me , request ) ;
94+ } catch ( e ) {
95+ error ( e ) ;
96+ }
6197 } , 0 ) ;
62- throw new Error ( `${ exposedMime } blocked by NoScript` ) ;
98+ let msg = `${ exposedMime } blocked by NoScript` ;
99+ log ( msg ) ;
100+ throw new Error ( msg ) ;
63101 }
64102
65103 return unpatched . get ( window . MediaSource . prototype ) . addSourceBuffer . call ( ms , mime , ...args ) ;
66104 } ) ;
67-
68- } else if ( "SecurityPolicyViolationEvent" in window ) {
69- // Chromium
70- let createPlaceholders = ( ) => {
71- let request = notify ( false ) ;
72- for ( let me of document . querySelectorAll ( "video,audio" ) ) {
73- if ( ! ( me . src || me . currentSrc ) || me . src . startsWith ( "blob" ) ) {
74- createPlaceholder ( me , request ) ;
75- }
76- }
77- }
78- let processedURIs = new Set ( ) ;
79- let whenReady = false ;
80- addEventListener ( "securitypolicyviolation" , e => {
81- if ( ! e . isTrusted || ns . allows ( "media" ) ) return ;
82- let { blockedURI, violatedDirective} = e ;
83- if ( blockedURI . startsWith ( "blob" ) &&
84- violatedDirective . startsWith ( "media-src" ) &&
85- ! processedURIs . has ( blockedURI ) ) {
86- processedURIs . add ( blockedURI ) ;
87- setTimeout ( createPlaceholders , 0 ) ;
88- }
89- } , true ) ;
90105 }
91106}
0 commit comments