aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLapshin Vitaliy <mr.lapshin.vitaly@gmail.com>2022-06-20 11:32:58 +0300
committerLapshin Vitaliy <mr.lapshin.vitaly@gmail.com>2022-06-20 11:32:58 +0300
commit5f5fd0bc48d9ca28cd7d55af1c9b57a940c6fd9c (patch)
tree0f3692e54949964f9ad61f48e6f83f163382e106
parentaaa9938353a02ca38cfe4a309b857c1ff8f738ca (diff)
downloadseaweedfs-5f5fd0bc48d9ca28cd7d55af1c9b57a940c6fd9c.tar.xz
seaweedfs-5f5fd0bc48d9ca28cd7d55af1c9b57a940c6fd9c.zip
validate tags on copy object and add regex for validating tags
-rw-r--r--weed/s3api/s3api_object_copy_handlers.go26
-rw-r--r--weed/s3api/s3api_object_copy_handlers_test.go2
-rw-r--r--weed/s3api/s3api_object_tagging_handlers.go18
-rw-r--r--weed/s3api/tags.go40
4 files changed, 60 insertions, 26 deletions
diff --git a/weed/s3api/s3api_object_copy_handlers.go b/weed/s3api/s3api_object_copy_handlers.go
index 9157748f6..8e62deb94 100644
--- a/weed/s3api/s3api_object_copy_handlers.go
+++ b/weed/s3api/s3api_object_copy_handlers.go
@@ -45,7 +45,11 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
return
}
- entry.Extended = processMetadataBytes(r.Header, entry.Extended, replaceMeta, replaceTagging)
+ entry.Extended, err = processMetadataBytes(r.Header, entry.Extended, replaceMeta, replaceTagging)
+ if err != nil {
+ glog.Errorf("CopyObjectHandler ValidateTags error %s: %v", r.URL, err)
+ s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
+ }
err = s3a.touch(dir, name, entry)
if err != nil {
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
@@ -252,7 +256,7 @@ func processMetadata(reqHeader, existing http.Header, replaceMeta, replaceTaggin
return
}
-func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, replaceMeta, replaceTagging bool) (metadata map[string][]byte) {
+func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, replaceMeta, replaceTagging bool) (metadata map[string][]byte, err error) {
metadata = make(map[string][]byte)
if sc := existing[s3_constants.AmzStorageClass]; len(sc) > 0 {
@@ -277,16 +281,18 @@ func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, rep
}
}
}
-
if replaceTagging {
if tags := reqHeader.Get(s3_constants.AmzObjectTagging); tags != "" {
- for _, v := range strings.Split(tags, "&") {
- tag := strings.Split(v, "=")
- if len(tag) == 2 {
- metadata[s3_constants.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
- } else if len(tag) == 1 {
- metadata[s3_constants.AmzObjectTagging+"-"+tag[0]] = nil
- }
+ parsedTags, err := parseTagsHeader(tags)
+ if err != nil {
+ return nil, err
+ }
+ err = validateTags(parsedTags)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range parsedTags {
+ metadata[s3_constants.AmzObjectTagging+"-"+k] = []byte(v)
}
}
} else {
diff --git a/weed/s3api/s3api_object_copy_handlers_test.go b/weed/s3api/s3api_object_copy_handlers_test.go
index 610b29a6b..3cb2b0562 100644
--- a/weed/s3api/s3api_object_copy_handlers_test.go
+++ b/weed/s3api/s3api_object_copy_handlers_test.go
@@ -367,7 +367,7 @@ func TestProcessMetadataBytes(t *testing.T) {
reqHeader := transferHToHeader(tc.request)
existing := transferHToBytesArr(tc.existing)
replaceMeta, replaceTagging := replaceDirective(reqHeader)
- extends := processMetadataBytes(reqHeader, existing, replaceMeta, replaceTagging)
+ extends, _ := processMetadataBytes(reqHeader, existing, replaceMeta, replaceTagging)
result := transferBytesArrToH(extends)
fmtTagging(result, tc.want)
diff --git a/weed/s3api/s3api_object_tagging_handlers.go b/weed/s3api/s3api_object_tagging_handlers.go
index 9fde0309c..35da1cc20 100644
--- a/weed/s3api/s3api_object_tagging_handlers.go
+++ b/weed/s3api/s3api_object_tagging_handlers.go
@@ -62,22 +62,10 @@ func (s3a *S3ApiServer) PutObjectTaggingHandler(w http.ResponseWriter, r *http.R
return
}
tags := tagging.ToTags()
- if len(tags) > 10 {
- glog.Errorf("PutObjectTaggingHandler tags %s: %d tags more than 10", r.URL, len(tags))
+ err = validateTags(tags)
+ if err != nil {
+ glog.Errorf("PutObjectTaggingHandler ValidateTags error %s: %v", r.URL, err)
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
- return
- }
- for k, v := range tags {
- if len(k) > 128 {
- glog.Errorf("PutObjectTaggingHandler tags %s: tag key %s longer than 128", r.URL, k)
- s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
- return
- }
- if len(v) > 256 {
- glog.Errorf("PutObjectTaggingHandler tags %s: tag value %s longer than 256", r.URL, v)
- s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
- return
- }
}
if err = s3a.setTags(dir, name, tagging.ToTags()); err != nil {
diff --git a/weed/s3api/tags.go b/weed/s3api/tags.go
index 979e5a80c..06c9e4b80 100644
--- a/weed/s3api/tags.go
+++ b/weed/s3api/tags.go
@@ -2,6 +2,9 @@ package s3api
import (
"encoding/xml"
+ "fmt"
+ "regexp"
+ "strings"
)
type Tag struct {
@@ -37,3 +40,40 @@ func FromTags(tags map[string]string) (t *Tagging) {
}
return
}
+
+func parseTagsHeader(tags string) (map[string]string, error) {
+ var parsedTags map[string]string
+ for _, v := range strings.Split(tags, "&") {
+ tag := strings.Split(v, "=")
+ if len(tag) == 2 {
+ parsedTags[tag[0]] = tag[1]
+ } else if len(tag) == 1 {
+ parsedTags[tag[0]] = ""
+ }
+ }
+ return nil, nil
+}
+
+func validateTags(tags map[string]string) error {
+ if len(tags) > 10 {
+ return fmt.Errorf("validate tags: %d tags more than 10", len(tags))
+ }
+ for k, v := range tags {
+ if len(k) > 128 {
+ return fmt.Errorf("validate tags: tag key %s longer than 128", k)
+ }
+ validateKey, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, k)
+ if !validateKey && err != nil {
+ return fmt.Errorf("validate tags key %s error %w ", k, err)
+ }
+ if len(v) > 256 {
+ return fmt.Errorf("validate tags: tag value %s longer than 256", v)
+ }
+ validateValue, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, v)
+ if !validateValue && err != nil {
+ return fmt.Errorf("validate tags value %s error %w ", v, err)
+ }
+ }
+
+ return nil
+}