I just came across this while using Prototype:
-
"section=blo%g&id=45".toQueryParams();
To save you the trouble of running it yourself, I’ll tell you what happens – the unescaped percent symbol causes a URI malformed error to be thrown.
Very odd. The Prototype documentation for toQueryParams says:
Parses a URI-like query string and returns an object composed of parameter/value pairs.
Since it’s a URI-like query string and not an actual query string (by which I mean one that’s been through the browser address bar and as such subject to whatever text munging the browser does), my example above should be a legal use case.
After a little digging around in prototype.js, it seems that the problem is caused by the JavaScript function decodeURIComponent() not enjoying being given a string that contains an unescaped percent symbol. Usually percent symbols are used in conjunction with a number to represent a non-alphanumeric character in a URL – %20 for space, etc, but in the above it’s a literal percent symbol.
My first attempt to fix it changed lines 98 and 100 of string.js in the Prototype source to use the built in escape function:
-
var key = decodeURIComponent(pair.shift());
-
…
-
if (value != undefined) value = decodeURIComponent(value);
-
-
to
-
-
var key = decodeURIComponent(escape(pair.shift()));
-
…
-
if (value != undefined) value = decodeURIComponent(escape(value));
This worked for my use case but caused Prototype to fail a different unit test. Changing them to the following worked out okay:
-
var key = unescape(decodeURIComponent(escape(pair.shift())));
-
…
-
if (value != undefined) value = unescape(decodeURIComponent(escape(value)));
Granted the unescape(…(escape(…)) is a little clumsy, but it seems to get the job done.
Adding the following unit test to string.html allows to test for the above:
-
this.assertHashEqual({‘key1′: ‘va%lue1′}, ‘key1=va%lue1′.toQueryParams(), ‘rogue percent symbol test’);
I’ve created some test pages which demonstrate the problem.
There is also a patch file available. Apply it to /src/string.js in your Prototype source tree.
Update
I’ve also filed a bug.
Popularity: 36% [?]
0 Responses to “Prototype String.toQueryParams() weirdness”