44package typesniffer
55
66import (
7+ "bytes"
78 "fmt"
89 "io"
910 "net/http"
@@ -25,8 +26,8 @@ const (
2526
2627var (
2728 svgComment = regexp .MustCompile (`(?s)<!--.*?-->` )
28- svgTagRegex = regexp .MustCompile (`(?si)\A\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>/] ` )
29- svgTagInXMLRegex = regexp .MustCompile (`(?si)\A<\?xml\b.*?\?>\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>/] ` )
29+ svgTagRegex = regexp .MustCompile (`(?si)\A\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg\b ` )
30+ svgTagInXMLRegex = regexp .MustCompile (`(?si)\A<\?xml\b.*?\?>\s*(?:(<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg\b ` )
3031)
3132
3233// SniffedType contains information about a blobs type.
@@ -80,6 +81,8 @@ func (ct SniffedType) GetMimeType() string {
8081 return strings .SplitN (ct .contentType , ";" , 2 )[0 ]
8182}
8283
84+ var svgCloseTag = []byte ("</svg>" )
85+
8386// DetectContentType extends http.DetectContentType with more content types. Defaults to text/unknown if input is empty.
8487func DetectContentType (data []byte ) SniffedType {
8588 if len (data ) == 0 {
@@ -94,16 +97,16 @@ func DetectContentType(data []byte) SniffedType {
9497
9598 // SVG is unsupported by http.DetectContentType, https://github.com/golang/go/issues/15888
9699
97- if strings .Contains (ct , "text/plain" ) || strings .Contains (ct , "text/html" ) {
98- dataNoComment := svgComment . ReplaceAll ( data , nil )
99- if svgTagRegex . Match ( dataNoComment ) {
100- ct = SvgMimeType
101- }
102- }
103- if strings . Contains ( ct , "text/xml" ) {
104- dataNoComment := svgComment . ReplaceAll ( data , nil )
105- if svgTagInXMLRegex . Match ( dataNoComment ) {
106- ct = SvgMimeType
100+ detectByHTML := strings .Contains (ct , "text/plain" ) || strings .Contains (ct , "text/html" )
101+ detectByXML := strings . Contains ( ct , "text/xml" )
102+ if detectByHTML || detectByXML {
103+ dataProcessed := svgComment . ReplaceAll ( data , nil )
104+ dataProcessed = bytes . TrimSpace ( dataProcessed )
105+ if bytes . HasSuffix ( dataProcessed , svgCloseTag ) {
106+ if detectByHTML && svgTagRegex . Match ( dataProcessed ) ||
107+ detectByXML && svgTagInXMLRegex . Match ( dataProcessed ) {
108+ ct = SvgMimeType
109+ }
107110 }
108111 }
109112
0 commit comments