Prototype String.toQueryParams() weirdness

I just came across this while using Prototype:

  1. "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:

  1. var key = decodeURIComponent(pair.shift());
  2. if (value != undefined) value = decodeURIComponent(value);
  3.  
  4. to
  5.  
  6. var key = decodeURIComponent(escape(pair.shift()));
  7. 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:

  1. var key = unescape(decodeURIComponent(escape(pair.shift())));
  2. 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:

  1. 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”


  • No Comments

Leave a Reply