diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2021-12-16 15:12:13 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2021-12-17 09:50:28 +0100 |
commit | 44954497bcb2d6d589b9340a43323663061c7b42 (patch) | |
tree | 0d0d06b11e462ccff1a908c2b1c4dfd039b82787 /resources/resource_factories/create/remote.go | |
parent | 22ef5da20d1685dfe6aff3bd9364c9b1f1d0d8f8 (diff) |
Always use content to resolve content type in resources.GetRemote
This is a security hardening measure; don't trust the URL extension or any `Content-Type`/`Content-Disposition` header on its own, always look at the file content using Go's `http.DetectContentType`.
This commit also adds ttf and otf media type definitions to Hugo.
Fixes #9302
Fixes #9301
Diffstat (limited to 'resources/resource_factories/create/remote.go')
-rw-r--r-- | resources/resource_factories/create/remote.go | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/resources/resource_factories/create/remote.go b/resources/resource_factories/create/remote.go index 53e77bc5e..f6d3f13dd 100644 --- a/resources/resource_factories/create/remote.go +++ b/resources/resource_factories/create/remote.go @@ -29,6 +29,7 @@ import ( "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/common/types" "github.com/gohugoio/hugo/helpers" + "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/resources" "github.com/gohugoio/hugo/resources/resource" "github.com/mitchellh/mapstructure" @@ -99,7 +100,7 @@ func (c *Client) FromRemote(uri string, optionsm map[string]interface{}) (resour body, err := ioutil.ReadAll(res.Body) if err != nil { - return nil, errors.Wrapf(err, "failed to read remote resource %s", uri) + return nil, errors.Wrapf(err, "failed to read remote resource %q", uri) } filename := path.Base(rURL.Path) @@ -109,33 +110,30 @@ func (c *Client) FromRemote(uri string, optionsm map[string]interface{}) (resour } } - var extension string + var extensionHint string + if arr, _ := mime.ExtensionsByType(res.Header.Get("Content-Type")); len(arr) == 1 { - extension = arr[0] + extensionHint = arr[0] } - // If extension was not determined by header, look for a file extention - if extension == "" { + // Look for a file extention + if extensionHint == "" { if ext := path.Ext(filename); ext != "" { - extension = ext + extensionHint = ext } } - // If extension was not determined by header or file extention, try using content itself - if extension == "" { - if ct := http.DetectContentType(body); ct != "application/octet-stream" { - if ct == "image/jpeg" { - extension = ".jpg" - } else if arr, _ := mime.ExtensionsByType(ct); arr != nil { - extension = arr[0] - } - } + // Now resolve the media type primarily using the content. + mediaType := media.FromContent(c.rs.MediaTypes, extensionHint, body) + if mediaType.IsZero() { + return nil, errors.Errorf("failed to resolve media type for remote resource %q", uri) } - resourceID = filename[:len(filename)-len(path.Ext(filename))] + "_" + resourceID + extension + resourceID = filename[:len(filename)-len(path.Ext(filename))] + "_" + resourceID + mediaType.FirstSuffix.FullSuffix return c.rs.New( resources.ResourceSourceDescriptor{ + MediaType: mediaType, LazyPublish: true, OpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) { return hugio.NewReadSeekerNoOpCloser(bytes.NewReader(body)), nil |