Skip to content

Commit

Permalink
fix: swag rejects valid MIME Types for Produce annotation, panic (#304)
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhujer authored and easonlin404 committed Feb 21, 2019
1 parent d95e114 commit a8247dc
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 80 deletions.
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,20 +371,23 @@ OPTIONS:
## Mime Types
| Mime Type | annotation |
|-----------------------------------|-----------------------------------------------------------|
| application/json | application/json, json |
| text/xml | text/xml, xml |
| text/plain | text/plain, plain |
| html | text/html, html |
| multipart/form-data | multipart/form-data, mpfd |
| application/x-www-form-urlencoded | application/x-www-form-urlencoded, x-www-form-urlencoded |
| application/vnd.api+json | application/vnd.api+json, json-api |
| application/x-json-stream | application/x-json-stream, json-stream |
| application/octet-stream | application/octet-stream, octet-stream |
| image/png | image/png, png |
| image/jpeg | image/jpeg, jpeg |
| image/gif | image/gif, gif |
`swag` accepts all MIME Types which are in the correct format, that is, match `*/*`.
Besides that, `swag` also accepts aliases for some MIME Types as follows:
| Alias | MIME Type |
|-----------------------|-----------------------------------|
| json | application/json |
| xml | text/xml |
| plain | text/plain |
| html | text/html |
| mpfd | multipart/form-data |
| x-www-form-urlencoded | application/x-www-form-urlencoded |
| json-api | application/vnd.api+json |
| json-stream | application/x-json-stream |
| octet-stream | application/octet-stream |
| png | image/png |
| jpeg | image/jpeg |
| gif | image/gif |
## Security
Expand Down
96 changes: 34 additions & 62 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ type Operation struct {
// Regular expression for comment with response
const responseCommentPattern = `([\d]+)[\s]+([\w\{\}]+)[\s]+([\w\-\.\/]+)[^"]*(.*)?`

var mimeTypeAliases = map[string]string{
"json": "application/json",
"xml": "text/xml",
"plain": "text/plain",
"html": "text/html",
"mpfd": "multipart/form-data",
"x-www-form-urlencoded": "application/x-www-form-urlencoded",
"json-api": "application/vnd.api+json",
"json-stream": "application/x-json-stream",
"octet-stream": "application/octet-stream",
"png": "image/png",
"jpeg": "image/jpeg",
"gif": "image/gif",
}

var mimeTypePattern = regexp.MustCompile("^[^/]+/[^/]+$")

// NewOperation creates a new Operation with default properties.
// map[int]Response
func NewOperation() *Operation {
Expand Down Expand Up @@ -328,71 +345,26 @@ func (operation *Operation) ParseTagsComment(commentLine string) {

// ParseAcceptComment parses comment for given `accept` comment string.
func (operation *Operation) ParseAcceptComment(commentLine string) error {
accepts := strings.Split(commentLine, ",")
for _, a := range accepts {
switch a {
case "json", "application/json":
operation.Consumes = append(operation.Consumes, "application/json")
case "xml", "text/xml":
operation.Consumes = append(operation.Consumes, "text/xml")
case "plain", "text/plain":
operation.Consumes = append(operation.Consumes, "text/plain")
case "html", "text/html":
operation.Consumes = append(operation.Consumes, "text/html")
case "mpfd", "multipart/form-data":
operation.Consumes = append(operation.Consumes, "multipart/form-data")
case "x-www-form-urlencoded", "application/x-www-form-urlencoded":
operation.Consumes = append(operation.Consumes, "application/x-www-form-urlencoded")
case "json-api", "application/vnd.api+json":
operation.Consumes = append(operation.Consumes, "application/vnd.api+json")
case "json-stream", "application/x-json-stream":
operation.Consumes = append(operation.Consumes, "application/x-json-stream")
case "octet-stream", "application/octet-stream":
operation.Consumes = append(operation.Consumes, "application/octet-stream")
case "png", "image/png":
operation.Consumes = append(operation.Consumes, "image/png")
case "jpeg", "image/jpeg":
operation.Consumes = append(operation.Consumes, "image/jpeg")
case "gif", "image/gif":
operation.Consumes = append(operation.Consumes, "image/gif")
default:
return fmt.Errorf("%v accept type can't accepted", a)
}
}
return nil
return parseMimeTypeList(commentLine, &operation.Consumes, "%v accept type can't be accepted")
}

// ParseProduceComment parses comment for gived `produce` comment string.
// ParseProduceComment parses comment for given `produce` comment string.
func (operation *Operation) ParseProduceComment(commentLine string) error {
produces := strings.Split(commentLine, ",")
for _, a := range produces {
switch a {
case "json", "application/json":
operation.Produces = append(operation.Produces, "application/json")
case "xml", "text/xml":
operation.Produces = append(operation.Produces, "text/xml")
case "plain", "text/plain":
operation.Produces = append(operation.Produces, "text/plain")
case "html", "text/html":
operation.Produces = append(operation.Produces, "text/html")
case "mpfd", "multipart/form-data":
operation.Produces = append(operation.Produces, "multipart/form-data")
case "x-www-form-urlencoded", "application/x-www-form-urlencoded":
operation.Produces = append(operation.Produces, "application/x-www-form-urlencoded")
case "json-api", "application/vnd.api+json":
operation.Produces = append(operation.Produces, "application/vnd.api+json")
case "json-stream", "application/x-json-stream":
operation.Produces = append(operation.Produces, "application/x-json-stream")
case "octet-stream", "application/octet-stream":
operation.Produces = append(operation.Produces, "application/octet-stream")
case "png", "image/png":
operation.Produces = append(operation.Produces, "image/png")
case "jpeg", "image/jpeg":
operation.Produces = append(operation.Produces, "image/jpeg")
case "gif", "image/gif":
operation.Produces = append(operation.Produces, "image/gif")
default:
return fmt.Errorf("%v produce type can't accepted", a)
return parseMimeTypeList(commentLine, &operation.Produces, "%v produce type can't be accepted")
}

// parseMimeTypeList parses a list of MIME Types for a comment like
// `produce` (`Content-Type:` response header) or
// `accept` (`Accept:` request header)
func parseMimeTypeList(mimeTypeList string, typeList *[]string, format string) error {
mimeTypes := strings.Split(mimeTypeList, ",")
for _, typeName := range mimeTypes {
if mimeTypePattern.MatchString(typeName) {
*typeList = append(*typeList, typeName)
} else if aliasMimeType, ok := mimeTypeAliases[typeName]; ok {
*typeList = append(*typeList, aliasMimeType)
} else {
return fmt.Errorf(format, typeName)
}
}
return nil
Expand Down
11 changes: 7 additions & 4 deletions operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ func TestParseAcceptComment(t *testing.T) {
"application/octet-stream",
"image/png",
"image/jpeg",
"image/gif"
"image/gif",
"application/xhtml+xml",
"application/health+json"
]
}`
comment := `/@Accept json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif`
comment := `/@Accept json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif,application/xhtml+xml,application/health+json`
operation := NewOperation()
err := operation.ParseComment(comment, nil)
assert.NoError(t, err)
Expand Down Expand Up @@ -79,10 +81,11 @@ func TestParseProduceComment(t *testing.T) {
"application/octet-stream",
"image/png",
"image/jpeg",
"image/gif"
"image/gif",
"application/health+json"
]
}`
comment := `/@Produce json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif`
comment := `/@Produce json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif,application/health+json`
operation := new(Operation)
operation.ParseComment(comment, nil)
b, _ := json.MarshalIndent(operation, "", " ")
Expand Down

0 comments on commit a8247dc

Please sign in to comment.