22// Copyright (c) James Jackson-South, Jeavon Leopold, and contributors. All rights reserved.
33// Licensed under the Apache License, Version 2.0.
44// </copyright>
5+
6+ // <summary>
7+ // A singleton class for communicating with Azure Blob Storage.
8+ // </summary>
59namespace Our . Umbraco . FileSystemProviders . Azure
610{
711 using System ;
@@ -10,6 +14,7 @@ namespace Our.Umbraco.FileSystemProviders.Azure
1014 using System . Globalization ;
1115 using System . IO ;
1216 using System . Linq ;
17+ using System . Text . RegularExpressions ;
1318 using global ::Umbraco . Core . IO ;
1419 using Microsoft . WindowsAzure . Storage ;
1520 using Microsoft . WindowsAzure . Storage . Blob ;
@@ -34,6 +39,11 @@ internal class AzureFileSystem : IFileSystem
3439 /// </summary>
3540 private const string Delimiter = "/" ;
3641
42+ /// <summary>
43+ /// The regex for parsing container names.
44+ /// </summary>
45+ private static readonly Regex ContainerRegex = new Regex ( "^[a-z0-9](?:[a-z0-9]|(\\ -(?!\\ -))){1,61}[a-z0-9]$|^\\ $root$" , RegexOptions . Compiled ) ;
46+
3747 /// <summary>
3848 /// Our object to lock against during initialization.
3949 /// </summary>
@@ -525,7 +535,7 @@ public Stream OpenFile(string path)
525535
526536 if ( ! blockBlob . Exists ( ) )
527537 {
528- this . LogHelper . Info < AzureBlobFileSystem > ( string . Format ( "No file exists at {0 }." , path ) ) ;
538+ this . LogHelper . Info < AzureBlobFileSystem > ( $ "No file exists at { path } .") ;
529539 return null ;
530540 }
531541
@@ -549,7 +559,16 @@ public Stream OpenFile(string path)
549559 /// <returns>The <see cref="CloudBlobContainer"/></returns>
550560 private static CloudBlobContainer CreateContainer ( CloudBlobClient cloudBlobClient , string containerName , BlobContainerPublicAccessType accessType )
551561 {
552- CloudBlobContainer container = cloudBlobClient . GetContainerReference ( containerName ) ;
562+ containerName = containerName . ToLowerInvariant ( ) ;
563+
564+ // Validate container name - from: http://stackoverflow.com/a/23364534/5018
565+ bool isContainerNameValid = ContainerRegex . IsMatch ( containerName ) ;
566+ if ( isContainerNameValid == false )
567+ {
568+ throw new ArgumentException ( $ "The container name { containerName } is not valid, see https://msdn.microsoft.com/en-us/library/azure/dd135715.aspx for the restrtictions for container names.") ;
569+ }
570+
571+ CloudBlobContainer container = cloudBlobClient . GetContainerReference ( containerName . ToLowerInvariant ( ) ) ;
553572 container . CreateIfNotExists ( ) ;
554573 container . SetPermissions ( new BlobContainerPermissions { PublicAccess = accessType } ) ;
555574 return container ;
0 commit comments