]> source.dussan.org Git - nextcloud-server.git/commitdiff
Encode parameters in `OC.generateUrl` by itself
authorLukas Reschke <lukas@owncloud.com>
Mon, 16 Feb 2015 19:07:45 +0000 (20:07 +0100)
committerLukas Reschke <lukas@owncloud.com>
Tue, 17 Feb 2015 13:41:06 +0000 (14:41 +0100)
This function is often used in a wrong and potential dangerous way... Thus we should escape the URL per default and offer developers to disable the automatic escaping via an option parameter if they really want that behaviour.

Might break some things, however, those things are then easy to fix and we really have a ton of bugs caused by this...

Fixes https://github.com/owncloud/core/issues/14228

core/js/js.js
core/js/tests/specs/coreSpec.js

index 7ff010eca0a285dbc696ef7d690c985daebcab09..a43df4014df398ee2b8484b048cea333ddd9637b 100644 (file)
@@ -116,17 +116,30 @@ var OC={
 
        /**
         * Generates the absolute url for the given relative url, which can contain parameters.
+        * Parameters will be URL encoded automatically.
         * @param {string} url
         * @param [params] params
+        * @param [options] options
+        * @param {bool} [options.escape=true] enable/disable auto escape of placeholders (by default enabled)
         * @return {string} Absolute URL for the given relative URL
         */
-       generateUrl: function(url, params) {
+       generateUrl: function(url, params, options) {
+               var defaultOptions = {
+                               escape: true
+                       },
+                       allOptions = options || {};
+               _.defaults(allOptions, defaultOptions);
+
                var _build = function (text, vars) {
                        var vars = vars || [];
                        return text.replace(/{([^{}]*)}/g,
                                function (a, b) {
-                                       var r = vars[b];
-                                       return typeof r === 'string' || typeof r === 'number' ? r : a;
+                                       var r = (vars[b]);
+                                       if(allOptions.escape) {
+                                               return (typeof r === 'string' || typeof r === 'number') ? encodeURIComponent(r) : encodeURIComponent(a);
+                                       } else {
+                                               return (typeof r === 'string' || typeof r === 'number') ? r : a;
+                                       }
                                }
                        );
                };
index 159c374366262387c439dfa8b2bf71c8bb579b13..7d06ac2e7df9c94a49f548af0a62b705a7c008f8 100644 (file)
@@ -393,11 +393,20 @@ describe('Core base tests', function() {
                        expect(OC.generateUrl('heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
                        expect(OC.generateUrl('/heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat');
                });
-               it('substitutes parameters', function() {
-                       expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt');
+               it('substitutes parameters which are escaped by default', function() {
+                       expect(OC.generateUrl('apps/files/download/{file}', {file: '<">ImAnUnescapedString/!'})).toEqual(OC.webroot + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!');
+               });
+               it('substitutes parameters which can also be unescaped via option flag', function() {
+                       expect(OC.generateUrl('apps/files/download/{file}', {file: 'subfolder/Welcome.txt'}, {escape: false})).toEqual(OC.webroot + '/index.php/apps/files/download/subfolder/Welcome.txt');
+               });
+               it('substitutes multiple parameters which are escaped by default', function() {
+                       expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: '<">ImAnUnescapedString/!', id: 5})).toEqual(OC.webroot + '/index.php/apps/files/download/%3C%22%3EImAnUnescapedString%2F!/5');
+               });
+               it('substitutes multiple parameters which can also be unescaped via option flag', function() {
+                       expect(OC.generateUrl('apps/files/download/{file}/{id}', {file: 'subfolder/Welcome.txt', id: 5}, {escape: false})).toEqual(OC.webroot + '/index.php/apps/files/download/subfolder/Welcome.txt/5');
                });
                it('doesnt error out with no params provided', function  () {
-                       expect(OC.generateUrl('apps/files/download{file}')).toEqual(OC.webroot + '/index.php/apps/files/download{file}');
+                       expect(OC.generateUrl('apps/files/download{file}')).toEqual(OC.webroot + '/index.php/apps/files/download%7Bfile%7D');
                });
        });
        describe('Main menu mobile toggle', function() {