@@ -103,15 +103,39 @@ impl SanitizeUrl {
103
103
}
104
104
}
105
105
106
+ /// Groups media-related URL info
107
+ struct MediaUrl {
108
+ is_media : bool ,
109
+ add_sanitize_query : bool ,
110
+ }
111
+
106
112
/// Determine whether the given URL has a media file externsion.
107
- fn is_media_url ( url : & str ) -> bool {
113
+ /// Also check if `sanitize=true` must be added to the query string,
114
+ /// which is required to load SVGs properly from GitHub.
115
+ fn is_media_url ( url : & str ) -> MediaUrl {
108
116
Path :: new ( url)
109
117
. extension ( )
110
118
. and_then ( std:: ffi:: OsStr :: to_str)
111
- . map_or ( false , |e| match e {
112
- "png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true ,
113
- _ => false ,
114
- } )
119
+ . map_or (
120
+ MediaUrl {
121
+ is_media : false ,
122
+ add_sanitize_query : false ,
123
+ } ,
124
+ |e| match e {
125
+ "svg" => MediaUrl {
126
+ is_media : true ,
127
+ add_sanitize_query : true ,
128
+ } ,
129
+ "png" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => MediaUrl {
130
+ is_media : true ,
131
+ add_sanitize_query : false ,
132
+ } ,
133
+ _ => MediaUrl {
134
+ is_media : false ,
135
+ add_sanitize_query : false ,
136
+ } ,
137
+ } ,
138
+ )
115
139
}
116
140
117
141
impl UrlRelativeEvaluate for SanitizeUrl {
@@ -124,7 +148,11 @@ impl UrlRelativeEvaluate for SanitizeUrl {
124
148
let mut new_url = base_url. clone ( ) ;
125
149
// Assumes GitHub’s URL scheme. GitHub renders text and markdown
126
150
// better in the "blob" view, but images need to be served raw.
127
- new_url += if is_media_url ( url) {
151
+ let MediaUrl {
152
+ is_media,
153
+ add_sanitize_query,
154
+ } = is_media_url ( url) ;
155
+ new_url += if is_media {
128
156
"raw/master"
129
157
} else {
130
158
"blob/master"
@@ -133,6 +161,12 @@ impl UrlRelativeEvaluate for SanitizeUrl {
133
161
new_url. push ( '/' ) ;
134
162
}
135
163
new_url += url;
164
+ if add_sanitize_query {
165
+ if let Ok ( mut parsed_url) = Url :: parse ( & new_url) {
166
+ parsed_url. query_pairs_mut ( ) . append_pair ( "sanitize" , "true" ) ;
167
+ new_url = parsed_url. into_string ( ) ;
168
+ }
169
+ }
136
170
Cow :: Owned ( new_url)
137
171
} )
138
172
}
@@ -310,6 +344,7 @@ mod tests {
310
344
let absolute = "[hi](/hi)" ;
311
345
let relative = "[there](there)" ;
312
346
let image = "" ;
347
+ let svg = "" ;
313
348
314
349
for host in & [ "github.com" , "gitlab.com" , "bitbucket.org" ] {
315
350
for ( & extra_slash, & dot_git) in [ true , false ] . iter ( ) . zip ( & [ true , false ] ) {
@@ -346,6 +381,15 @@ mod tests {
346
381
host
347
382
)
348
383
) ;
384
+
385
+ let result = markdown_to_html ( svg, Some ( & url) ) ;
386
+ assert_eq ! (
387
+ result,
388
+ format!(
389
+ "<p><img src=\" https://{}/rust-lang/test/raw/master/sanitize.svg?sanitize=true\" alt=\" alt\" ></p>\n " ,
390
+ host
391
+ )
392
+ ) ;
349
393
}
350
394
}
351
395
0 commit comments