File tree Expand file tree Collapse file tree 2 files changed +73
-4
lines changed Expand file tree Collapse file tree 2 files changed +73
-4
lines changed Original file line number Diff line number Diff line change @@ -142,11 +142,24 @@ export default function isURL(url, options) {
142142 }
143143 }
144144 } else {
145- // No @ symbol, this is definitely a protocol
146- url = cleanUpProtocol ( potential_protocol ) ;
145+ // No @ symbol found. Check if this could be a port number instead of a protocol.
146+ // If what's after the colon is numeric (or starts with a digit and contains only
147+ // valid port characters until a path separator), it's likely hostname:port, not a protocol.
148+ const looks_like_port = / ^ [ 0 - 9 ] / . test ( after_colon ) ;
147149
148- if ( url === false ) {
149- return false ;
150+ if ( looks_like_port ) {
151+ // This looks like hostname:port, not a protocol
152+ if ( options . require_protocol ) {
153+ return false ;
154+ }
155+ // Don't consume anything; let it be parsed as hostname:port
156+ } else {
157+ // This is definitely a protocol
158+ url = cleanUpProtocol ( potential_protocol ) ;
159+
160+ if ( url === false ) {
161+ return false ;
162+ }
150163 }
151164 }
152165 } else {
Original file line number Diff line number Diff line change @@ -488,6 +488,62 @@ describe('Validators', () => {
488488 } ) ;
489489 } ) ;
490490
491+ it ( 'should validate URLs without protocol' , ( ) => {
492+ test ( {
493+ validator : 'isURL' ,
494+ args : [ {
495+ require_tld : false ,
496+ require_valid_protocol : false ,
497+ } ] ,
498+ valid : [
499+ 'localhost' ,
500+ 'localhost:3000' ,
501+ 'service-name:8080' ,
502+ 'https://localhost' ,
503+ 'http://localhost:3000' ,
504+ 'http://service-name:8080' ,
505+ 'user:password@localhost' ,
506+ 'user:pass@service-name:8080' ,
507+ ] ,
508+ invalid : [ ] ,
509+ } ) ;
510+
511+ // Test with require_protocol: true - should reject hostnames with ports but no protocol
512+ test ( {
513+ validator : 'isURL' ,
514+ args : [ {
515+ require_tld : false ,
516+ require_protocol : true ,
517+ require_valid_protocol : false ,
518+ } ] ,
519+ valid : [
520+ 'http://localhost:3000' ,
521+ 'https://service-name:8080' ,
522+ 'custom://localhost' ,
523+ ] ,
524+ invalid : [
525+ 'localhost:3000' ,
526+ 'service-name:8080' ,
527+ 'user:password@localhost' ,
528+ ] ,
529+ } ) ;
530+
531+ // Test non-numeric patterns after colon (should be treated as protocols)
532+ test ( {
533+ validator : 'isURL' ,
534+ args : [ {
535+ require_tld : false ,
536+ require_valid_protocol : false ,
537+ protocols : [ 'custom' , 'myscheme' ] ,
538+ } ] ,
539+ valid : [
540+ 'custom:something' ,
541+ 'myscheme:data' ,
542+ ] ,
543+ invalid : [ ] ,
544+ } ) ;
545+ } ) ;
546+
491547 it ( 'should validate URLs with custom protocols' , ( ) => {
492548 test ( {
493549 validator : 'isURL' ,
You can’t perform that action at this time.
0 commit comments