Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The 'pattern' struct tag does not work in some cases. #555

Open
ayoo opened this issue Aug 22, 2024 · 2 comments
Open

The 'pattern' struct tag does not work in some cases. #555

ayoo opened this issue Aug 22, 2024 · 2 comments
Labels
question Further information is requested

Comments

@ayoo
Copy link

ayoo commented Aug 22, 2024

The pattern attribute used to validate input values with regex sometimes doesn't work, allowing invalid requests to get through.

Here is my test script.

    import (
        "context"
        "github.com/danielgtaylor/huma/v2"
        "github.com/danielgtaylor/huma/v2/humatest"
        "net/http"
        "testing"
    )
    
    type TestPatternInput struct {
        Body struct {
	        FirstName string `json:"firstName" required:"true" pattern:"^[\p{L}]+([\p{L} '-][\p{L}]+)*$" patternDescription:"matches any kind of letters in any language including hyphen, apostrophe and space"`
        }
    }
    
    func Test_StringPattern(t *testing.T) {
        _, humaapi := humatest.New(t)
        huma.Register(humaapi, huma.Operation{
	        Method:        http.MethodPost,
	        Path:          "/test",
	        DefaultStatus: http.StatusCreated,
        }, func(ctx context.Context, i *TestPatternInput) (*struct{}, error) {
	        return &struct{}{}, nil
        })
    
        t.Run("with valid name", func(t *testing.T) {
	        resp := humaapi.Post("/test",
		        "Content-Type: application/json",
		        map[string]string{
			        "firstName": "John",
		        })
	        if resp.Code != http.StatusCreated {
		        t.Fatal()
	        }
        })
    
        t.Run("with invalid name", func(t *testing.T) {
	        resp := humaapi.Post("/test",
		        "Content-Type: application/json",
		        map[string]string{
			        "firstName": "11111",
		        })
	        if resp.Code == http.StatusCreated {
		        t.Fatal()
	        }
        })
    }

When '111111' was provided as a firstName and it still passes the validation.

The pattern matching works in Go and tested as shown here.

Example

Is this a bug or am I missing something here?

Thanks in advance.

@ayoo
Copy link
Author

ayoo commented Aug 26, 2024

This turned out that the backslash in the pattern needed to be escaped like this pattern:

^[\\p{L}]+([\\p{L} '-][\\p{L}]+)*$

then it works all good.

The only issue with this is the default error message without 'patternDescription' containing the extra backslash as well.

  "$schema": "http://localhost:8080/schemas/ErrorModel.json",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "validation failed",
  "errors": [
    {
      "message": "expected string to match pattern ^[\\p{L}]+([\\p{L} '-][\\p{L}]+)*$",
      "location": "body.firstName",
      "value": "11111"
    }
  ]
}

@danielgtaylor danielgtaylor added the question Further information is requested label Sep 13, 2024
@danielgtaylor
Copy link
Owner

@ayoo glad you figured it out! The extra backslash in the returned JSON is because of the JSON encoder I believe, for example take a look at:

https://go.dev/play/p/-Qz6io2G89d

If this gets parsed and displayed somewhere it should just have the one backslash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants