Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copying blob where target name differs only in casing will break the file #892

Open
barthamark opened this issue May 21, 2019 · 0 comments

Comments

Projects
None yet
2 participants
@barthamark
Copy link

commented May 21, 2019

Which service(blob, file, queue, table) does this issue concern?

blob

Which version of the SDK was used?

9.3.3 (also happens in 5.0.2)

Which platform are you using? (ex: .NET Core 2.1)

.NET Core 2.2 (also happens in .NET Framework 4.5.2)

What problem was encountered?

Our application has a rename feature where the blob is being copied using the target name and the original one is deleted. When the target file name only differs in casing the new blob is created as expected but the file will break (i.e. the downloaded file cannot be opened).
Deleting the original blob is not required to reproduce this issue.

The reproduction steps below uses a .jpg file but I also tried with a .txt file where I found that the file is filled with white spaces and the size will be the same.

How can we reproduce the problem in the simplest way?

I reproduced this issue in a .NET Core 2.2 Console application using the Storage Emulator. Here is the code that I used. The broken file will be created with the copiedBlob2 blob.

            string storageConnectionString = "UseDevelopmentStorage=true";

            CloudStorageAccount storageAccount;
            if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
            {
                var cloudBlobClient = storageAccount.CreateCloudBlobClient();

                CloudBlobContainer cloudBlobContainer = cloudBlobClient
                    .GetContainerReference("copytest");

                if (!await cloudBlobContainer.ExistsAsync())
                {
                    await cloudBlobContainer.CreateAsync();

                    BlobContainerPermissions permissions = new BlobContainerPermissions
                    {
                        PublicAccess = BlobContainerPublicAccessType.Blob
                    };
                    await cloudBlobContainer.SetPermissionsAsync(permissions);
                }

                // Initialize a blob from an image from a computer.
                var sourceFile = @"D:\Temp\test.jpg";
                var blobName = @"Original\test.jpg";
                var blob = cloudBlobContainer.GetBlockBlobReference(blobName);
                await blob.UploadFromFileAsync(sourceFile);
                
                // Copy the blob using an entirely new blob name. This file will be healthy and accessible.
                var copiedBlobName1 = @"Copied\test.jpg";
                var copiedBlob1 = cloudBlobContainer.GetBlockBlobReference(copiedBlobName1);
                await copiedBlob1.StartCopyAsync(blob);

                // Copy the blob but change only the casing. This file will be broken.
                var copiedBlobName2 = @"original\test.jpg";
                var copiedBlob2 = cloudBlobContainer.GetBlockBlobReference(copiedBlobName2);
                await copiedBlob2.StartCopyAsync(blob);

                // Delete the original blob (not necessary for the repro but the final goal would be a rename feature).
                await blob.DeleteAsync();
            }

Have you found a mitigation/solution?

Not yet.

UPDATE: If you rename it to a temporary name and then rename it again to the target name (the one which differs only in casing) seems to work but it's a workaround only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.