Repository: getkin/kin-openapi
Pull request #85 (2019-04-16 04:45:10)

fix email validation
`^[\\w]` in regexp does not make sense, as it reads literally as "not \ and not w". It causes any email that contains `w` character in the domain to fail validation. Example

```go
func main() {
	payload := map[string]interface{}{
		"prop1": "name@www.site.com",
	}

	schema := `{
		"type": "object",
		"required": ["prop1"],
		"properties": {
			"prop1": {
				"type": "string",
				"format": "email"
			}
		}
	}
	`

	var dataSchema openapi3.Schema
	json.Unmarshal([]byte(schema), &dataSchema)
	err := dataSchema.VisitJSON(payload)
	fmt.Println(err)
}

```

gives `Error at "/prop1":JSON string doesn't match the format 'email (regular expression ^[^@]+@[^@<>",\\w]+$)'`

My understanding, `\\w` should be `\s` which is "any whitespace"

fenollp: Yeah that is weird. However this fix isn't the right one I believe: classes are not interpreted as classes when inside square brackets so if this now never accepts domains that contain an S, let's replace `\s` with the string of spaces it represents. 
evgenykireev: > classes are not interpreted as classes when inside square brackets

are you sure? I don't think so:
https://play.golang.org/p/pf7fDfI81p3

Patch:
diff --git a/README.md b/README.md
index 6d6dbc5..e979cfa 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ The project has received pull requests from many people. Thanks to everyone!
 Here's some projects that depend on _kin-openapi_:
   * [github.com/getkin/kin](https://github.com/getkin/kin) - "A configurable backend"
   * [github.com/danielgtaylor/apisprout](https://github.com/danielgtaylor/apisprout) - "Lightweight, blazing fast, cross-platform OpenAPI 3 mock server with validation"
+  * [github.com/deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) - Generate Go server boilerplate from an OpenAPI 3 spec
   * (Feel free to add your project by [creating an issue](https://github.com/getkin/kin-openapi/issues/new) or a pull request)
 
 ## Alternative projects
@@ -122,7 +123,7 @@ func main() {
 ## Custom content type for body of HTTP request/response
 
 By default, the library parses a body of HTTP request and response
-if it has one of the next content types: `"plain/text"` or `"application/json"`.
+if it has one of the next content types: `"text/plain"` or `"application/json"`.
 To support other content types you must register decoders for them:
 
 ```go
diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go
index aa7df87..9b2f316 100644
--- a/openapi3/schema_formats.go
+++ b/openapi3/schema_formats.go
@@ -19,7 +19,7 @@ func DefineStringFormat(name string, pattern string) {
 func init() {
 	// This pattern catches only some suspiciously wrong-looking email addresses.
 	// Use DefineStringFormat(...) if you need something stricter.
-	DefineStringFormat("email", `^[^@]+@[^@<>",\\w]+$`)
+	DefineStringFormat("email", `^[^@]+@[^@<>",\s]+$`)
 
 	// Base64
 	// The pattern supports base64 and b./ase64url. Padding ('=') is supported.
diff --git a/openapi3filter/req_resp_decoder.go b/openapi3filter/req_resp_decoder.go
index dee4f23..6bc1f99 100644
--- a/openapi3filter/req_resp_decoder.go
+++ b/openapi3filter/req_resp_decoder.go
@@ -662,7 +662,7 @@ func decodeBody(body io.Reader, header http.Header, schema *openapi3.SchemaRef,
 }
 
 func init() {
-	RegisterBodyDecoder("plain/text", plainBodyDecoder)
+	RegisterBodyDecoder("text/plain", plainBodyDecoder)
 	RegisterBodyDecoder("application/json", jsonBodyDecoder)
 	RegisterBodyDecoder("application/x-www-form-urlencoded", urlencodedBodyDecoder)
 	RegisterBodyDecoder("multipart/form-data", multipartBodyDecoder)


Test patch:
diff --git a/openapi3filter/req_resp_decoder_test.go b/openapi3filter/req_resp_decoder_test.go
index 86fefe0..02627fb 100644
--- a/openapi3filter/req_resp_decoder_test.go
+++ b/openapi3filter/req_resp_decoder_test.go
@@ -892,10 +892,10 @@ func TestDecodeBody(t *testing.T) {
 	d, err := json.Marshal(map[string]interface{}{"d1": "d1"})
 	require.NoError(t, err)
 	multipartForm, multipartFormMime, err := newTestMultipartForm([]*testFormPart{
-		{name: "a", contentType: "plain/text", data: strings.NewReader("a1")},
+		{name: "a", contentType: "text/plain", data: strings.NewReader("a1")},
 		{name: "b", contentType: "application/json", data: strings.NewReader("10")},
-		{name: "c", contentType: "plain/text", data: strings.NewReader("c1")},
-		{name: "c", contentType: "plain/text", data: strings.NewReader("c2")},
+		{name: "c", contentType: "text/plain", data: strings.NewReader("c1")},
+		{name: "c", contentType: "text/plain", data: strings.NewReader("c2")},
 		{name: "d", contentType: "application/json", data: bytes.NewReader(d)},
 		{name: "f", contentType: "application/octet-stream", data: strings.NewReader("foo"), filename: "f1"},
 	})
@@ -923,7 +923,7 @@ func TestDecodeBody(t *testing.T) {
 		},
 		{
 			name: "plain text",
-			mime: "plain/text",
+			mime: "text/plain",
 			body: strings.NewReader("text"),
 			want: "text",
 		},
diff --git a/openapi3filter/validation_test.go b/openapi3filter/validation_test.go
index 88bf415..7ffd33c 100644
--- a/openapi3filter/validation_test.go
+++ b/openapi3filter/validation_test.go
@@ -182,7 +182,7 @@ func TestValidateRequestBody(t *testing.T) {
 		WithRequired(true)
 
 	plainTextContent := openapi3.NewContent()
-	plainTextContent["plain/text"] = openapi3.NewMediaType().WithSchema(openapi3.NewStringSchema())
+	plainTextContent["text/plain"] = openapi3.NewMediaType().WithSchema(openapi3.NewStringSchema())
 
 	testCases := []struct {
 		name    string
@@ -217,7 +217,7 @@ func TestValidateRequestBody(t *testing.T) {
 		{
 			name: "not JSON data",
 			body: openapi3.NewRequestBody().WithContent(plainTextContent).WithRequired(true),
-			mime: "plain/text",
+			mime: "text/plain",
 			data: strings.NewReader("foo"),
 		},
 		{