diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobUriBuilder.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobUriBuilder.cs index 4b19c2c31a5d..26aeec1d767a 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobUriBuilder.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobUriBuilder.cs @@ -285,9 +285,9 @@ private RequestUriBuilder BuildUri() if (!string.IsNullOrWhiteSpace(BlobContainerName)) { path.Append("/").Append(BlobContainerName); - if (!String.IsNullOrWhiteSpace(BlobName)) + if (!string.IsNullOrWhiteSpace(BlobName)) { - path.Append("/").Append(BlobName); + path.Append("/").Append(Uri.EscapeDataString(BlobName)); } } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs index b262ddeff6dc..618153e0d577 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs @@ -61,6 +61,30 @@ public void Ctor_ConnectionString() Assert.AreEqual("accountName", builder2.AccountName); } + [Test] + // Test framework doesn't allow recorded tests with connection string because the word 'Sanitized' is not base-64 encoded, + // so we can't pass connection string validation" + [LiveOnly] + public async Task Ctor_ConnectionStringEscapeBlobName() + { + // Arrange + await using DisposingContainer test = await GetTestContainerAsync(); + string blobName = "!*'();[]:@&%=+$,/?#äÄöÖüÜß"; + + BlockBlobClient initalBlob = InstrumentClient(test.Container.GetBlockBlobClient(blobName)); + var data = GetRandomBuffer(Constants.KB); + + using var stream = new MemoryStream(data); + Response uploadResponse = await initalBlob.UploadAsync(stream); + + // Act + BlobBaseClient blob = new BlobBaseClient(TestConfigDefault.ConnectionString, test.Container.Name, blobName, GetOptions()); + Response propertiesResponse = await blob.GetPropertiesAsync(); + + // Assert + Assert.AreEqual(uploadResponse.Value.ETag, propertiesResponse.Value.ETag); + } + [Test] public void Ctor_Uri() { diff --git a/sdk/storage/Azure.Storage.Files.Shares/src/ShareUriBuilder.cs b/sdk/storage/Azure.Storage.Files.Shares/src/ShareUriBuilder.cs index bbade2a9a437..96e07eb9bab8 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/src/ShareUriBuilder.cs +++ b/sdk/storage/Azure.Storage.Files.Shares/src/ShareUriBuilder.cs @@ -279,7 +279,7 @@ private RequestUriBuilder BuildUri() path.Append("/").Append(ShareName); if (!string.IsNullOrWhiteSpace(DirectoryOrFilePath)) { - path.Append("/").Append(DirectoryOrFilePath); + path.Append("/").Append(Uri.EscapeDataString(DirectoryOrFilePath)); } } diff --git a/sdk/storage/Azure.Storage.Files.Shares/tests/DirectoryClientTests.cs b/sdk/storage/Azure.Storage.Files.Shares/tests/DirectoryClientTests.cs index 1dea23ce6d19..25d8bbd1d4cf 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/tests/DirectoryClientTests.cs +++ b/sdk/storage/Azure.Storage.Files.Shares/tests/DirectoryClientTests.cs @@ -44,6 +44,30 @@ public void Ctor_ConnectionString() //Assert.AreEqual("accountName", builder.AccountName); } + [Test] + //Test framework doesn't allow recorded tests with connection string because the word 'Sanitized' is not base-64 encoded, + // so we can't pass connection string validation" + [LiveOnly] + public async Task Ctor_ConnectionStringEscapePath() + { + // Arrange + await using DisposingShare test = await GetTestShareAsync(); + string directoryName = "!#@&=;äÄöÖüÜß"; + ShareDirectoryClient initalDirectory = InstrumentClient(test.Share.GetDirectoryClient(directoryName)); + Response createResponse = await initalDirectory.CreateAsync(); + + // Act + ShareDirectoryClient directory = new ShareDirectoryClient( + TestConfigDefault.ConnectionString, + test.Share.Name, + directoryName, + GetOptions()); + Response propertiesResponse = await directory.GetPropertiesAsync(); + + // Assert + Assert.AreEqual(createResponse.Value.ETag, propertiesResponse.Value.ETag); + } + [Test] public void DirectoryPathsParsing() { diff --git a/sdk/storage/Azure.Storage.Files.Shares/tests/FileClientTests.cs b/sdk/storage/Azure.Storage.Files.Shares/tests/FileClientTests.cs index 21212f13c931..570c1bfcb1be 100644 --- a/sdk/storage/Azure.Storage.Files.Shares/tests/FileClientTests.cs +++ b/sdk/storage/Azure.Storage.Files.Shares/tests/FileClientTests.cs @@ -50,6 +50,33 @@ public void Ctor_ConnectionString() //Assert.AreEqual("accountName", builder.AccountName); } + [Test] + // "Test framework doesn't allow recorded tests with connection string because the word 'Sanitized' is not base-64 encoded, + // so we can't pass connection string validation" + [LiveOnly] + public async Task Ctor_ConnectionStringEscapePath() + { + // Arrange + await using DisposingShare test = await GetTestShareAsync(); + string directoryName = "!#@&=;äÄ"; + string fileName = "#$=;!öÖ"; + ShareDirectoryClient directory = InstrumentClient(test.Share.GetDirectoryClient(directoryName)); + await directory.CreateAsync(); + ShareFileClient initalFile = InstrumentClient(directory.GetFileClient(fileName)); + Response createResponse = await initalFile.CreateAsync(Constants.KB); + + // Act + ShareFileClient file = new ShareFileClient( + TestConfigDefault.ConnectionString, + test.Share.Name, + $"{directoryName}/{fileName}", + GetOptions()); + Response propertiesResponse = await file.GetPropertiesAsync(); + + // Assert + Assert.AreEqual(createResponse.Value.ETag, propertiesResponse.Value.ETag); + } + [Test] public void FilePathsParsing() {