]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fixed parseQueryString to handle empty values and plus signs
authorVincent Petry <pvince81@owncloud.com>
Tue, 28 Jan 2014 15:16:09 +0000 (16:16 +0100)
committerVincent Petry <pvince81@owncloud.com>
Tue, 1 Apr 2014 21:02:34 +0000 (23:02 +0200)
- now correctly parse query strings with '+' signs
- empty values are now parsed either as null or empty string
- added unit test for parseQueryString()

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

index 302b6b4d9faba8a990fdf6838304e7286a682a95..e907db2837e6b82f7c2808ab9cb247ee873b5eba 100644 (file)
@@ -371,6 +371,7 @@ var OC={
         */
        parseQueryString:function(queryString){
                var parts,
+                       pos,
                        components,
                        result = {},
                        key,
@@ -378,12 +379,25 @@ var OC={
                if (!queryString){
                        return null;
                }
-               if (queryString[0] === '?'){
-                       queryString = queryString.substr(1);
+               pos = queryString.indexOf('?');
+               if (pos >= 0){
+                       queryString = queryString.substr(pos + 1);
                }
-               parts = queryString.split('&');
+               parts = queryString.replace(/\+/g, '%20').split('&');
                for (var i = 0; i < parts.length; i++){
-                       components = parts[i].split('=');
+                       // split on first equal sign
+                       var part = parts[i]
+                       pos = part.indexOf('=');
+                       if (pos >= 0) {
+                               components = [
+                                       part.substr(0, pos),
+                                       part.substr(pos + 1)
+                               ]
+                       }
+                       else {
+                               // key only
+                               components = [part];
+                       }
                        if (!components.length){
                                continue;
                        }
@@ -391,8 +405,14 @@ var OC={
                        if (!key){
                                continue;
                        }
-                       value = components[1];
-                       result[key] = value && decodeURIComponent(value);
+                       // if equal sign was there, return string
+                       if (components.length > 1) {
+                               result[key] = decodeURIComponent(components[1]);
+                       }
+                       // no equal sign => null value
+                       else {
+                               result[key] = null;
+                       }
                }
                return result;
        },
index 57ea5be8be051599c9b91584bbe00d4c032e367b..94a397b789268277bbbc39a1a4d555df61fa018a 100644 (file)
@@ -268,7 +268,72 @@ describe('Core base tests', function() {
                        // still nothing
                        expect(counter).toEqual(0);
                });
-
+       });
+       describe('Parse query string', function() {
+               it('Parses query string from full URL', function() {
+                       var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x');
+                       expect(query).toEqual({q: 'a', b: 'x'});
+               });
+               it('Parses query string from query part alone', function() {
+                       var query = OC.parseQueryString('q=a&b=x');
+                       expect(query).toEqual({q: 'a', b: 'x'});
+               });
+               it('Returns null hash when empty query', function() {
+                       var query = OC.parseQueryString('');
+                       expect(query).toEqual(null);
+               });
+               it('Returns empty hash when empty query with question mark', function() {
+                       var query = OC.parseQueryString('?');
+                       expect(query).toEqual({});
+               });
+               it('Decodes regular query strings', function() {
+                       var query = OC.parseQueryString('a=abc&b=def');
+                       expect(query).toEqual({
+                               a: 'abc',
+                               b: 'def'
+                       });
+               });
+               it('Ignores empty parts', function() {
+                       var query = OC.parseQueryString('&q=a&&b=x&');
+                       expect(query).toEqual({q: 'a', b: 'x'});
+               });
+               it('Ignores lone equal signs', function() {
+                       var query = OC.parseQueryString('&q=a&=&b=x&');
+                       expect(query).toEqual({q: 'a', b: 'x'});
+               });
+               it('Includes extra equal signs in value', function() {
+                       var query = OC.parseQueryString('u=a=x&q=a=b');
+                       expect(query).toEqual({u: 'a=x', q: 'a=b'});
+               });
+               it('Decodes plus as space', function() {
+                       var query = OC.parseQueryString('space+key=space+value');
+                       expect(query).toEqual({'space key': 'space value'});
+               });
+               it('Decodes special characters', function() {
+                       var query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97');
+                       expect(query).toEqual({unicode: '汉字'});
+                       query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand');
+                       expect(query).toEqual({
+                               b: 'spaace value',
+                               'space key': 'normalvalue',
+                               'slash/this': 'amp&ersand'
+                       });
+               });
+               it('Decodes empty values', function() {
+                       var query = OC.parseQueryString('keywithemptystring=&keywithnostring');
+                       expect(query).toEqual({
+                               'keywithemptystring': '',
+                               'keywithnostring': null
+                       });
+               });
+               it('Does not interpret data types', function() {
+                       var query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123');
+                       expect(query).toEqual({
+                               'booleanfalse': 'false',
+                               'booleantrue': 'true',
+                               'number': '123'
+                       });
+               });
        });
        describe('Generate Url', function() {
                it('returns absolute urls', function() {