fix(sources): read a bracketed key as parameters unless it is JSON

The name check returned early for any value starting with `{` or `[`,
so `[password]=…` (not JSON) skipped the parameter check and its
password stayed in the name. It now returns early only when the value
parses as a JSON object or array.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-10-14 01:14:45 +02:00
1 parent a06dd988be
commit bfce3bd04e
2 files changed
+14 -2

No files matched your search

@@ -130,6 +130,15 @@ describe('sourceDisplayName', () => {
).toBe('Mine');
});
it('reads a bracketed key that only starts like JSON as parameters', () => {
const url = `https://proxy.test/list?config=${encodeURIComponent(
'[password]=hunter2'
)}`;
expect(sourceDisplayName({ title: 'Mine hunter2', url })).toBe(
'proxy.test'
);
});
it('keeps a name that only shares a letter with a decoded password', () => {
// `%2542` is the password as written; decoded it is just `B`.
const url = 'https://host.test/list?password=%2542';
@@ -108,8 +108,11 @@ function collectUrlSecrets(
if (value === null) {
return;
}
if (/^\s*[{[]/.test(value)) {
visitJson(parseJson(value), 0);
// Only real JSON: `[password]=…` starts like it but is a parameter
// list, read below.
const json = /^\s*[{[]/.test(value) ? parseJson(value) : null;
if (json !== null && typeof json === 'object') {
visitJson(json, 0);
return;
}
const nested = ABSOLUTE_URL.test(value.trim()) ? parseUrl(value) : null;