Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions backbone.js
Original file line number Diff line number Diff line change
Expand Up @@ -1764,13 +1764,21 @@

// Given a route, and a URL fragment that it matches, return the array of
// extracted decoded parameters. Empty or unmatched parameters will be
// treated as `null` to normalize cross-browser behavior.
// treated as `null` to normalize cross-browser behavior. A malformed
// percent-encoding (e.g. `%foo`) would otherwise throw a `URIError` and
// crash the router (#3440); such parameters fall back to the raw value.
_extractParameters: function(route, fragment) {
var params = route.exec(fragment).slice(1);
return _.map(params, function(param, i) {
// Don't decode the search params.
if (i === params.length - 1) return param || null;
return param ? decodeURIComponent(param) : null;
if (!param) return null;
try {
return decodeURIComponent(param);
} catch (e) {
if (e instanceof URIError) return param;
throw e;
}
});
}

Expand Down
13 changes: 13 additions & 0 deletions test/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,19 @@
Backbone.history.start({pushState: true});
});

QUnit.test('#3440 - Malformed param does not throw URIError.', function(assert) {
assert.expect(2);
var myRouter = new Backbone.Router;
var route = /^search\/([^\/]+)$/;
var params;
// Should not throw on malformed percent-encoding.
params = myRouter._extractParameters(route, 'search/malformed%query');
assert.ok(params, 'extract did not throw');
// The malformed value falls back to the raw, undecoded string so the
// route can still match and the application can handle it.
assert.strictEqual(params[0], 'malformed%query');
});

QUnit.test('Router#execute receives callback, args, name.', function(assert) {
assert.expect(3);
location.replace('http://example.com#foo/123/bar?x=y');
Expand Down
Loading