From 61927d228c3efc7e3678d54f2540b0ccb12e1b39 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Tue, 1 Oct 2019 21:09:29 +0100 Subject: [PATCH] listV2: Continuation and NextContinuation tokens are encoded with base64 (#8337) Minio V2 listing uses object names/prefixes as continuation tokens. This is problematic when object names contain some characters that are forbidden in XML documents. This PR will use base64 encoded form of continuation and next continuation tokens to address that corner case. --- cmd/api-resources.go | 11 ++++++++++- cmd/api-resources_test.go | 4 ++-- cmd/api-response.go | 5 +++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmd/api-resources.go b/cmd/api-resources.go index 13f79fb34..d3f1eaa92 100644 --- a/cmd/api-resources.go +++ b/cmd/api-resources.go @@ -17,6 +17,7 @@ package cmd import ( + "encoding/base64" "net/url" "strconv" ) @@ -86,11 +87,19 @@ func getListObjectsV2Args(values url.Values) (prefix, token, startAfter, delimit } prefix = values.Get("prefix") - token = values.Get("continuation-token") startAfter = values.Get("start-after") delimiter = values.Get("delimiter") fetchOwner = values.Get("fetch-owner") == "true" encodingType = values.Get("encoding-type") + + if token = values.Get("continuation-token"); token != "" { + decodedToken, err := base64.StdEncoding.DecodeString(token) + if err != nil { + errCode = ErrIncorrectContinuationToken + return + } + token = string(decodedToken) + } return } diff --git a/cmd/api-resources_test.go b/cmd/api-resources_test.go index 9b0c98799..81aee118f 100644 --- a/cmd/api-resources_test.go +++ b/cmd/api-resources_test.go @@ -34,7 +34,7 @@ func TestListObjectsV2Resources(t *testing.T) { { values: url.Values{ "prefix": []string{"photos/"}, - "continuation-token": []string{"token"}, + "continuation-token": []string{"dG9rZW4="}, "start-after": []string{"start-after"}, "delimiter": []string{SlashSeparator}, "fetch-owner": []string{"true"}, @@ -53,7 +53,7 @@ func TestListObjectsV2Resources(t *testing.T) { { values: url.Values{ "prefix": []string{"photos/"}, - "continuation-token": []string{"token"}, + "continuation-token": []string{"dG9rZW4="}, "start-after": []string{"start-after"}, "delimiter": []string{SlashSeparator}, "fetch-owner": []string{"true"}, diff --git a/cmd/api-response.go b/cmd/api-response.go index 088307b6c..24f86567f 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -18,6 +18,7 @@ package cmd import ( "context" + "encoding/base64" "encoding/xml" "net/http" "net/url" @@ -498,8 +499,8 @@ func generateListObjectsV2Response(bucket, prefix, token, nextToken, startAfter, data.Delimiter = s3EncodeName(delimiter, encodingType) data.Prefix = s3EncodeName(prefix, encodingType) data.MaxKeys = maxKeys - data.ContinuationToken = s3EncodeName(token, encodingType) - data.NextContinuationToken = s3EncodeName(nextToken, encodingType) + data.ContinuationToken = base64.StdEncoding.EncodeToString([]byte(token)) + data.NextContinuationToken = base64.StdEncoding.EncodeToString([]byte(nextToken)) data.IsTruncated = isTruncated for _, prefix := range prefixes { var prefixItem = CommonPrefix{}