@@ -925,6 +925,48 @@ describe('links', () => {
925
925
expect ( console . warn ) . toHaveBeenCalled ( ) ;
926
926
} ) ;
927
927
928
+ it ( 'should sanitize markdown links containing JS expressions' , ( ) => {
929
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
930
+
931
+ render ( compiler ( '' ) ) ;
932
+
933
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
934
+
935
+ <img data-reactroot
936
+ alt="foo"
937
+ >
938
+
939
+ ` ) ;
940
+
941
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
942
+ } ) ;
943
+
944
+ it ( 'should sanitize markdown links containing Data expressions' , ( ) => {
945
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
946
+ render ( compiler ( '[foo](data:doSomethingBad)' ) ) ;
947
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
948
+
949
+ <a data-reactroot>
950
+ foo
951
+ </a>
952
+
953
+ ` ) ;
954
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
955
+ } ) ;
956
+
957
+ it ( 'should sanitize markdown links containing VBScript expressions' , ( ) => {
958
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
959
+ render ( compiler ( '[foo](vbScript:doSomethingBad)' ) ) ;
960
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
961
+
962
+ <a data-reactroot>
963
+ foo
964
+ </a>
965
+
966
+ ` ) ;
967
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
968
+ } ) ;
969
+
928
970
it ( 'should sanitize markdown links containing encoded JS expressions' , ( ) => {
929
971
jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
930
972
@@ -957,6 +999,60 @@ describe('links', () => {
957
999
expect ( console . warn ) . toHaveBeenCalled ( ) ;
958
1000
} ) ;
959
1001
1002
+ it ( 'should sanitize markdown links containing padded encoded vscript expressions' , ( ) => {
1003
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1004
+
1005
+ render ( compiler ( '[foo]( VBScript%3AdoSomethingBad)' ) ) ;
1006
+
1007
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1008
+
1009
+ <a data-reactroot>
1010
+ foo
1011
+ </a>
1012
+
1013
+ ` ) ;
1014
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1015
+ } ) ;
1016
+
1017
+ it ( 'should sanitize markdown images containing padded encoded vscript expressions' , ( ) => {
1018
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1019
+ render ( compiler ( '' ) ) ;
1020
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1021
+
1022
+ <img data-reactroot
1023
+ alt="foo"
1024
+ >
1025
+
1026
+ ` ) ;
1027
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1028
+ } ) ;
1029
+
1030
+ it ( 'should sanitize markdown links containing padded encoded data expressions' , ( ) => {
1031
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1032
+ render ( compiler ( '[foo](`<data:doSomethingBad)' ) ) ;
1033
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1034
+
1035
+ <a data-reactroot>
1036
+ foo
1037
+ </a>
1038
+
1039
+ ` ) ;
1040
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1041
+ } ) ;
1042
+
1043
+ it ( 'should sanitize markdown images containing padded encoded data expressions' , ( ) => {
1044
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1045
+ render ( compiler ( '' ) ) ;
1046
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1047
+
1048
+ <img data-reactroot
1049
+ alt="foo"
1050
+ >
1051
+
1052
+ ` ) ;
1053
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1054
+ } ) ;
1055
+
960
1056
it ( 'should sanitize markdown links containing invalid characters' , ( ) => {
961
1057
jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
962
1058
@@ -973,20 +1069,65 @@ describe('links', () => {
973
1069
} ) ;
974
1070
975
1071
it ( 'should sanitize html links containing JS expressions' , ( ) => {
976
- jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1072
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1073
+
1074
+ render ( compiler ( '<a href="javascript:doSomethingBad">foo</a>' ) ) ;
1075
+
1076
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1077
+
1078
+ <a data-reactroot>
1079
+ foo
1080
+ </a>
1081
+
1082
+ ` ) ;
977
1083
978
- render ( compiler ( '<a href="javascript:doSomethingBad">foo</a>' ) ) ;
1084
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1085
+ } ) ;
979
1086
980
- expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1087
+ it ( 'should sanitize html links containing encoded, prefixed data expressions' , ( ) => {
1088
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1089
+ render ( compiler ( '<a href="<`data:doSomethingBad">foo</a>' ) ) ;
1090
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
981
1091
982
1092
<a data-reactroot>
983
1093
foo
984
1094
</a>
985
1095
986
1096
` ) ;
1097
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1098
+ } ) ;
1099
+
1100
+ it ( 'should sanitize html images containing encoded, prefixed JS expressions' , ( ) => {
1101
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1102
+
1103
+ // TODO: something is off on parsing here, because this prints:
1104
+ // console.error("Warning: Unknown prop `javascript:alert` on <img> tag"...)
1105
+ // Which it shouldn't
1106
+ render ( compiler ( '<img src="`<javascript:alert>`(\'alertstr\')"' ) ) ;
1107
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
987
1108
988
- expect ( console . warn ) . toHaveBeenCalled ( ) ;
989
- } ) ;
1109
+ <span data-reactroot>
1110
+ <img src="true">
1111
+ \`('alertstr')"
1112
+ </span>
1113
+
1114
+ ` ) ;
1115
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1116
+ } ) ;
1117
+
1118
+ it ( 'should sanitize html images containing weird parsing src=s' , ( ) => {
1119
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1120
+ render ( compiler ( '<img src="`<src="javascript:alert(`xss`)">`' ) ) ;
1121
+ expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1122
+
1123
+ <span data-reactroot>
1124
+ <img src="\`<src=">
1125
+ \`
1126
+ </span>
1127
+
1128
+ ` ) ;
1129
+ expect ( console . warn ) . toHaveBeenCalled ( ) ;
1130
+ } ) ;
990
1131
991
1132
it ( 'should handle a link with a URL in the text' , ( ) => {
992
1133
render (
@@ -1582,14 +1723,14 @@ describe('GFM tables', () => {
1582
1723
1583
1724
it ( '#241 should not ignore the first cell when its contents is empty' , ( ) => {
1584
1725
render (
1585
- compiler (
1586
- [
1587
- '| Foo | Bar | Baz |' ,
1588
- '| --- | --- | --- |' ,
1589
- '| | 2 | 3 |' ,
1590
- '| | 5 | 6 |' ,
1591
- ] . join ( '\n' )
1592
- )
1726
+ compiler (
1727
+ [
1728
+ '| Foo | Bar | Baz |' ,
1729
+ '| --- | --- | --- |' ,
1730
+ '| | 2 | 3 |' ,
1731
+ '| | 5 | 6 |' ,
1732
+ ] . join ( '\n' )
1733
+ )
1593
1734
) ;
1594
1735
1595
1736
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
@@ -1780,7 +1921,6 @@ describe('GFM tables', () => {
1780
1921
1781
1922
` ) ;
1782
1923
} ) ;
1783
-
1784
1924
} ) ;
1785
1925
1786
1926
describe ( 'arbitrary HTML' , ( ) => {
@@ -1976,10 +2116,12 @@ describe('arbitrary HTML', () => {
1976
2116
} ) ;
1977
2117
1978
2118
it ( 'throws out multiline HTML comments' , ( ) => {
1979
- render ( compiler ( `Foo\n<!-- this is
2119
+ render (
2120
+ compiler ( `Foo\n<!-- this is
1980
2121
a
1981
2122
multiline
1982
- comment -->` ) ) ;
2123
+ comment -->` )
2124
+ ) ;
1983
2125
1984
2126
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
1985
2127
@@ -2800,7 +2942,7 @@ fun main() {
2800
2942
2801
2943
` ) ;
2802
2944
} ) ;
2803
- it ( 'should not fail with lots of \\n in the middle of the text' , ( ) => {
2945
+ it ( 'should not fail with lots of \\n in the middle of the text' , ( ) => {
2804
2946
render (
2805
2947
compiler (
2806
2948
'Text\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ntext' ,
@@ -2825,12 +2967,9 @@ fun main() {
2825
2967
2826
2968
it ( 'should not render html if disableParsingRawHTML is true' , ( ) => {
2827
2969
render (
2828
- compiler (
2829
- 'Text with <span>html</span> inside' ,
2830
- {
2831
- disableParsingRawHTML : true
2832
- }
2833
- )
2970
+ compiler ( 'Text with <span>html</span> inside' , {
2971
+ disableParsingRawHTML : true ,
2972
+ } )
2834
2973
) ;
2835
2974
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
2836
2975
@@ -2843,12 +2982,9 @@ fun main() {
2843
2982
2844
2983
it ( 'should render html if disableParsingRawHTML is false' , ( ) => {
2845
2984
render (
2846
- compiler (
2847
- 'Text with <span>html</span> inside' ,
2848
- {
2849
- disableParsingRawHTML : false
2850
- }
2851
- )
2985
+ compiler ( 'Text with <span>html</span> inside' , {
2986
+ disableParsingRawHTML : false ,
2987
+ } )
2852
2988
) ;
2853
2989
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
2854
2990
@@ -2976,7 +3112,15 @@ describe('footnotes', () => {
2976
3112
} ) ;
2977
3113
2978
3114
it ( 'should handle complex references' , ( ) => {
2979
- render ( compiler ( [ 'foo[^referencé heré 123] bar' , '' , '[^referencé heré 123]: Baz baz' ] . join ( '\n' ) ) ) ;
3115
+ render (
3116
+ compiler (
3117
+ [
3118
+ 'foo[^referencé heré 123] bar' ,
3119
+ '' ,
3120
+ '[^referencé heré 123]: Baz baz' ,
3121
+ ] . join ( '\n' )
3122
+ )
3123
+ ) ;
2980
3124
2981
3125
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
2982
3126
@@ -3002,7 +3146,13 @@ describe('footnotes', () => {
3002
3146
} ) ;
3003
3147
3004
3148
it ( 'should handle conversion of multiple references into links' , ( ) => {
3005
- render ( compiler ( [ 'foo[^abc] bar. baz[^def]' , '' , '[^abc]: Baz baz' , '[^def]: Def' ] . join ( '\n' ) ) ) ;
3149
+ render (
3150
+ compiler (
3151
+ [ 'foo[^abc] bar. baz[^def]' , '' , '[^abc]: Baz baz' , '[^def]: Def' ] . join (
3152
+ '\n'
3153
+ )
3154
+ )
3155
+ ) ;
3006
3156
3007
3157
expect ( root . innerHTML ) . toMatchInlineSnapshot ( `
3008
3158
@@ -3410,7 +3560,7 @@ describe('overrides', () => {
3410
3560
render (
3411
3561
compiler ( 'Hello.\n\n' , {
3412
3562
overrides : { p : { component : FakeParagraph } } ,
3413
- options : { disableParsingRawHTML : true }
3563
+ options : { disableParsingRawHTML : true } ,
3414
3564
} )
3415
3565
) ;
3416
3566
@@ -3424,7 +3574,7 @@ describe('overrides', () => {
3424
3574
render (
3425
3575
compiler ( 'Hello.\n\n<FakeSpan>I am a fake span</FakeSpan>' , {
3426
3576
overrides : { FakeSpan } ,
3427
- options : { disableParsingRawHTML : true }
3577
+ options : { disableParsingRawHTML : true } ,
3428
3578
} )
3429
3579
) ;
3430
3580
0 commit comments