Skip to content

Commit e2a569c

Browse files
committed
add safe decodeURIComponent helper; add changeset entry
1 parent 0924abb commit e2a569c

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modelcontextprotocol/core': patch
3+
---
4+
5+
Fix `UriTemplate.match()` to correctly handle optional, out-of-order, and URL-encoded query parameters. Previously, query parameters had to appear in the exact order specified in the template and omitted parameters would cause match failures. Omitted query parameters are now
6+
absent from the result (rather than set to `''`), so callers can use `vars.param ?? defaultValue`.

src/shared/uriTemplate.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ const MAX_VARIABLE_LENGTH = 1000000; // 1MB
77
const MAX_TEMPLATE_EXPRESSIONS = 10000;
88
const MAX_REGEX_LENGTH = 1000000; // 1MB
99

10+
function safeDecode(s: string): string {
11+
try {
12+
return decodeURIComponent(s);
13+
} catch {
14+
return s;
15+
}
16+
}
17+
1018
export class UriTemplate {
1119
/**
1220
* Returns true if the given string contains any URI template expressions.
@@ -295,8 +303,8 @@ export class UriTemplate {
295303
for (const pair of queryPart.split('&')) {
296304
const equalIndex = pair.indexOf('=');
297305
if (equalIndex !== -1) {
298-
const key = decodeURIComponent(pair.slice(0, equalIndex));
299-
const value = decodeURIComponent(pair.slice(equalIndex + 1));
306+
const key = safeDecode(pair.slice(0, equalIndex));
307+
const value = safeDecode(pair.slice(equalIndex + 1));
300308
queryParams.set(key, value);
301309
}
302310
}

test/shared/uriTemplate.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ describe('UriTemplate', () => {
232232
version: 'v1',
233233
resource: 'users',
234234
apiKey: 'testkey',
235-
q: 'user',
235+
q: 'user'
236236
});
237237
expect(template.variableNames).toEqual(['version', 'resource', 'apiKey', 'q', 'p', 'sort']);
238238
});

0 commit comments

Comments
 (0)