diff options
Diffstat (limited to 'workhorse/internal/upload')
-rw-r--r-- | workhorse/internal/upload/exif/exif.go | 5 | ||||
-rw-r--r-- | workhorse/internal/upload/rewrite.go | 15 | ||||
-rw-r--r-- | workhorse/internal/upload/uploads_test.go | 22 |
3 files changed, 33 insertions, 9 deletions
diff --git a/workhorse/internal/upload/exif/exif.go b/workhorse/internal/upload/exif/exif.go index 2f8218c3bc3..db3c45431c0 100644 --- a/workhorse/internal/upload/exif/exif.go +++ b/workhorse/internal/upload/exif/exif.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "os" "os/exec" "regexp" @@ -109,6 +110,10 @@ func (c *cleaner) startProcessing(stdin io.Reader) error { } func FileTypeFromSuffix(filename string) FileType { + if os.Getenv("SKIP_EXIFTOOL") == "1" { + return TypeUnknown + } + jpegMatch := regexp.MustCompile(`(?i)^[^\n]*\.(jpg|jpeg)$`) if jpegMatch.MatchString(filename) { return TypeJPEG diff --git a/workhorse/internal/upload/rewrite.go b/workhorse/internal/upload/rewrite.go index ba6bd0e501a..85063d65c1b 100644 --- a/workhorse/internal/upload/rewrite.go +++ b/workhorse/internal/upload/rewrite.go @@ -9,6 +9,7 @@ import ( "mime/multipart" "net/http" "os" + "path/filepath" "strings" "github.com/prometheus/client_golang/prometheus" @@ -117,6 +118,10 @@ func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipa filename := p.FileName() + if opts.FeatureFlagExtractBase { + filename = filepath.Base(filename) + } + if strings.Contains(filename, "/") || filename == "." || filename == ".." { return fmt.Errorf("illegal filename: %q", filename) } @@ -187,7 +192,10 @@ func handleExifUpload(ctx context.Context, r io.Reader, filename string, imageTy return nil, err } - tmpfile.Seek(0, io.SeekStart) + if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { + return nil, err + } + isValidType := false switch imageType { case exif.TypeJPEG: @@ -196,7 +204,10 @@ func handleExifUpload(ctx context.Context, r io.Reader, filename string, imageTy isValidType = isTIFF(tmpfile) } - tmpfile.Seek(0, io.SeekStart) + if _, err := tmpfile.Seek(0, io.SeekStart); err != nil { + return nil, err + } + if !isValidType { log.WithContextFields(ctx, log.Fields{ "filename": filename, diff --git a/workhorse/internal/upload/uploads_test.go b/workhorse/internal/upload/uploads_test.go index 0885f31d5a4..d77d73b5f48 100644 --- a/workhorse/internal/upload/uploads_test.go +++ b/workhorse/internal/upload/uploads_test.go @@ -325,14 +325,20 @@ func TestInvalidFileNames(t *testing.T) { defer os.RemoveAll(tempPath) for _, testCase := range []struct { - filename string - code int + filename string + code int + FeatureFlagExtractBase bool + expectedPrefix string }{ - {"foobar", 200}, // sanity check for test setup below - {"foo/bar", 500}, - {"/../../foobar", 500}, - {".", 500}, - {"..", 500}, + {"foobar", 200, false, "foobar"}, // sanity check for test setup below + {"foo/bar", 500, false, ""}, + {"foo/bar", 200, true, "bar"}, + {"foo/bar/baz", 200, true, "baz"}, + {"/../../foobar", 500, false, ""}, + {"/../../foobar", 200, true, "foobar"}, + {".", 500, false, ""}, + {"..", 500, false, ""}, + {"./", 500, false, ""}, } { buffer := &bytes.Buffer{} @@ -350,10 +356,12 @@ func TestInvalidFileNames(t *testing.T) { apiResponse := &api.Response{TempPath: tempPath} preparer := &DefaultPreparer{} opts, _, err := preparer.Prepare(apiResponse) + opts.FeatureFlagExtractBase = testCase.FeatureFlagExtractBase require.NoError(t, err) HandleFileUploads(response, httpRequest, nilHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts) require.Equal(t, testCase.code, response.Code) + require.Equal(t, testCase.expectedPrefix, opts.TempFilePrefix) } } |