Skip to content

Commit

Permalink
fix: Fixed CopySource parsing to handle the values starting with '/' …
Browse files Browse the repository at this point in the history
…in CopyObject action in posix and azure backends.
  • Loading branch information
0x180 committed Jul 22, 2024
1 parent d521c66 commit 5e484f2
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
9 changes: 7 additions & 2 deletions backend/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,12 @@ func (az *Azure) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3
return nil, azureErrToS3Err(err)
}

if strings.Join([]string{*input.Bucket, *input.Key}, "/") == *input.CopySource && isMetaSame(res.Metadata, input.Metadata) {
cpSrc := *input.CopySource
if cpSrc[0] == '/' {
cpSrc = cpSrc[1:]
}

if strings.Join([]string{*input.Bucket, *input.Key}, "/") == cpSrc && isMetaSame(res.Metadata, input.Metadata) {
return nil, s3err.GetAPIError(s3err.ErrInvalidCopyDest)
}

Expand All @@ -758,7 +763,7 @@ func (az *Azure) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3
return nil, err
}

resp, err := client.CopyFromURL(ctx, az.serviceURL+"/"+*input.CopySource, &blob.CopyFromURLOptions{
resp, err := client.CopyFromURL(ctx, az.serviceURL+"/"+cpSrc, &blob.CopyFromURLOptions{
BlobTags: tags,
Metadata: parseMetadata(input.Metadata),
})
Expand Down
8 changes: 7 additions & 1 deletion backend/posix/posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -1938,7 +1938,13 @@ func (p *Posix) CopyObject(ctx context.Context, input *s3.CopyObjectInput) (*s3.
if input.ExpectedBucketOwner == nil {
return nil, s3err.GetAPIError(s3err.ErrInvalidRequest)
}
srcBucket, srcObject, ok := strings.Cut(*input.CopySource, "/")

cpSrc := *input.CopySource
if cpSrc[0] == '/' {
cpSrc = cpSrc[1:]
}

srcBucket, srcObject, ok := strings.Cut(cpSrc, "/")
if !ok {
return nil, s3err.GetAPIError(s3err.ErrInvalidCopySource)
}
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/group-tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func TestCopyObject(s *S3Conf) {
CopyObject_not_owned_source_bucket(s)
CopyObject_copy_to_itself(s)
CopyObject_to_itself_with_new_metadata(s)
CopyObject_CopySource_starting_with_slash(s)
CopyObject_success(s)
}

Expand Down Expand Up @@ -609,6 +610,7 @@ func GetIntTests() IntTests {
"CopyObject_not_owned_source_bucket": CopyObject_not_owned_source_bucket,
"CopyObject_copy_to_itself": CopyObject_copy_to_itself,
"CopyObject_to_itself_with_new_metadata": CopyObject_to_itself_with_new_metadata,
"CopyObject_CopySource_starting_with_slash": CopyObject_CopySource_starting_with_slash,
"CopyObject_success": CopyObject_success,
"PutObjectTagging_non_existing_object": PutObjectTagging_non_existing_object,
"PutObjectTagging_long_tags": PutObjectTagging_long_tags,
Expand Down
60 changes: 60 additions & 0 deletions tests/integration/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4215,6 +4215,66 @@ func CopyObject_to_itself_with_new_metadata(s *S3Conf) error {
})
}

func CopyObject_CopySource_starting_with_slash(s *S3Conf) error {
testName := "CopyObject_CopySource_starting_with_slash"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
dataLength, obj := int64(1234567), "src-obj"
dstBucket := getBucketName()
if err := setup(s, dstBucket); err != nil {
return err
}

csum, _, err := putObjectWithData(dataLength, &s3.PutObjectInput{
Bucket: &bucket,
Key: &obj,
}, s3client)
if err != nil {
return err
}

ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
Bucket: &dstBucket,
Key: &obj,
CopySource: getPtr(fmt.Sprintf("/%v/%v", bucket, obj)),
})
cancel()
if err != nil {
return err
}

ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
out, err := s3client.GetObject(ctx, &s3.GetObjectInput{
Bucket: &dstBucket,
Key: &obj,
})
defer cancel()
if err != nil {
return err
}
if *out.ContentLength != dataLength {
return fmt.Errorf("expected content-length %v, instead got %v", dataLength, out.ContentLength)
}

defer out.Body.Close()

bdy, err := io.ReadAll(out.Body)
if err != nil {
return err
}
outCsum := sha256.Sum256(bdy)
if outCsum != csum {
return fmt.Errorf("invalid object data")
}

if err := teardown(s, dstBucket); err != nil {
return err
}

return nil
})
}

func CopyObject_success(s *S3Conf) error {
testName := "CopyObject_success"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
Expand Down

0 comments on commit 5e484f2

Please sign in to comment.