Repository: getkin/kin-openapi
Pull request #778 (2023-03-23 08:44:23)

feat: support nil uuid
This makes the regex supporting `nil` UUID like defined in the RFC: https://www.rfc-editor.org/rfc/rfc4122#section-4.1.7

fenollp: Please add a test. 
I'd also prefer you add the zeros to the third and fifth square brackets instead of a big group. 
zekth: > I'd also prefer you add the zeros to the third and fifth square brackets instead of a big group.

Wouldn't this allow to create invalid uuids then?
fenollp: Ah you're right

Patch:
diff --git a/.github/docs/openapi3.txt b/.github/docs/openapi3.txt
index 3ce7ed9..82a5e0b 100644
--- a/.github/docs/openapi3.txt
+++ b/.github/docs/openapi3.txt
@@ -1,6 +1,6 @@
 const ParameterInPath = "path" ...
 const TypeArray = "array" ...
-const FormatOfStringForUUIDOfRFC4122 = `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$` ...
+const FormatOfStringForUUIDOfRFC4122 = `^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$` ...
 const SerializationSimple = "simple" ...
 var SchemaErrorDetailsDisabled = false ...
 var CircularReferenceCounter = 3
diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go
index ecbc0eb..ea38400 100644
--- a/openapi3/schema_formats.go
+++ b/openapi3/schema_formats.go
@@ -9,7 +9,7 @@ import (
 
 const (
 	// FormatOfStringForUUIDOfRFC4122 is an optional predefined format for UUID v1-v5 as specified by RFC4122
-	FormatOfStringForUUIDOfRFC4122 = `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$`
+	FormatOfStringForUUIDOfRFC4122 = `^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$`
 
 	// FormatOfStringForEmail pattern catches only some suspiciously wrong-looking email addresses.
 	// Use DefineStringFormat(...) if you need something stricter.


Test patch:
diff --git a/openapi3/schema_formats_test.go b/openapi3/schema_formats_test.go
index 3899fab..70092d6 100644
--- a/openapi3/schema_formats_test.go
+++ b/openapi3/schema_formats_test.go
@@ -3,6 +3,7 @@ package openapi3
 import (
 	"context"
 	"errors"
+	"fmt"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -105,3 +106,51 @@ components:
 	delete(SchemaStringFormats, "ipv4")
 	SchemaErrorDetailsDisabled = false
 }
+
+func TestUuidFormat(t *testing.T) {
+
+	type testCase struct {
+		name    string
+		value   string
+		wantErr bool
+	}
+
+	DefineStringFormat("uuid", FormatOfStringForUUIDOfRFC4122)
+	testCases := []testCase{
+		{
+			name:    "invalid",
+			value:   "foo",
+			wantErr: true,
+		},
+		{
+			name:    "uuid v1",
+			value:   "77e66540-ca29-11ed-afa1-0242ac120002",
+			wantErr: false,
+		},
+		{
+			name:    "uuid v4",
+			value:   "00f4d301-b9f4-4366-8907-2b5a03430aa1",
+			wantErr: false,
+		},
+		{
+			name:    "uuid nil",
+			value:   "00000000-0000-0000-0000-000000000000",
+			wantErr: false,
+		},
+	}
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			err := NewUUIDSchema().VisitJSON(tc.value)
+			var schemaError = &SchemaError{}
+			if tc.wantErr {
+				require.Error(t, err)
+				require.ErrorAs(t, err, &schemaError)
+
+				require.NotZero(t, schemaError.Reason)
+				require.NotContains(t, schemaError.Reason, fmt.Sprint(tc.value))
+			} else {
+				require.Nil(t, err)
+			}
+		})
+	}
+}