From 90d23139f626bcaa3a7519698773faac86cb9afb Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 11 Oct 2022 17:54:22 +0100 Subject: [PATCH] s3: drop binary metadata with an ERROR message Before this change, rclone would attempt to upload metadata with binary contents which fail to be uploaded by net/http. This checks the keys and values for validity as http header values before uploading. See: https://forum.rclone.org/t/invalid-metadata-key-names-result-in-a-failure-to-transfer-xattr-results-in-failure-to-upload-net-http-invalid-header-field-value-for-x-amz-meta-samba-pai/33406/ --- backend/s3/s3.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 9aba03a3f..d869efb8d 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -57,6 +57,7 @@ import ( "github.com/rclone/rclone/lib/readers" "github.com/rclone/rclone/lib/rest" "github.com/rclone/rclone/lib/version" + "golang.org/x/net/http/httpguts" "golang.org/x/sync/errgroup" ) @@ -5241,6 +5242,20 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } } + // Check metadata keys and values are valid + for key, value := range req.Metadata { + if !httpguts.ValidHeaderFieldName(key) { + fs.Errorf(o, "Dropping invalid metadata key %q", key) + delete(req.Metadata, key) + } else if value == nil { + fs.Errorf(o, "Dropping nil metadata value for key %q", key) + delete(req.Metadata, key) + } else if !httpguts.ValidHeaderFieldValue(*value) { + fs.Errorf(o, "Dropping invalid metadata value %q for key %q", *value, key) + delete(req.Metadata, key) + } + } + var wantETag string // Multipart upload Etag to check var gotEtag string // Etag we got from the upload var lastModified time.Time // Time we got from the upload