From b849c828e3c05318809db3ddd2f83b1ddcbf5640 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Sat, 28 Aug 2021 11:12:03 +0200 Subject: [PATCH] fix: String.parseIdentifierIntoParts not working with unicode matrix.to links Some clients do not uri-encode the identifier for matrix.to links, so we must handle if we can't uri-decode them --- lib/src/utils/matrix_id_string_extension.dart | 27 +++++++++++++++---- test/matrix_id_string_extension_test.dart | 4 +++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/src/utils/matrix_id_string_extension.dart b/lib/src/utils/matrix_id_string_extension.dart index a92028a8..b526ba30 100644 --- a/lib/src/utils/matrix_id_string_extension.dart +++ b/lib/src/utils/matrix_id_string_extension.dart @@ -74,10 +74,20 @@ extension MatrixIdExtension on String { if (index == -1) { continue; } - final parameter = - Uri.decodeQueryComponent(parameterStr.substring(0, index)); - final value = - Uri.decodeQueryComponent(parameterStr.substring(index + 1)); + var parameter = parameterStr.substring(0, index); + try { + parameter = Uri.decodeQueryComponent(parameter); + } catch (_) { + // do nothing: the parameter wasn't url-encoded, and we already have the + // plaintext version in the `parameter` variable + } + var value = parameterStr.substring(index + 1); + try { + value = Uri.decodeQueryComponent(value); + } catch (_) { + // do nothing: the value wasn't url-encoded, and we already have the + // plaintext version in the `value` variable + } if (parameter == 'via') { via.add(value); } @@ -132,7 +142,14 @@ extension MatrixIdExtension on String { if (toLowerCase().startsWith(matrixToPrefix)) { // as we decode a component we may only call it on the url part *before* the "query" part final parts = substring(matrixToPrefix.length).split('?'); - s = Uri.decodeComponent(parts.removeAt(0)) + '?' + parts.join('?'); + var ident = parts.removeAt(0); + try { + ident = Uri.decodeComponent(ident); + } catch (_) { + // do nothing: the identifier wasn't url-encoded, and we already have the + // plaintext version in the `ident` variable + } + s = ident + '?' + parts.join('?'); } final match = RegExp(r'^([#!@+][^:]*:[^\/?]*)(?:\/(\$[^?]*))?(?:\?(.*))?$') .firstMatch(s); diff --git a/test/matrix_id_string_extension_test.dart b/test/matrix_id_string_extension_test.dart index 409a5f54..52a24592 100644 --- a/test/matrix_id_string_extension_test.dart +++ b/test/matrix_id_string_extension_test.dart @@ -75,6 +75,10 @@ void main() { expect(res.primaryIdentifier, '#alias:beep'); expect(res.secondaryIdentifier, null); expect(res.queryString, null); + res = 'https://matrix.to/#/#🦊:beep'.parseIdentifierIntoParts(); + expect(res.primaryIdentifier, '#🦊:beep'); + expect(res.secondaryIdentifier, null); + expect(res.queryString, null); res = 'https://matrix.to/#/%23alias%3abeep'.parseIdentifierIntoParts(); expect(res.primaryIdentifier, '#alias:beep'); expect(res.secondaryIdentifier, null);