diff --git a/packages/snap-url-manager/src/Translators/Url/UrlTranslator.test.ts b/packages/snap-url-manager/src/Translators/Url/UrlTranslator.test.ts index 081b40729..4a215aa23 100644 --- a/packages/snap-url-manager/src/Translators/Url/UrlTranslator.test.ts +++ b/packages/snap-url-manager/src/Translators/Url/UrlTranslator.test.ts @@ -16,6 +16,27 @@ describe('UrlTranslator', () => { expect(urlTranslator.serialize({})).toBe('/'); }); + it('gracefully fails with malformed uri in hash', () => { + const url = 'http://example.com#/valid:true/utm_campaign:BFCM%2020%OFF%20Perfumes%20TEST%20(28.11.24)%20(clone)/valid2:truueee'; + const urlTranslator = new UrlTranslator(); + // @ts-ignore + expect(urlTranslator.parseHashString(url)).toStrictEqual([ + { key: ['valid'], type: 'hash', value: 'true' }, + { key: ['valid2'], type: 'hash', value: 'truueee' }, + ]); + }); + + it('gracefully fails with malformed uri in query', () => { + const url = 'http://example.com?valid=true&utm_campaign=BFCM:%2020%OFF%20Perfumes%20TEST%20(28.11.24)%20(clone)&valid2=truueee'; + const urlTranslator = new UrlTranslator(); + + // @ts-ignore + expect(urlTranslator.parseQueryString(url)).toStrictEqual([ + { key: ['valid'], type: 'query', value: 'true' }, + { key: ['valid2'], type: 'query', value: 'truueee' }, + ]); + }); + it('prepends urlRoot when provided', () => { const url = 'http://example.com?bar=baz'; class customTranslator extends UrlTranslator { diff --git a/packages/snap-url-manager/src/Translators/Url/UrlTranslator.ts b/packages/snap-url-manager/src/Translators/Url/UrlTranslator.ts index 778404948..999faaff1 100644 --- a/packages/snap-url-manager/src/Translators/Url/UrlTranslator.ts +++ b/packages/snap-url-manager/src/Translators/Url/UrlTranslator.ts @@ -148,27 +148,37 @@ export class UrlTranslator implements Translator { .split('&') .filter((v) => v) .map((kvPair) => { - const [key, value] = kvPair.split('=').map((v) => decodeURIComponent(v.replace(/\+/g, ' '))); - return { key: key.split('.'), value, type: ParamLocationType.query }; + try { + const [key, value] = kvPair.split('=').map((v) => decodeURIComponent(v.replace(/\+/g, ' '))); + return { key: key.split('.'), value, type: ParamLocationType.query }; + } catch (err) { + console.warn('Snap UrlTranslator: URI malformed - ignoring parameter', kvPair); + return { key: ['ss__delete'], value: 'ss__delete', type: ParamLocationType.query }; + } }) .filter((param) => { - // remove core fields that do not contain a value + // remove core fields that do not contain a value or had malformed data const isCoreField = this.reverseMapping[param.key[0]]; - return !isCoreField || (isCoreField && param.value); + return param.value !== 'ss__delete' ? !isCoreField || (isCoreField && param.value) : ''; }); } protected parseHashString(hashString: string): Array { const params: Array = []; - const justHashString = hashString.split('#').join('/') || ''; + const justHashString = hashString.split('#').pop() || ''; justHashString .split('/') .filter((v) => v) .map((hashEntries) => { - return hashEntries.split(':').map((v) => decodeHashComponent(v)); + try { + return hashEntries.split(':').map((v) => decodeHashComponent(v)); + } catch (err) { + console.warn('Snap UrlTranslator: URI malformed - ignoring parameter', hashEntries); + return []; + } }) .filter((param) => { - // remove core fields that do not contain a value + // remove core fields that do not contain a value or had malformed data const [key, value] = param; const isCoreField = this.reverseMapping[key]; return !isCoreField || (isCoreField && value);