From 2bbd78f1d66dcd911736161f60b5108d98caf061 Mon Sep 17 00:00:00 2001 From: Andrew Austin Date: Fri, 20 Mar 2015 00:30:52 -0400 Subject: [PATCH] fix(ngInput): change URL_REGEXP to better match RFC3987 The URL_REGEXP in use to perform validation in ngInput is too restrictive and fails to follow RFC3987. In particular, it only accepts ftp, http, and https scheme components and rejects perfectly valid schemes such as "file", "mailto", "chrome-extension", etc. The regex also requires the scheme to be followed by two "/" but the RFC says 0 to n are acceptable. This change fixes both of these issues to better align to the standard. Closes #11341 --- src/ng/directive/input.js | 3 ++- test/ng/directive/inputSpec.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index e9b781bcf320..50c07f2775da 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -11,7 +11,8 @@ // Regex code is obtained from SO: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231 var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/; -var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; +// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) +var URL_REGEXP = /^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/]*)?$/; var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index becc6b72aa49..c0afdea7813e 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2387,8 +2387,18 @@ describe('input', function() { describe('URL_REGEXP', function() { /* global URL_REGEXP: false */ it('should validate url', function() { + // See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987) expect(URL_REGEXP.test('http://server:123/path')).toBe(true); + expect(URL_REGEXP.test('https://server:123/path')).toBe(true); + expect(URL_REGEXP.test('file:///home/user')).toBe(true); + expect(URL_REGEXP.test('mailto:user@example.com?subject=Foo')).toBe(true); + expect(URL_REGEXP.test('r2-d2.c3-p0://localhost/foo')).toBe(true); + expect(URL_REGEXP.test('abc:/foo')).toBe(true); + expect(URL_REGEXP.test('http:')).toBe(false); expect(URL_REGEXP.test('a@B.c')).toBe(false); + expect(URL_REGEXP.test('a_B.c')).toBe(false); + expect(URL_REGEXP.test('0scheme://example.com')).toBe(false); + expect(URL_REGEXP.test('http://example.com:9999/~~``')).toBe(false); }); }); });