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: 96% [?]
April 17th, 2008 at 3:46 am
I have the same problem and i was making my brain ache too!! DAMN!
April 17th, 2008 at 4:11 am
no it didnt worked
April 17th, 2008 at 9:52 am
Daniel - what didn’t work?
April 18th, 2008 at 6:43 am
why do you still bother using Prototype? it’s a real PITA from the code, implementation and to the documentation itself!
April 18th, 2008 at 7:38 am
Mainly because of work. When the project began, Prototype best fitted our needs and we’re too far along to consider re-implementing. Not until version 2 at any rate.
Granted at one point the documentation (or lack thereof) was shockingly bad, but nowadays we are spoilt.
I’m not sure why you have a problem with the implementation as it’s a library like any other - code to the API and forget about it. When it doesn’t work as expected, file a bug.
As for the code, again I’m not sure what you mean. Could the problem you have be that it doesn’t look like Java?
June 25th, 2008 at 5:35 pm
I applied the patch and it seemed to be working, but if you throw it an ASCII Hex code/value, like %50, it fails. Or not fail, but it converts it to its keyboard character equivalent, %50 = ‘P’
June 26th, 2008 at 6:09 pm
Nevermind the above comment we found the backend was doing the conversion.