File tree Expand file tree Collapse file tree 5 files changed +27
-2
lines changed
Expand file tree Collapse file tree 5 files changed +27
-2
lines changed Original file line number Diff line number Diff line change @@ -516,7 +516,7 @@ export function url(params?: string | core.$ZodURLParams): ZodURL {
516516
517517export function httpUrl ( params ?: string | Omit < core . $ZodURLParams , "protocol" | "hostname" > ) : ZodURL {
518518 return core . _url ( ZodURL , {
519- protocol : / ^ h t t p s ? $ / ,
519+ protocol : core . regexes . httpProtocol ,
520520 hostname : core . regexes . domain ,
521521 ...util . normalizeParams ( params ) ,
522522 } ) ;
Original file line number Diff line number Diff line change @@ -454,6 +454,12 @@ test("httpurl", () => {
454454 ) . toThrow ( ) ;
455455 expect ( ( ) => httpUrl . parse ( "http://asdf.c" ) ) . toThrow ( ) ;
456456 expect ( ( ) => httpUrl . parse ( "mailto:asdf@lckj.com" ) ) . toThrow ( ) ;
457+ // missing // after protocol
458+ expect ( ( ) => httpUrl . parse ( "http:example.com" ) ) . toThrow ( ) ;
459+ expect ( ( ) => httpUrl . parse ( "https:example.com" ) ) . toThrow ( ) ;
460+ // missing one /
461+ expect ( ( ) => httpUrl . parse ( "https:/www.google.com" ) ) . toThrow ( ) ;
462+ expect ( ( ) => httpUrl . parse ( "http:/example.com" ) ) . toThrow ( ) ;
457463} ) ;
458464
459465test ( "url error overrides" , ( ) => {
Original file line number Diff line number Diff line change @@ -81,6 +81,8 @@ export const hostname: RegExp =
8181
8282export const domain : RegExp = / ^ ( [ a - z A - Z 0 - 9 ] (?: [ a - z A - Z 0 - 9 - ] { 0 , 61 } [ a - z A - Z 0 - 9 ] ) ? \. ) + [ a - z A - Z ] { 2 , } $ / ;
8383
84+ export const httpProtocol : RegExp = / ^ h t t p s ? $ / ;
85+
8486// https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces)
8587// E.164: leading digit must be 1-9; total digits (excluding '+') between 7-15
8688export const e164 : RegExp = / ^ \+ [ 1 - 9 ] \d { 6 , 14 } $ / ;
Original file line number Diff line number Diff line change @@ -478,6 +478,23 @@ export const $ZodURL: core.$constructor<$ZodURL> = /*@__PURE__*/ core.$construct
478478 try {
479479 // Trim whitespace from input
480480 const trimmed = payload . value . trim ( ) ;
481+
482+ // When normalize is off, require :// for http/https URLs
483+ // This prevents strings like "http:example.com" or "https:/path" from being silently accepted
484+ if ( ! def . normalize && def . protocol ?. source === regexes . httpProtocol . source ) {
485+ if ( ! / ^ h t t p s ? : \/ \/ / i. test ( trimmed ) ) {
486+ payload . issues . push ( {
487+ code : "invalid_format" ,
488+ format : "url" ,
489+ note : "Invalid URL format" ,
490+ input : payload . value ,
491+ inst,
492+ continue : ! def . abort ,
493+ } ) ;
494+ return ;
495+ }
496+ }
497+
481498 // @ts -ignore
482499 const url = new URL ( trimmed ) ;
483500
Original file line number Diff line number Diff line change @@ -200,7 +200,7 @@ export function url(params?: string | core.$ZodURLParams): ZodMiniURL {
200200// @__NO_SIDE_EFFECTS__
201201export function httpUrl ( params ?: string | Omit < core . $ZodURLParams , "protocol" | "hostname" > ) : ZodMiniURL {
202202 return core . _url ( ZodMiniURL , {
203- protocol : / ^ h t t p s ? $ / ,
203+ protocol : core . regexes . httpProtocol ,
204204 hostname : core . regexes . domain ,
205205 ...util . normalizeParams ( params ) ,
206206 } ) ;
You can’t perform that action at this time.
0 commit comments