authorgravatar for saiansh2525@gmail.comYash Singh <saiansh2525@gmail.com> 2026-09-26 03:15:41-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-26 03:15:41-05:00
logfe6388f01d5ae9f9db43079c6f5b2c31869067ca
tree4abc7148b051700e577aba921ac032dafe4826a7
parentdef34c28b8841002bb97a3238b82ac758cbdaa0f
signature Signed by PGP key B5690EEEBB952194

fix(mobile): link URLs with ports and single-label hosts (#13795)


3 files changed, 78 insertions(+), 5 deletions(-)

patches/react-native-nitro-markdown@0.5.8.patch created+70
......@@ -0,0 +1,70 @@
1diff --git a/cpp/md4c/md4c.c b/cpp/md4c/md4c.c
2--- a/cpp/md4c/md4c.c
3+++ b/cpp/md4c/md4c.c
4@@ -3908,10 +3908,10 @@
5 int min_components;
6 const MD_CHAR optional_end_char;
7 } URL_MAP[] = {
8- { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */
9- { _T('/'), _T('/'), _T("/.-_"), 0, _T('/') }, /* path */
10- { _T('?'), _T('&'), _T("&.-+_=()"), 1, _T('\0') }, /* query */
11- { _T('#'), _T('\0'), _T(".-+_") , 1, _T('\0') } /* fragment */
12+ { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */
13+ { _T('/'), _T('/'), _T("/.-_():~%+@&!,;"), 0, _T('/') }, /* path */
14+ { _T('?'), _T('&'), _T("&.-+_=().:!~%,;@"), 1, _T('\0') }, /* query */
15+ { _T('#'), _T('\0'), _T(".-+_:%~") , 1, _T('\0') } /* fragment */
16 };
17
18 MD_MARK* opener = &ctx->marks[mark_index];
19@@ -3981,8 +3981,11 @@
20 } else if(end < line_end &&
21 ISANYOF(end, URL_MAP[i].allowed_nonalnum_chars) &&
22 md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor) == NULL &&
23- ((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) &&
24- ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')')))
25+ /* Scheme URLs keep '...' and ':' in the path and query.
26+ * Host, e-mail, and www labels stay flanked by alphanumerics. */
27+ ((opener->ch == _T(':') && i > 0) ||
28+ (((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) &&
29+ ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')')))))
30 {
31 if(CH(end) == URL_MAP[i].delim_char)
32 n_components++;
33@@ -4006,16 +4009,35 @@
34 CH(end) == URL_MAP[i].optional_end_char)
35 end++;
36
37- if(n_components < URL_MAP[i].min_components || n_open_brackets != 0)
38+ /* Scheme autolinks allow one host label, so localhost and devbox link.
39+ * E-mail and www autolinks still require a dotted host. */
40+ if(n_components < (i == 0 && opener->ch == ':' ? 1 : URL_MAP[i].min_components) ||
41+ n_open_brackets != 0)
42 return;
43
44+ /* Optional port on a scheme autolink: ':' followed by digits. */
45+ if(i == 0 && opener->ch == ':' && end + 1 < line_end &&
46+ CH(end) == _T(':') && ISDIGIT(end + 1)) {
47+ end++;
48+ while(end < line_end && ISDIGIT(end))
49+ end++;
50+ }
51+
52 if(opener->ch == '@') /* E-mail autolinks wants only the host. */
53 break;
54+ }
55+
56+ /* GFM leaves a trailing run of punctuation outside the link, including
57+ * the sentence dots in "https://example.com/a...". */
58+ if(opener->ch == _T(':')) {
59+ while(end > opener->end && ISANYOF(end - 1, _T("?!.,:*_~")))
60+ end--;
61 }
62
63 /* Verify there's line boundary, whitespace, allowed punctuation or
64 * resolved emphasis mark just after the suspected autolink. */
65- if(end == line_end || ISUNICODEWHITESPACE(end) || ISANYOF(end, _T(")}].!?,;"))) {
66+ if(end == line_end || ISUNICODEWHITESPACE(end) ||
67+ ISANYOF(end, opener->ch == _T(':') ? _T(")}].!?,;:*_~'\"`<>") : _T(")}].!?,;"))) {
68 right_boundary_ok = TRUE;
69 } else {
70 MD_MARK* right_mark;
pnpm-lock.yaml+6-5
......@@ -108,6 +108,7 @@ patchedDependencies:
108108 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6
109109 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2
110110 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787
111 react-native-nitro-markdown@0.5.8: 7f5d2a8c357746316f67c9600034abbe71166ec766df27619a157f40b2c5a23c
111112 react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675
112113 react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d
113114 react-native-screens@4.26.2: 595114f3f9ce8b9f0d99d1aafe5c12c997b7d75ca9add31d46cbedbfe347b8e0
......@@ -298,7 +299,7 @@ importers:
298299 version: link:../../packages/contracts
299300 '@t3tools/mobile-markdown-text':
300301 specifier: file:./modules/t3-markdown-text
301 version: file:apps/mobile/modules/t3-markdown-text(6f0a94b6f541bbd4be3f343e27991996)
302 version: file:apps/mobile/modules/t3-markdown-text(54829604106ac55999e32558f817d201)
302303 '@t3tools/mobile-review-diff-native':
303304 specifier: file:./modules/t3-review-diff
304305 version: file:apps/mobile/modules/t3-review-diff
......@@ -445,7 +446,7 @@ importers:
445446 version: 1.21.13(patch_hash=6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787)(react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
446447 react-native-nitro-markdown:
447448 specifier: ^0.5.0
448 version: 0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
449 version: 0.5.8(patch_hash=7f5d2a8c357746316f67c9600034abbe71166ec766df27619a157f40b2c5a23c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
449450 react-native-nitro-modules:
450451 specifier: 0.35.9
451452 version: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
......@@ -15082,7 +15083,7 @@ snapshots:
1508215083 dependencies:
1508315084 defer-to-connect: 2.0.1
1508415085
15085 '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(6f0a94b6f541bbd4be3f343e27991996)':
15086 '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(54829604106ac55999e32558f817d201)':
1508615087 dependencies:
1508715088 '@t3tools/client-runtime': link:packages/client-runtime
1508815089 '@t3tools/shared': link:packages/shared
......@@ -15093,7 +15094,7 @@ snapshots:
1509315094 expo-symbols: 57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
1509415095 react: 19.2.3
1509515096 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)
15096 react-native-nitro-markdown: 0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
15097 react-native-nitro-markdown: 0.5.8(patch_hash=7f5d2a8c357746316f67c9600034abbe71166ec766df27619a157f40b2c5a23c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
1509715098
1509815099 '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': {}
1509915100
......@@ -20677,7 +20678,7 @@ snapshots:
2067720678 react-native-is-edge-to-edge: 1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
2067820679 react-native-reanimated: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
2067920680
20680 react-native-nitro-markdown@0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3):
20681 react-native-nitro-markdown@0.5.8(patch_hash=7f5d2a8c357746316f67c9600034abbe71166ec766df27619a157f40b2c5a23c)(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3):
2068120682 dependencies:
2068220683 react: 19.2.3
2068320684 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)
pnpm-workspace.yaml+2
......@@ -197,6 +197,8 @@ patchedDependencies:
197197 react-native-gesture-handler@2.32.0: patches/react-native-gesture-handler@2.32.0.patch
198198 react-native-keyboard-controller@1.21.13: patches/react-native-keyboard-controller@1.21.13.patch
199199 react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch
200 # Link http(s) URLs with a port or a single-label host. md4c otherwise requires a dotted host and stops at ':'.
201 react-native-nitro-markdown@0.5.8: patches/react-native-nitro-markdown@0.5.8.patch
200202 # Preserve the final layout frame. Backport of [#10171](https://github.com/software-mansion/react-native-reanimated/pull/10171).
201203 react-native-reanimated@4.5.5: patches/react-native-reanimated@4.5.5.patch
202204 react-native-screens@4.26.2: patches/react-native-screens@4.26.2.patch