Skip to content

Commit 85cbeb0

Browse files
committed
internal_link: Escape single quotes in narrow links.
Add single quote (') to the list of characters that are dot-encoded in narrow link URLs. Some software with URL detection heuristics may interpret a single quote as the end of a URL, causing links to break. This aligns with the behavior needed for consistent URL detection across different platforms and messaging clients. Fixes #2105
1 parent 3340749 commit 85cbeb0

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

lib/model/internal_link.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ const _hashReplacements = {
1414
"(": ".28",
1515
")": ".29",
1616
".": ".2E",
17+
"'": ".27", // Escape single quotes to prevent URL detection issues
1718
};
1819

19-
final _encodeHashComponentRegex = RegExp(r'[%().]');
20+
final _encodeHashComponentRegex = RegExp("[%()'.]");
2021

2122
// Corresponds to encodeHashComponent in Zulip web;
2223
// see web/shared/src/internal_url.ts.

test/model/internal_link_test.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ void main() {
9595
'#narrow/channel/377-translation.2Fzh_tw/topic/.E7.BF.BB.E8.AD.AF.20.22stream.22');
9696
checkNarrow(streamId: 42, name: 'Outreachy 2016-2017', topic: '2017-18 Stream?', nearMessageId: 302690,
9797
'#narrow/channel/42-Outreachy-2016-2017/topic/2017-18.20Stream.3F/near/302690');
98+
99+
// Test single quote escaping (fixes #2105)
100+
checkNarrow(streamId: 500, name: "it's-a-test",
101+
'#narrow/channel/500-it.27s-a-test');
102+
checkNarrow(streamId: 501, name: 'general', topic: "What's new?",
103+
'#narrow/channel/501-general/topic/What.27s.20new.3F');
98104
});
99105

100106
test('legacy including "stream" operator', () {
@@ -408,7 +414,8 @@ void main() {
408414
['some_text', 'some_text'],
409415
['some.20text', 'some text'],
410416
['some.2Etext', 'some.text'],
411-
417+
['what.27s.20new', "what's new"], // single quote encoding (fixes #2105)
418+
['what.27s.20up', "what's up"], // new test case for single quote
412419
['na.C3.AFvet.C3.A9', 'naïveté'],
413420
['.C2.AF.5C_(.E3.83.84)_.2F.C2.AF', r'¯\_(ツ)_/¯'],
414421
];

0 commit comments

Comments
 (0)