Repository: fsouza/fake-gcs-server
Pull request #330 (2020-09-17 09:43:50)

Fix bucket name validation to allow underscores
According to Google's [bucket naming guidelines](https://cloud.google.com/storage/docs/naming-buckets) underscores in bucket names are OK.

This patch updates the validation regex to more closely match the guidelines, by:

* Allowing underscores
* Preventing non-alphanumeric characters at the start/end of names

I haven't added the length checks, or for the `goog` prefix, so these can still be created erroneously - but this should fix downstream projects that have broken because of the incorrect name validation change.


Patch:
diff --git a/fakestorage/bucket.go b/fakestorage/bucket.go
index 65eeeea..029cebb 100644
--- a/fakestorage/bucket.go
+++ b/fakestorage/bucket.go
@@ -13,7 +13,7 @@ import (
 	"github.com/gorilla/mux"
 )
 
-var bucketRegexp = regexp.MustCompile(`^[a-zA-Z0-9-][a-zA-Z0-9.-]*[a-zA-Z0-9-]$`)
+var bucketRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$`)
 
 // CreateBucket creates a bucket inside the server, so any API calls that
 // require the bucket name will recognize this bucket.


Test patch:
diff --git a/fakestorage/bucket_test.go b/fakestorage/bucket_test.go
index 9ded216..968e267 100644
--- a/fakestorage/bucket_test.go
+++ b/fakestorage/bucket_test.go
@@ -20,7 +20,8 @@ func TestServerClientBucketAttrs(t *testing.T) {
 		{BucketName: "some-bucket", Name: "img/hi-res/party-01.jpg"},
 		{BucketName: "some-bucket", Name: "img/hi-res/party-02.jpg"},
 		{BucketName: "some-bucket", Name: "img/hi-res/party-03.jpg"},
-		{BucketName: "other-bucket", Name: "static/css/website.css"},
+		{BucketName: "other_bucket", Name: "static/css/website.css"},
+		{BucketName: "dot.bucket", Name: "static/js/app.js"},
 	}
 	startTime := time.Now()
 	runServersTest(t, objs, func(t *testing.T, server *Server) {
@@ -96,8 +97,12 @@ func TestServerClientBucketAttrsAfterCreateBucketByPost(t *testing.T) {
 func TestServerClientBucketCreateValidation(t *testing.T) {
 	bucketNames := []string{
 		"..what-is-this",
+		"-hostname-cant-start-with-dash",
+		"_hostname-cant-start-with-underscore",
+		"hostname-cant-end-with-dash-",
+		"hostname-cant-end-with-underscore_",
 		".host.name.cant.start.with.dot",
-		"no_underlines_either",
+		"host.name.cant.end.with.dot.",
 		"or spaces",
 		"don't even try",
 		"no/slashes/either",
@@ -133,7 +138,8 @@ func TestServerClientListBuckets(t *testing.T) {
 		{BucketName: "some-bucket", Name: "img/hi-res/party-01.jpg"},
 		{BucketName: "some-bucket", Name: "img/hi-res/party-02.jpg"},
 		{BucketName: "some-bucket", Name: "img/hi-res/party-03.jpg"},
-		{BucketName: "other-bucket", Name: "static/css/website.css"},
+		{BucketName: "other_bucket", Name: "static/css/website.css"},
+		{BucketName: "dot.bucket", Name: "static/js/app.js"},
 	}
 
 	runServersTest(t, objs, func(t *testing.T, server *Server) {
@@ -147,7 +153,7 @@ func TestServerClientListBuckets(t *testing.T) {
 		}
 		it := client.Buckets(context.Background(), "whatever")
 		expectedBuckets := map[string]bool{
-			"other-bucket": false, "some-bucket": false, versionedBucketName: true,
+			"other_bucket": false, "dot.bucket": false, "some-bucket": false, versionedBucketName: true,
 		}
 		b, err := it.Next()
 		numberOfBuckets := 0