From a26c1a109a02d08921a5173a97708db1b6e1098a 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..29292d824aff 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); }); }); });