From f746922fa5407e230e6ea66280273b41c0d7280c Mon Sep 17 00:00:00 2001 From: Jos Houtman Date: Fri, 16 Apr 2021 11:02:59 +0200 Subject: [PATCH] Path escape the data return in the X-Object-Manifest header This fixes an rclone bug 5180 where openstack/swift returned an url encoded path in the X-Object-Manifest header. This then caused problems when resolving the segments. --- dlo.go | 6 +++++- largeobjects.go | 14 +++++++++++--- slo.go | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/dlo.go b/dlo.go index 35acce729..da0684a76 100644 --- a/dlo.go +++ b/dlo.go @@ -46,7 +46,11 @@ func (c *Connection) DynamicLargeObjectMove(ctx context.Context, srcContainer st return err } - segmentContainer, segmentPath := parseFullPath(headers["X-Object-Manifest"]) + segmentContainer, segmentPath, err := parseFullPath(headers["X-Object-Manifest"]) + if err != nil { + return err + } + if err := c.createDLOManifest(ctx, dstContainer, dstObjectName, segmentContainer+"/"+segmentPath, info.ContentType, sanitizeLargeObjectMoveHeaders(headers)); err != nil { return err } diff --git a/largeobjects.go b/largeobjects.go index 50e0b5e82..e65252ddc 100644 --- a/largeobjects.go +++ b/largeobjects.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "net/url" "os" gopath "path" "strconv" @@ -57,13 +58,17 @@ func getSegment(segmentPath string, partNumber int) string { return fmt.Sprintf("%s/%016d", segmentPath, partNumber) } -func parseFullPath(manifest string) (container string, prefix string) { +func parseFullPath(manifest string) (container string, prefix string, err error) { + manifest, err = url.PathUnescape(manifest) + if err != nil { + return + } components := strings.SplitN(manifest, "/", 2) container = components[0] if len(components) > 1 { prefix = components[1] } - return container, prefix + return container, prefix, nil } func (headers Headers) IsLargeObjectDLO() bool { @@ -82,7 +87,10 @@ func (headers Headers) IsLargeObject() bool { func (c *Connection) getAllSegments(ctx context.Context, container string, path string, headers Headers) (string, []Object, error) { if manifest, isDLO := headers["X-Object-Manifest"]; isDLO { - segmentContainer, segmentPath := parseFullPath(manifest) + segmentContainer, segmentPath, err := parseFullPath(manifest) + if err != nil { + return segmentContainer, nil, err + } segments, err := c.getAllDLOSegments(ctx, segmentContainer, segmentPath) return segmentContainer, segments, err } diff --git a/slo.go b/slo.go index 9f5ac783e..b656096a3 100644 --- a/slo.go +++ b/slo.go @@ -164,7 +164,10 @@ func (c *Connection) getAllSLOSegments(ctx context.Context, container, path stri json.Unmarshal(content, &segmentList) for _, segment := range segmentList { - segmentContainer, segPath = parseFullPath(segment.Name[1:]) + segmentContainer, segPath, err = parseFullPath(segment.Name[1:]) + if err != nil { + return "", nil, err + } segments = append(segments, Object{ Name: segPath, Bytes: segment.Bytes,