From f80d16cd106a69fc4e34882718182af61f81e817 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 8 Jul 2026 10:22:01 +0800 Subject: [PATCH] fix(util/gvalid): date validation allows invalid formats like Y-MMMM and invalid dates like 2026-13-33 (#4740) --- .../gvalid/gvalid_z_unit_feature_rule_test.go | 5 +++++ util/gvalid/internal/builtin/builtin_date.go | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/util/gvalid/gvalid_z_unit_feature_rule_test.go b/util/gvalid/gvalid_z_unit_feature_rule_test.go index da6f94898..f77e9afce 100755 --- a/util/gvalid/gvalid_z_unit_feature_rule_test.go +++ b/util/gvalid/gvalid_z_unit_feature_rule_test.go @@ -279,6 +279,11 @@ func Test_Date(t *testing.T) { "2010/11/01": true, "2010=11=01": false, "123": false, + "2026-1111": false, // Bug: invalid format should not pass + "2026-13-33": false, // Bug: invalid date should not pass + "2026-02-29": false, // Non-leap year should not pass + "2024-02-29": true, // Leap year should pass + "202611-11": false, // Invalid separator should not pass } for k, v := range m { err := g.Validator().Data(k).Rules("date").Run(ctx) diff --git a/util/gvalid/internal/builtin/builtin_date.go b/util/gvalid/internal/builtin/builtin_date.go index d186bbd64..eff0e9a98 100644 --- a/util/gvalid/internal/builtin/builtin_date.go +++ b/util/gvalid/internal/builtin/builtin_date.go @@ -10,7 +10,7 @@ import ( "errors" "time" - "github.com/gogf/gf/v2/text/gregex" + "github.com/gogf/gf/v2/os/gtime" ) // RuleDate implements `date` rule: @@ -41,12 +41,19 @@ func (r RuleDate) Run(in RunInput) error { if obj.IsZero() { return errors.New(in.Message) } + return nil } - if !gregex.IsMatchString( - `\d{4}[\.\-\_/]{0,1}\d{2}[\.\-\_/]{0,1}\d{2}`, - in.Value.String(), - ) { - return errors.New(in.Message) + // Try direct time conversion for validation, which handles both format and date validity. + // Support common date formats: 2006-01-02, 20060102, 2006.01.02, 2006/01/02 + if _, err := gtime.StrToTimeFormat(in.Value.String(), "Ymd"); err != nil { + // Try with different separator formats + if _, err := gtime.StrToTimeFormat(in.Value.String(), "Y-m-d"); err != nil { + if _, err := gtime.StrToTimeFormat(in.Value.String(), "Y.m.d"); err != nil { + if _, err := gtime.StrToTimeFormat(in.Value.String(), "Y/m/d"); err != nil { + return errors.New(in.Message) + } + } + } } return nil }