Skip to content

Commit 46b292e

Browse files
authored
Fix: #1112 URL validation accepts "http:" as valid url (#1114)
## Fixes Or Enhances Fixes #1112 **Make sure that you've checked the boxes below before you submit PR:** - [x] Tests exist or have been written that cover this particular change. @go-playground/validator-maintainers Benchmarks before: ``` GO111MODULE=on go test -bench=. -benchmem ./... goos: linux goarch: amd64 pkg: github.com/go-playground/validator/v10 cpu: AMD Ryzen 7 PRO 3700U w/ Radeon Vega Mobile Gfx BenchmarkFieldSuccess-8 11801617 93.70 ns/op 0 B/op 0 allocs/op BenchmarkFieldSuccessParallel-8 54093084 20.37 ns/op 0 B/op 0 allocs/op BenchmarkFieldFailure-8 1362246 973.9 ns/op 200 B/op 4 allocs/op BenchmarkFieldFailureParallel-8 6183358 176.7 ns/op 200 B/op 4 allocs/op BenchmarkFieldArrayDiveSuccess-8 1000000 1645 ns/op 145 B/op 8 allocs/op BenchmarkFieldArrayDiveSuccessParallel-8 4890320 228.8 ns/op 145 B/op 8 allocs/op BenchmarkFieldArrayDiveFailure-8 1000000 2394 ns/op 348 B/op 13 allocs/op BenchmarkFieldArrayDiveFailureParallel-8 2763897 410.4 ns/op 349 B/op 13 allocs/op BenchmarkFieldMapDiveSuccess-8 602858 3888 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveSuccessParallel-8 2359784 516.7 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveFailure-8 624718 3158 ns/op 376 B/op 13 allocs/op BenchmarkFieldMapDiveFailureParallel-8 2218954 495.2 ns/op 376 B/op 13 allocs/op BenchmarkFieldMapDiveWithKeysSuccess-8 534006 4128 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveWithKeysSuccessParallel-8 1714122 669.2 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveWithKeysFailure-8 459775 4310 ns/op 553 B/op 16 allocs/op BenchmarkFieldMapDiveWithKeysFailureParallel-8 1275787 958.4 ns/op 553 B/op 16 allocs/op BenchmarkFieldCustomTypeSuccess-8 1944307 584.1 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeSuccessParallel-8 11220068 107.1 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeFailure-8 1661941 680.6 ns/op 184 B/op 3 allocs/op BenchmarkFieldCustomTypeFailureParallel-8 6390658 203.3 ns/op 184 B/op 3 allocs/op BenchmarkFieldOrTagSuccess-8 1000000 1131 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagSuccessParallel-8 4221580 259.6 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagFailure-8 1393892 934.2 ns/op 216 B/op 5 allocs/op BenchmarkFieldOrTagFailureParallel-8 5197488 212.3 ns/op 216 B/op 5 allocs/op BenchmarkStructLevelValidationSuccess-8 2816329 452.1 ns/op 16 B/op 1 allocs/op BenchmarkStructLevelValidationSuccessParallel-8 17393395 75.46 ns/op 16 B/op 1 allocs/op BenchmarkStructLevelValidationFailure-8 1000000 1588 ns/op 264 B/op 7 allocs/op BenchmarkStructLevelValidationFailureParallel-8 4049802 292.1 ns/op 264 B/op 7 allocs/op BenchmarkStructSimpleCustomTypeSuccess-8 1250786 879.9 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeSuccessParallel-8 7151274 150.8 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeFailure-8 967278 2294 ns/op 416 B/op 9 allocs/op BenchmarkStructSimpleCustomTypeFailureParallel-8 2779010 420.0 ns/op 432 B/op 10 allocs/op BenchmarkStructFilteredSuccess-8 1000000 1805 ns/op 248 B/op 7 allocs/op BenchmarkStructFilteredSuccessParallel-8 3521836 330.2 ns/op 248 B/op 7 allocs/op BenchmarkStructFilteredFailure-8 902488 1346 ns/op 232 B/op 6 allocs/op BenchmarkStructFilteredFailureParallel-8 3735235 274.8 ns/op 232 B/op 6 allocs/op BenchmarkStructPartialSuccess-8 1000000 1596 ns/op 240 B/op 5 allocs/op BenchmarkStructPartialSuccessParallel-8 4368409 264.4 ns/op 240 B/op 5 allocs/op BenchmarkStructPartialFailure-8 717194 2519 ns/op 456 B/op 10 allocs/op BenchmarkStructPartialFailureParallel-8 2608501 469.6 ns/op 456 B/op 10 allocs/op BenchmarkStructExceptSuccess-8 780676 2380 ns/op 456 B/op 10 allocs/op BenchmarkStructExceptSuccessParallel-8 4490192 246.6 ns/op 224 B/op 4 allocs/op BenchmarkStructExceptFailure-8 976275 2091 ns/op 440 B/op 9 allocs/op BenchmarkStructExceptFailureParallel-8 2592588 469.4 ns/op 440 B/op 9 allocs/op BenchmarkStructSimpleCrossFieldSuccess-8 1000000 1123 ns/op 56 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldSuccessParallel-8 5899574 202.4 ns/op 56 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldFailure-8 851788 1740 ns/op 272 B/op 8 allocs/op BenchmarkStructSimpleCrossFieldFailureParallel-8 3188026 368.7 ns/op 272 B/op 8 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 1000000 1578 ns/op 64 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 4619691 241.5 ns/op 64 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailure-8 829128 2893 ns/op 288 B/op 9 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 2677923 398.1 ns/op 288 B/op 9 allocs/op BenchmarkStructSimpleSuccess-8 3592005 345.2 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleSuccessParallel-8 14831719 76.84 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleFailure-8 795216 2249 ns/op 416 B/op 9 allocs/op BenchmarkStructSimpleFailureParallel-8 2835547 390.4 ns/op 416 B/op 9 allocs/op BenchmarkStructComplexSuccess-8 459040 5754 ns/op 288 B/op 9 allocs/op BenchmarkStructComplexSuccessParallel-8 1591882 695.9 ns/op 288 B/op 9 allocs/op BenchmarkStructComplexFailure-8 101236 14735 ns/op 3105 B/op 52 allocs/op BenchmarkStructComplexFailureParallel-8 419730 2822 ns/op 3105 B/op 52 allocs/op BenchmarkOneof-8 7499676 159.7 ns/op 0 B/op 0 allocs/op BenchmarkOneofParallel-8 25018995 44.49 ns/op 0 B/op 0 allocs/op ``` Benchmarks after: ``` GO111MODULE=on go test -bench=. -benchmem ./... goos: linux goarch: amd64 pkg: github.com/go-playground/validator/v10 cpu: AMD Ryzen 7 PRO 3700U w/ Radeon Vega Mobile Gfx BenchmarkFieldSuccess-8 12974497 92.64 ns/op 0 B/op 0 allocs/op BenchmarkFieldSuccessParallel-8 46178876 22.92 ns/op 0 B/op 0 allocs/op BenchmarkFieldFailure-8 1345202 921.7 ns/op 200 B/op 4 allocs/op BenchmarkFieldFailureParallel-8 6294452 174.0 ns/op 200 B/op 4 allocs/op BenchmarkFieldArrayDiveSuccess-8 1000000 1610 ns/op 145 B/op 8 allocs/op BenchmarkFieldArrayDiveSuccessParallel-8 4974109 223.0 ns/op 145 B/op 8 allocs/op BenchmarkFieldArrayDiveFailure-8 1000000 2327 ns/op 348 B/op 13 allocs/op BenchmarkFieldArrayDiveFailureParallel-8 2909164 399.9 ns/op 349 B/op 13 allocs/op BenchmarkFieldMapDiveSuccess-8 551305 3845 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveSuccessParallel-8 2488228 467.0 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveFailure-8 772414 3410 ns/op 376 B/op 13 allocs/op BenchmarkFieldMapDiveFailureParallel-8 2193524 488.3 ns/op 376 B/op 13 allocs/op BenchmarkFieldMapDiveWithKeysSuccess-8 642025 3966 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveWithKeysSuccessParallel-8 1863225 554.4 ns/op 288 B/op 14 allocs/op BenchmarkFieldMapDiveWithKeysFailure-8 559651 4328 ns/op 553 B/op 16 allocs/op BenchmarkFieldMapDiveWithKeysFailureParallel-8 1647622 683.6 ns/op 553 B/op 16 allocs/op BenchmarkFieldCustomTypeSuccess-8 2121175 616.3 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeSuccessParallel-8 11822690 93.81 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeFailure-8 1485889 797.6 ns/op 184 B/op 3 allocs/op BenchmarkFieldCustomTypeFailureParallel-8 7947081 148.4 ns/op 184 B/op 3 allocs/op BenchmarkFieldOrTagSuccess-8 1000000 1167 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagSuccessParallel-8 4742452 218.4 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagFailure-8 1203343 1057 ns/op 216 B/op 5 allocs/op BenchmarkFieldOrTagFailureParallel-8 5406589 204.8 ns/op 216 B/op 5 allocs/op BenchmarkStructLevelValidationSuccess-8 3298723 489.8 ns/op 16 B/op 1 allocs/op BenchmarkStructLevelValidationSuccessParallel-8 14399948 74.10 ns/op 16 B/op 1 allocs/op BenchmarkStructLevelValidationFailure-8 1000000 1513 ns/op 264 B/op 7 allocs/op BenchmarkStructLevelValidationFailureParallel-8 4103812 278.4 ns/op 264 B/op 7 allocs/op BenchmarkStructSimpleCustomTypeSuccess-8 1406757 1091 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeSuccessParallel-8 7505160 141.8 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeFailure-8 883422 2300 ns/op 416 B/op 9 allocs/op BenchmarkStructSimpleCustomTypeFailureParallel-8 2746707 415.6 ns/op 432 B/op 10 allocs/op BenchmarkStructFilteredSuccess-8 1000000 1779 ns/op 248 B/op 7 allocs/op BenchmarkStructFilteredSuccessParallel-8 3896308 302.1 ns/op 248 B/op 7 allocs/op BenchmarkStructFilteredFailure-8 1000000 1517 ns/op 232 B/op 6 allocs/op BenchmarkStructFilteredFailureParallel-8 4696162 246.0 ns/op 232 B/op 6 allocs/op BenchmarkStructPartialSuccess-8 1000000 1636 ns/op 240 B/op 5 allocs/op BenchmarkStructPartialSuccessParallel-8 4503459 255.5 ns/op 240 B/op 5 allocs/op BenchmarkStructPartialFailure-8 857544 2530 ns/op 456 B/op 10 allocs/op BenchmarkStructPartialFailureParallel-8 2814386 415.4 ns/op 456 B/op 10 allocs/op BenchmarkStructExceptSuccess-8 712800 2558 ns/op 456 B/op 10 allocs/op BenchmarkStructExceptSuccessParallel-8 4881768 231.8 ns/op 224 B/op 4 allocs/op BenchmarkStructExceptFailure-8 980643 2203 ns/op 440 B/op 9 allocs/op BenchmarkStructExceptFailureParallel-8 3072993 393.5 ns/op 440 B/op 9 allocs/op BenchmarkStructSimpleCrossFieldSuccess-8 1000000 1350 ns/op 56 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldSuccessParallel-8 6480792 163.9 ns/op 56 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldFailure-8 890593 2411 ns/op 272 B/op 8 allocs/op BenchmarkStructSimpleCrossFieldFailureParallel-8 3336048 365.9 ns/op 272 B/op 8 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 839727 1641 ns/op 64 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 4652806 237.4 ns/op 64 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailure-8 680821 3032 ns/op 288 B/op 9 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 2641432 409.4 ns/op 288 B/op 9 allocs/op BenchmarkStructSimpleSuccess-8 3409771 375.2 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleSuccessParallel-8 14754860 81.12 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleFailure-8 802147 2292 ns/op 416 B/op 9 allocs/op BenchmarkStructSimpleFailureParallel-8 2884316 390.0 ns/op 416 B/op 9 allocs/op BenchmarkStructComplexSuccess-8 407000 5694 ns/op 288 B/op 9 allocs/op BenchmarkStructComplexSuccessParallel-8 1722357 686.1 ns/op 288 B/op 9 allocs/op BenchmarkStructComplexFailure-8 105184 14341 ns/op 3105 B/op 52 allocs/op BenchmarkStructComplexFailureParallel-8 435258 2783 ns/op 3105 B/op 52 allocs/op BenchmarkOneof-8 6750638 175.3 ns/op 0 B/op 0 allocs/op BenchmarkOneofParallel-8 25553877 45.96 ns/op 0 B/op 0 allocs/op ``` The fix doesn't appear to affect the overall performance.
1 parent fcd0d86 commit 46b292e

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

