aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/lib/elgglib.js33
-rw-r--r--js/tests/ElggLibTest.js32
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
+};