@@ -58,7 +58,7 @@ describe('auto-csp', () => {
5858 const csps = getCsps ( result ) ;
5959 expect ( csps ) . toHaveSize ( 1 ) ;
6060 expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
61- expect ( result ) . toContain ( `const scripts = [['./main.js', '' , false, false, null, null]];` ) ;
61+ expect ( result ) . toContain ( `const scripts = [['./main.js', "" , false, false, null, null]];` ) ;
6262 } ) ;
6363
6464 it ( 'should rewrite a single source script in place' , async ( ) => {
@@ -78,7 +78,7 @@ describe('auto-csp', () => {
7878 expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
7979 // Our loader script appears after the HTML text content.
8080 expect ( result ) . toMatch (
81- / S o m e t e x t < \/ d i v > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n .j s ' , ' ' , f a l s e , f a l s e , n u l l , n u l l \] \] ; / ,
81+ / S o m e t e x t < \/ d i v > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n .j s ' , " " , f a l s e , f a l s e , n u l l , n u l l \] \] ; / ,
8282 ) ;
8383 } ) ;
8484
@@ -103,7 +103,7 @@ describe('auto-csp', () => {
103103 expect ( csps [ 0 ] ) . toMatch ( CSP_TWO_HASHES_REGEX ) ;
104104 expect ( result ) . toContain (
105105 // eslint-disable-next-line max-len
106- `const scripts = [['./main1.js', '' , false, false, null, null],['./main2.js', '' , true, false, null, null],['./main3.js', ' module' , true, true, null, null]];` ,
106+ `const scripts = [['./main1.js', "" , false, false, null, null],['./main2.js', "" , true, false, null, null],['./main3.js', " module" , true, true, null, null]];` ,
107107 ) ;
108108 // Head loader script is in the head.
109109 expect ( result ) . toContain ( `</script></head>` ) ;
@@ -166,12 +166,12 @@ describe('auto-csp', () => {
166166 // Loader script for main.js and main2.js appear after 'foo' and before 'bar'.
167167 expect ( result ) . toMatch (
168168 // eslint-disable-next-line max-len
169- / c o n s o l e .l o g \( ' f o o ' \) ; < \/ s c r i p t > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n .j s ' , ' ' , f a l s e , f a l s e , n u l l , n u l l \] , \[ ' .\/ m a i n 2 .j s ' , ' ' , f a l s e , f a l s e , n u l l , n u l l \] \] ; [ \s \S ] * c o n s o l e .l o g \( ' b a r ' \) ; / ,
169+ / c o n s o l e .l o g \( ' f o o ' \) ; < \/ s c r i p t > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n .j s ' , " " , f a l s e , f a l s e , n u l l , n u l l \] , \[ ' .\/ m a i n 2 .j s ' , " " , f a l s e , f a l s e , n u l l , n u l l \] \] ; [ \s \S ] * c o n s o l e .l o g \( ' b a r ' \) ; / ,
170170 ) ;
171171 // Loader script for main3.js and main4.js appear after 'bar'.
172172 expect ( result ) . toMatch (
173173 // eslint-disable-next-line max-len
174- / c o n s o l e .l o g \( ' b a r ' \) ; < \/ s c r i p t > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n 3 .j s ' , ' ' , f a l s e , f a l s e , n u l l , n u l l \] , \[ ' .\/ m a i n 4 .j s ' , ' ' , f a l s e , f a l s e , n u l l , n u l l \] \] ; / ,
174+ / c o n s o l e .l o g \( ' b a r ' \) ; < \/ s c r i p t > \s * < s c r i p t > \( \( \) = > { \s * c o n s t s c r i p t s = \[ \[ ' .\/ m a i n 3 .j s ' , " " , f a l s e , f a l s e , n u l l , n u l l \] , \[ ' .\/ m a i n 4 .j s ' , " " , f a l s e , f a l s e , n u l l , n u l l \] \] ; / ,
175175 ) ;
176176 // Exactly 4 scripts should be left.
177177 expect ( Array . from ( result . matchAll ( / < s c r i p t > / gi) ) . length ) . toEqual ( 4 ) ;
@@ -238,7 +238,7 @@ describe('auto-csp', () => {
238238 expect ( csps ) . toHaveSize ( 1 ) ;
239239 expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
240240 expect ( result ) . toContain (
241- `const scripts = [['./main.js', ' module' , false, false, "sha384-xyz123", "anonymous"]];` ,
241+ `const scripts = [['./main.js', " module" , false, false, "sha384-xyz123", "anonymous"]];` ,
242242 ) ;
243243 } ) ;
244244
@@ -258,7 +258,7 @@ describe('auto-csp', () => {
258258 expect ( csps ) . toHaveSize ( 1 ) ;
259259 expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
260260 expect ( result ) . toContain (
261- `const scripts = [['./main.js', '' , false, false, "sha384-xyz123", null]];` ,
261+ `const scripts = [['./main.js', "" , false, false, "sha384-xyz123", null]];` ,
262262 ) ;
263263 } ) ;
264264
@@ -278,7 +278,45 @@ describe('auto-csp', () => {
278278 expect ( csps ) . toHaveSize ( 1 ) ;
279279 expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
280280 expect ( result ) . toContain (
281- `const scripts = [['./main.js', '' , false, false, null, "anonymous"]];` ,
281+ `const scripts = [['./main.js', "" , false, false, null, "anonymous"]];` ,
282282 ) ;
283283 } ) ;
284+
285+ it ( 'should encode a script type that carries MIME parameters' , async ( ) => {
286+ const result = await autoCsp ( `
287+ <html>
288+ <head>
289+ </head>
290+ <body>
291+ <script src="./main.js" type="text/javascript;']];var x=1;var junk=[['a','b"></script>
292+ </body>
293+ </html>
294+ ` ) ;
295+
296+ const csps = getCsps ( result ) ;
297+ expect ( csps ) . toHaveSize ( 1 ) ;
298+ expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
299+ // The type stays inside its string literal.
300+ expect ( result ) . toContain (
301+ `const scripts = [['./main.js', "text/javascript;']];var x=1;var junk=[['a','b", false, false, null, null]];` ,
302+ ) ;
303+ } ) ;
304+
305+ it ( 'should encode a script type that contains a closing script tag' , async ( ) => {
306+ const result = await autoCsp ( `
307+ <html>
308+ <head>
309+ </head>
310+ <body>
311+ <script src="./main.js" type="text/javascript;</script><script>x</script>"></script>
312+ </body>
313+ </html>
314+ ` ) ;
315+
316+ const csps = getCsps ( result ) ;
317+ expect ( csps ) . toHaveSize ( 1 ) ;
318+ expect ( csps [ 0 ] ) . toMatch ( CSP_SINGLE_HASH_REGEX ) ;
319+ // Only the loader element is emitted.
320+ expect ( Array . from ( result . matchAll ( / < s c r i p t / gi) ) . length ) . toEqual ( 1 ) ;
321+ } ) ;
284322} ) ;
0 commit comments