baked_in.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,25 +1414,21 @@ func isURL(fl FieldLevel) bool {
14141414
switch field.Kind() {
14151415
case reflect.String:
14161416

1417-
var i int
14181417
s := field.String()
14191418

1420-
// checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
1421-
// emulate browser and strip the '#' suffix prior to validation. see issue-#237
1422-
if i = strings.Index(s, "#"); i > -1 {
1423-
s = s[:i]
1424-
}
1425-
14261419
if len(s) == 0 {
14271420
return false
14281421
}
14291422

1430-
url, err := url.ParseRequestURI(s)
1431-
1423+
url, err := url.Parse(s)
14321424
if err != nil || url.Scheme == "" {
14331425
return false
14341426
}
14351427

1428+
if url.Host == "" && url.Fragment == "" && url.Opaque == "" {
1429+
return false
1430+
}
1431+
14361432
return true
14371433
}
14381434

@@ -1450,7 +1446,13 @@ func isHttpURL(fl FieldLevel) bool {
14501446
case reflect.String:
14511447

14521448
s := strings.ToLower(field.String())
1453-
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
1449+
1450+
url, err := url.Parse(s)
1451+
if err != nil || url.Host == "" {
1452+
return false
1453+
}
1454+
1455+
return url.Scheme == "http" || url.Scheme == "https"
14541456
}
14551457

14561458
panic(fmt.Sprintf("Bad field type %T", field.Interface()))

validator_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8039,6 +8039,8 @@ func TestUrl(t *testing.T) {
80398039
{"irc://#channel@network", true},
80408040
{"/abs/test/dir", false},
80418041
{"./rel/test/dir", false},
8042+
{"irc:", false},
8043+
{"http://", false},
80428044
}
80438045

80448046
validate := New()
@@ -8110,6 +8112,10 @@ func TestHttpUrl(t *testing.T) {
81108112
{"irc://#channel@network", false},
81118113
{"/abs/test/dir", false},
81128114
{"./rel/test/dir", false},
8115+
{"http:", false},
8116+
{"http://", false},
8117+
{"http://#invalid", false},
8118+
{"https://1.1.1.1", true},
81138119
}
81148120

81158121
validate := New()

0 commit comments

Comments
 (0)