@@ -148,15 +148,39 @@ impl SanitizeUrl {
148
148
}
149
149
}
150
150
151
+ /// Groups media-related URL info
152
+ struct MediaUrl {
153
+ is_media : bool ,
154
+ add_sanitize_query : bool ,
155
+ }
156
+
151
157
/// Determine whether the given URL has a media file externsion.
152
- fn is_media_url ( url : & str ) -> bool {
158
+ /// Also check if `sanitize=true` must be added to the query string,
159
+ /// which is required to load SVGs properly from GitHub.
160
+ fn is_media_url ( url : & str ) -> MediaUrl {
153
161
Path :: new ( url)
154
162
. extension ( )
155
163
. and_then ( std:: ffi:: OsStr :: to_str)
156
- . map_or ( false , |e| match e {
157
- "png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true ,
158
- _ => false ,
159
- } )
164
+ . map_or (
165
+ MediaUrl {
166
+ is_media : false ,
167
+ add_sanitize_query : false ,
168
+ } ,
169
+ |e| match e {
170
+ "svg" => MediaUrl {
171
+ is_media : true ,
172
+ add_sanitize_query : true ,
173
+ } ,
174
+ "png" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => MediaUrl {
175
+ is_media : true ,
176
+ add_sanitize_query : false ,
177
+ } ,
178
+ _ => MediaUrl {
179
+ is_media : false ,
180
+ add_sanitize_query : false ,
181
+ } ,
182
+ } ,
183
+ )
160
184
}
161
185
162
186
impl UrlRelativeEvaluate for SanitizeUrl {
@@ -169,7 +193,11 @@ impl UrlRelativeEvaluate for SanitizeUrl {
169
193
let mut new_url = base_url. clone ( ) ;
170
194
// Assumes GitHub’s URL scheme. GitHub renders text and markdown
171
195
// better in the "blob" view, but images need to be served raw.
172
- new_url += if is_media_url ( url) {
196
+ let MediaUrl {
197
+ is_media,
198
+ add_sanitize_query,
199
+ } = is_media_url ( url) ;
200
+ new_url += if is_media {
173
201
"raw/master"
174
202
} else {
175
203
"blob/master"
@@ -178,6 +206,12 @@ impl UrlRelativeEvaluate for SanitizeUrl {
178
206
new_url. push ( '/' ) ;
179
207
}
180
208
new_url += url;
209
+ if add_sanitize_query {
210
+ if let Ok ( mut parsed_url) = Url :: parse ( & new_url) {
211
+ parsed_url. query_pairs_mut ( ) . append_pair ( "sanitize" , "true" ) ;
212
+ new_url = parsed_url. into_string ( ) ;
213
+ }
214
+ }
181
215
Cow :: Owned ( new_url)
182
216
} )
183
217
}
@@ -356,6 +390,7 @@ mod tests {
356
390
let absolute = "[hi](/hi)" ;
357
391
let relative = "[there](there)" ;
358
392
let image = "" ;
393
+ let svg = "" ;
359
394
360
395
for host in & [ "github.com" , "gitlab.com" , "bitbucket.org" ] {
361
396
for ( & extra_slash, & dot_git) in [ true , false ] . iter ( ) . zip ( & [ true , false ] ) {
@@ -392,6 +427,15 @@ mod tests {
392
427
host
393
428
)
394
429
) ;
430
+
431
+ let result = markdown_to_html ( svg, Some ( & url) ) ;
432
+ assert_eq ! (
433
+ result,
434
+ format!(
435
+ "<p><img src=\" https://{}/rust-lang/test/raw/master/sanitize.svg?sanitize=true\" alt=\" alt\" ></p>\n " ,
436
+ host
437
+ )
438
+ ) ;
395
439
}
396
440
}
397
441
0 commit comments