Merge pull request #166 from flowonyx/v7-development

Added checking for nil receiver on Validator methods
pull/167/head
Dean Karn 9 years ago
commit 0650f73d40
  1. 2
      README.md
  2. 26
      validator.go
  3. 25
      validator_test.go

@ -227,7 +227,7 @@ please make your pull requests against those branches.
If the changes being proposed or requested are breaking changes, please create an issue, for discussion If the changes being proposed or requested are breaking changes, please create an issue, for discussion
or create a pull request against the highest development branch for example this package has a or create a pull request against the highest development branch for example this package has a
v1 and v1-development branch however, there will also be a v2-development brach even though v2 doesn't exist yet. v1 and v1-development branch however, there will also be a v2-development branch even though v2 doesn't exist yet.
I strongly encourage everyone whom creates a custom validation function to contribute them and I strongly encourage everyone whom creates a custom validation function to contribute them and
help make this package even better. help make this package even better.

@ -146,7 +146,9 @@ func New(config Config) *Validate {
// NOTE: if the key already exists, the previous validation function will be replaced. // NOTE: if the key already exists, the previous validation function will be replaced.
// NOTE: this method is not thread-safe // NOTE: this method is not thread-safe
func (v *Validate) RegisterValidation(key string, f Func) error { func (v *Validate) RegisterValidation(key string, f Func) error {
if v == nil {
panic("Validate.RegisterValidation called with nil receiver")
}
if len(key) == 0 { if len(key) == 0 {
return errors.New("Function Key cannot be empty") return errors.New("Function Key cannot be empty")
} }
@ -162,6 +164,9 @@ func (v *Validate) RegisterValidation(key string, f Func) error {
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types // RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) { func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
if v == nil {
panic("Validate.RegisterCustomTypeFunc called with nil receiver")
}
if v.config.CustomTypeFuncs == nil { if v.config.CustomTypeFuncs == nil {
v.config.CustomTypeFuncs = map[reflect.Type]CustomTypeFunc{} v.config.CustomTypeFuncs = map[reflect.Type]CustomTypeFunc{}
@ -178,7 +183,9 @@ func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{
// NOTE: it returns ValidationErrors instead of a single FieldError because this can also // NOTE: it returns ValidationErrors instead of a single FieldError because this can also
// validate Array, Slice and maps fields which may contain more than one error // validate Array, Slice and maps fields which may contain more than one error
func (v *Validate) Field(field interface{}, tag string) ValidationErrors { func (v *Validate) Field(field interface{}, tag string) ValidationErrors {
if v == nil {
panic("Validate.Field called with nil receiver")
}
errs := errsPool.Get().(ValidationErrors) errs := errsPool.Get().(ValidationErrors)
fieldVal := reflect.ValueOf(field) fieldVal := reflect.ValueOf(field)
@ -196,6 +203,9 @@ func (v *Validate) Field(field interface{}, tag string) ValidationErrors {
// NOTE: it returns ValidationErrors instead of a single FieldError because this can also // NOTE: it returns ValidationErrors instead of a single FieldError because this can also
// validate Array, Slice and maps fields which may contain more than one error // validate Array, Slice and maps fields which may contain more than one error
func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) ValidationErrors { func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) ValidationErrors {
if v == nil {
panic("Validate.FieldWithValue called with nil receiver")
}
errs := errsPool.Get().(ValidationErrors) errs := errsPool.Get().(ValidationErrors)
topVal := reflect.ValueOf(val) topVal := reflect.ValueOf(val)
@ -216,7 +226,9 @@ func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string
// NOTE: This is normally not needed, however in some specific cases such as: tied to a // NOTE: This is normally not needed, however in some specific cases such as: tied to a
// legacy data structure, it will be useful // legacy data structure, it will be useful
func (v *Validate) StructPartial(current interface{}, fields ...string) ValidationErrors { func (v *Validate) StructPartial(current interface{}, fields ...string) ValidationErrors {
if v == nil {
panic("Validate.StructPartial called with nil receiver")
}
sv, _ := v.extractType(reflect.ValueOf(current)) sv, _ := v.extractType(reflect.ValueOf(current))
name := sv.Type().Name() name := sv.Type().Name()
m := map[string]*struct{}{} m := map[string]*struct{}{}
@ -274,7 +286,9 @@ func (v *Validate) StructPartial(current interface{}, fields ...string) Validati
// NOTE: This is normally not needed, however in some specific cases such as: tied to a // NOTE: This is normally not needed, however in some specific cases such as: tied to a
// legacy data structure, it will be useful // legacy data structure, it will be useful
func (v *Validate) StructExcept(current interface{}, fields ...string) ValidationErrors { func (v *Validate) StructExcept(current interface{}, fields ...string) ValidationErrors {
if v == nil {
panic("Validate.StructExcept called with nil receiver")
}
sv, _ := v.extractType(reflect.ValueOf(current)) sv, _ := v.extractType(reflect.ValueOf(current))
name := sv.Type().Name() name := sv.Type().Name()
m := map[string]*struct{}{} m := map[string]*struct{}{}
@ -297,7 +311,9 @@ func (v *Validate) StructExcept(current interface{}, fields ...string) Validatio
// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified. // Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
func (v *Validate) Struct(current interface{}) ValidationErrors { func (v *Validate) Struct(current interface{}) ValidationErrors {
if v == nil {
panic("Validate.Struct called with nil receiver")
}
errs := errsPool.Get().(ValidationErrors) errs := errsPool.Get().(ValidationErrors)
sv := reflect.ValueOf(current) sv := reflect.ValueOf(current)

@ -210,6 +210,31 @@ type TestPartial struct {
} }
} }
func TestNilValidator(t *testing.T) {
type TestStruct struct {
Test string `validate:"required"`
}
ts := TestStruct{}
var val *Validate
fn := func(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
return current.String() == field.String()
}
PanicMatches(t, func() { val.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) }, "Validate.RegisterCustomTypeFunc called with nil receiver")
PanicMatches(t, func() { val.RegisterValidation("something", fn) }, "Validate.RegisterValidation called with nil receiver")
PanicMatches(t, func() { val.Field(ts.Test, "required") }, "Validate.Field called with nil receiver")
PanicMatches(t, func() { val.FieldWithValue("test", ts.Test, "required") }, "Validate.FieldWithValue called with nil receiver")
PanicMatches(t, func() { val.Struct(ts) }, "Validate.Struct called with nil receiver")
PanicMatches(t, func() { val.StructExcept(ts, "Test") }, "Validate.StructExcept called with nil receiver")
PanicMatches(t, func() { val.StructPartial(ts, "Test") }, "Validate.StructPartial called with nil receiver")
}
func TestStructPartial(t *testing.T) { func TestStructPartial(t *testing.T) {
p1 := []string{ p1 := []string{

Loading…
Cancel
Save