diff options
-rw-r--r-- | js/lib/elgglib.js | 33 | ||||
-rw-r--r-- | js/tests/ElggLibTest.js | 32 |
2 files changed, 57 insertions, 8 deletions
diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js index d963a62be..caef4d0f1 100644 --- a/js/lib/elgglib.js +++ b/js/lib/elgglib.js @@ -250,8 +250,35 @@ elgg.normalize_url = function(url) { url = url || ''; elgg.assertTypeOf('string', url); - // jslint complains if you use /regexp/ shorthand here... ?!?! - if ((new RegExp("^(https?:)?//", "i")).test(url)) { + validated = (function(url){ + url = elgg.parse_url(url); + if(url.scheme){ + url.scheme = url.scheme.toLowerCase(); + } + if(url.scheme == 'http' || url.scheme == 'https') { + if(!url.host) { + return false; + } + /* hostname labels may contain only alphanumeric characters, dots and hypens. */ + if(!(new RegExp("^([a-zA-Z0-9][a-zA-Z0-9\\-\\.]*)$", "i")).test(url.host) || url.host.charAt(-1) == '.'){ + return false; + } + } + /* some schemas allow the host to be empty */ + if (!url.scheme || !url.host && url.scheme != 'mailto' && url.scheme != 'news' && url.scheme != 'file') { + return false; + } + return true; + })(url); + + // all normal URLs including mailto: + if (validated) { + return url; + } + + // '//example.com' (Shortcut for protocol.) + // '?query=test', #target + else if ((new RegExp("^(\\#|\\?|//)", "i")).test(url)) { return url; } @@ -569,4 +596,4 @@ elgg.initWhenReady = function() { elgg.trigger_hook('init', 'system'); elgg.trigger_hook('ready', 'system'); } -};
\ No newline at end of file +}; diff --git a/js/tests/ElggLibTest.js b/js/tests/ElggLibTest.js index dd0267c5c..688a1016c 100644 --- a/js/tests/ElggLibTest.js +++ b/js/tests/ElggLibTest.js @@ -73,12 +73,34 @@ ElggLibTest.prototype.testNormalizeUrl = function() { [ ['', elgg.config.wwwroot], - ['test', elgg.config.wwwroot + 'test'], - ['http://google.com', 'http://google.com'], + ['http://example.com', 'http://example.com'], + ['https://example.com', 'https://example.com'], + ['http://example-time.com', 'http://example-time.com'], ['//example.com', '//example.com'], - ['/page', elgg.config.wwwroot + 'page'], - ['mod/plugin/index.php', elgg.config.wwwroot + 'mod/plugin/index.php'], + + ['ftp://example.com/file', 'ftp://example.com/file', + ['mailto:brett@elgg.org', 'mailto:brett@elgg.org', + ['javascript:alert("test")', 'javascript:alert("test")', + ['app://endpoint', 'app://endpoint', + + ['example.com', 'http://example.com', + ['example.com/subpage', 'http://example.com/subpage', + + ['page/handler', elgg.config.wwwroot + 'page/handler', + ['page/handler?p=v&p2=v2', elgg.config.wwwroot + 'page/handler?p=v&p2=v2', + ['mod/plugin/file.php', elgg.config.wwwroot + 'mod/plugin/file.php', + ['mod/plugin/file.php?p=v&p2=v2', elgg.config.wwwroot + 'mod/plugin/file.php?p=v&p2=v2', + ['rootfile.php', elgg.config.wwwroot + 'rootfile.php', + ['rootfile.php?p=v&p2=v2', elgg.config.wwwroot + 'rootfile.php?p=v&p2=v2', + + ['/page/handler', elgg.config.wwwroot + 'page/handler', + ['/page/handler?p=v&p2=v2', elgg.config.wwwroot + 'page/handler?p=v&p2=v2', + ['/mod/plugin/file.php', elgg.config.wwwroot + 'mod/plugin/file.php', + ['/mod/plugin/file.php?p=v&p2=v2', elgg.config.wwwroot + 'mod/plugin/file.php?p=v&p2=v2', + ['/rootfile.php', elgg.config.wwwroot + 'rootfile.php', + ['/rootfile.php?p=v&p2=v2', elgg.config.wwwroot + 'rootfile.php?p=v&p2=v2', + ].forEach(function(args) { assertEquals(args[1], elgg.normalize_url(args[0])); }); -};
\ No newline at end of file +}; |