Skip to content

Commit 22a3016

Browse files
committed
Fix regression with escaped brackets
1 parent 2a1ad62 commit 22a3016

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,26 @@ function pathtoRegexp(path, keys, options) {
9191
var len = keys.length
9292

9393
while (len-- > keysOffset && keys[len].offset > index) {
94-
keys[len].offset += 3;
94+
keys[len].offset += 3; // Replacement length minus asterisk length.
9595
}
9696

9797
return '(.*)';
9898
});
9999

100100
// This is a workaround for handling unnamed matching groups.
101101
while (m = MATCHING_GROUP_REGEXP.exec(path)) {
102+
var escapeCount = 0;
103+
var index = m.index;
104+
105+
while (path.charAt(--index) === '\\') {
106+
escapeCount++;
107+
}
108+
109+
// It's possible to escape the bracket.
110+
if (escapeCount % 2 === 1) {
111+
continue;
112+
}
113+
102114
if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
103115
keys.splice(keysOffset + i, 0, {
104116
name: name++, // Unnamed matching groups must be consistently linear.

test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,4 +764,44 @@ describe('path-to-regexp', function () {
764764
assert.equal(m[3], 'path');
765765
});
766766
});
767+
768+
describe('regressions', function () {
769+
it('should work with strongloop/expressjs.com#417', function () {
770+
var params = [];
771+
var re = pathToRegExp('/:foo\\(:bar?\\)', params);
772+
var m;
773+
774+
assert.equal(params.length, 2);
775+
assert.equal(params[0].name, 'foo');
776+
assert.equal(params[0].optional, false);
777+
assert.equal(params[1].name, 'bar');
778+
assert.equal(params[1].optional, true);
779+
780+
m = re.exec('/hello(world)');
781+
782+
assert.equal(m.length, 3);
783+
assert.equal(m[0], '/hello(world)');
784+
assert.equal(m[1], 'hello');
785+
assert.equal(m[2], 'world');
786+
});
787+
788+
it('should handle an escaped escape character', function () {
789+
var params = [];
790+
var re = pathToRegExp('/:foo\\\\(world)', params);
791+
var m;
792+
793+
assert.equal(params.length, 2);
794+
assert.equal(params[0].name, 'foo');
795+
assert.equal(params[0].optional, false);
796+
assert.equal(params[1].name, 0);
797+
assert.equal(params[1].optional, false);
798+
799+
m = re.exec('/hello\\world');
800+
801+
assert.equal(m.length, 3);
802+
assert.equal(m[0], '/hello\\world');
803+
assert.equal(m[1], 'hello');
804+
assert.equal(m[2], 'world');
805+
});
806+
});
767807
});

0 commit comments

Comments
 (0)