aboutsummaryrefslogtreecommitdiffhomepage
path: root/media
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2021-12-21 10:35:33 +0100
committerBjørn Erik Pedersen <[email protected]>2021-12-22 11:35:53 +0100
commit6779117f72e2d92f708cff2bfc004d2cfd7d068b (patch)
tree1c6f9243575e95756bf68942a8c40a835e76bbe0 /media
parentce04011096456c77479fa98a6ceee242aeac7919 (diff)
downloadhugo-6779117f72e2d92f708cff2bfc004d2cfd7d068b.tar.gz
hugo-6779117f72e2d92f708cff2bfc004d2cfd7d068b.zip
media: Also consider extension in FromContent
As used in `resources.GetRemote`. This will now reject image files with text and text files with images.
Diffstat (limited to 'media')
-rw-r--r--media/mediaType.go43
-rw-r--r--media/mediaType_test.go29
-rw-r--r--media/testdata/fake.jsbin0 -> 13327 bytes
-rw-r--r--media/testdata/fake.png3
-rw-r--r--media/testdata/resource.jpebin0 -> 116955 bytes
5 files changed, 59 insertions, 16 deletions
diff --git a/media/mediaType.go b/media/mediaType.go
index 819de9d80..47a74ec56 100644
--- a/media/mediaType.go
+++ b/media/mediaType.go
@@ -28,6 +28,8 @@ import (
"github.com/mitchellh/mapstructure"
)
+var zero Type
+
const (
defaultDelimiter = "."
)
@@ -64,16 +66,14 @@ type SuffixInfo struct {
// FromContent resolve the Type primarily using http.DetectContentType.
// If http.DetectContentType resolves to application/octet-stream, a zero Type is returned.
// If http.DetectContentType resolves to text/plain or application/xml, we try to get more specific using types and ext.
-func FromContent(types Types, ext string, content []byte) Type {
- ext = strings.TrimPrefix(ext, ".")
+func FromContent(types Types, extensionHints []string, content []byte) Type {
t := strings.Split(http.DetectContentType(content), ";")[0]
- var m Type
if t == "application/octet-stream" {
- return m
+ return zero
}
var found bool
- m, found = types.GetByType(t)
+ m, found := types.GetByType(t)
if !found {
if t == "text/xml" {
// This is how it's configured in Hugo by default.
@@ -81,19 +81,36 @@ func FromContent(types Types, ext string, content []byte) Type {
}
}
- if !found || ext == "" {
- return m
+ if !found {
+ return zero
+ }
+
+ var mm Type
+
+ for _, extension := range extensionHints {
+ extension = strings.TrimPrefix(extension, ".")
+ mm, _, found = types.GetFirstBySuffix(extension)
+ if found {
+ break
+ }
}
- if m.Type() == "text/plain" || m.Type() == "application/xml" {
- // http.DetectContentType isn't brilliant when it comes to common text formats, so we need to do better.
- // For now we say that if it's detected to be a text format and the extension/content type in header reports
- // it to be a text format, then we use that.
- mm, _, found := types.GetFirstBySuffix(ext)
- if found && mm.IsText() {
+ if found {
+ if m == mm {
+ return m
+ }
+
+ if m.IsText() && mm.IsText() {
+ // http.DetectContentType isn't brilliant when it comes to common text formats, so we need to do better.
+ // For now we say that if it's detected to be a text format and the extension/content type in header reports
+ // it to be a text format, then we use that.
return mm
}
+
+ // E.g. an image with a *.js extension.
+ return zero
}
+
return m
}
diff --git a/media/mediaType_test.go b/media/mediaType_test.go
index cd4439fe7..2e32568f1 100644
--- a/media/mediaType_test.go
+++ b/media/mediaType_test.go
@@ -15,7 +15,6 @@ package media
import (
"encoding/json"
- "fmt"
"io/ioutil"
"path/filepath"
"sort"
@@ -194,15 +193,39 @@ func TestFromContent(t *testing.T) {
content, err := ioutil.ReadFile(filename)
c.Assert(err, qt.IsNil)
ext := strings.TrimPrefix(paths.Ext(filename), ".")
- fmt.Println("=>", ext)
+ var exts []string
+ if ext == "jpg" {
+ exts = append(exts, "foo", "bar", "jpg")
+ } else {
+ exts = []string{ext}
+ }
expected, _, found := mtypes.GetFirstBySuffix(ext)
c.Assert(found, qt.IsTrue)
- got := FromContent(mtypes, ext, content)
+ got := FromContent(mtypes, exts, content)
c.Assert(got, qt.Equals, expected)
})
}
}
+func TestFromContentFakes(t *testing.T) {
+ c := qt.New(t)
+
+ files, err := filepath.Glob("./testdata/fake.*")
+ c.Assert(err, qt.IsNil)
+ mtypes := DefaultTypes
+
+ for _, filename := range files {
+ name := filepath.Base(filename)
+ c.Run(name, func(c *qt.C) {
+ content, err := ioutil.ReadFile(filename)
+ c.Assert(err, qt.IsNil)
+ ext := strings.TrimPrefix(paths.Ext(filename), ".")
+ got := FromContent(mtypes, []string{ext}, content)
+ c.Assert(got, qt.Equals, zero)
+ })
+ }
+}
+
func TestDecodeTypes(t *testing.T) {
c := qt.New(t)
diff --git a/media/testdata/fake.js b/media/testdata/fake.js
new file mode 100644
index 000000000..08ae570d2
--- /dev/null
+++ b/media/testdata/fake.js
Binary files differ
diff --git a/media/testdata/fake.png b/media/testdata/fake.png
new file mode 100644
index 000000000..75ba3b7fe
--- /dev/null
+++ b/media/testdata/fake.png
@@ -0,0 +1,3 @@
+function foo() {
+ return "foo";
+} \ No newline at end of file
diff --git a/media/testdata/resource.jpe b/media/testdata/resource.jpe
new file mode 100644
index 000000000..a9049e81b
--- /dev/null
+++ b/media/testdata/resource.jpe
Binary files differ