diff --git a/GitUI/Editor/RichTextBoxXhtmlSupportExtension.cs b/GitUI/Editor/RichTextBoxXhtmlSupportExtension.cs
index 89dcb7b4ceb..3574cd6d850 100644
--- a/GitUI/Editor/RichTextBoxXhtmlSupportExtension.cs
+++ b/GitUI/Editor/RichTextBoxXhtmlSupportExtension.cs
@@ -15,6 +15,8 @@ namespace GitUI.Editor.RichTextBoxExtension
{
internal static class RichTextBoxXhtmlSupportExtension
{
+ private const string LinkSeparator = "|||";
+
///
/// Maintains performance while updating.
///
@@ -1143,10 +1145,9 @@ public static string GetPlainText(this RichTextBox rtb, int from, int to)
++to;
}
- if (to < text.Length && text[to] == '#')
+ if (to < text.Length && DoesMatchLinkSeparatorPattern(text, to))
{
- ++to;
- from = to;
+ from = to + LinkSeparator.Length;
while (to < text.Length && !char.IsWhiteSpace(text[to]) && text[to] != ',')
{
++to;
@@ -1156,7 +1157,7 @@ public static string GetPlainText(this RichTextBox rtb, int from, int to)
// prior to net47 links were created via hidden text, and had the following format: "text#link"
// extract the link portion only
string linkOldFormat = text.Substring(from, to - from);
- return linkOldFormat.Substring(linkOldFormat.IndexOf("#") + 1);
+ return linkOldFormat.Substring(linkOldFormat.IndexOf(LinkSeparator) + LinkSeparator.Length);
}
catch
{
@@ -1173,6 +1174,19 @@ public static string GetPlainText(this RichTextBox rtb, int from, int to)
}
}
+ private static bool DoesMatchLinkSeparatorPattern(string text, int index)
+ {
+ for (int ls = 0; ls < LinkSeparator.Length && index < text.Length; ls++, index++)
+ {
+ if (text[index] != LinkSeparator[ls])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
///
/// Returns input text with characters disallowed by XML spec (e.g. most control codes in 0x00-0x20 range)
/// replaced with equivalent character references or question marks if there is an unrecoverable error.
@@ -1519,7 +1533,7 @@ private static void ProcessEndElement(XmlReader reader, RTFCurrentState cs, Rich
{
string head = rtfText.Substring(0, idx);
string tail = rtfText.Substring(idx);
- RtbSetSelectedRtf(rtb, head + @"\v #" + cs.hyperlink + @"\v0" + tail);
+ RtbSetSelectedRtf(rtb, head + @"\v " + LinkSeparator + cs.hyperlink + @"\v0" + tail);
length = rtb.TextLength - cs.hyperlinkStart;
}
}
diff --git a/UnitTests/GitUI.Tests/Editor/RichTextBoxXhtmlSupportExtensionTests.cs b/UnitTests/GitUI.Tests/Editor/RichTextBoxXhtmlSupportExtensionTests.cs
index 5af7f3535b5..a32b027fa00 100644
--- a/UnitTests/GitUI.Tests/Editor/RichTextBoxXhtmlSupportExtensionTests.cs
+++ b/UnitTests/GitUI.Tests/Editor/RichTextBoxXhtmlSupportExtensionTests.cs
@@ -15,6 +15,7 @@ public class RichTextBoxXhtmlSupportExtensionTests
private const string _defaultLinkUri = "https://uri.org";
private const string _defaultPrefix = "pre ";
private const string _defaultSuffix = " suf";
+ private const string _linkSeparator = "|||";
private RichTextBox _rtb;
private ILinkFactory _linkFactory;
@@ -86,12 +87,35 @@ public void GetLink_should_return_null_if_left_of_link()
public void GetLink_should_return_null_if_right_of_link()
{
SetupDefaultLink();
- for (int index = _defaultPrefix.Length + _defaultLinkText.Length + _defaultLinkUri.Length + 1; index < _rtb.Text.Length; ++index)
+ for (int index = _defaultPrefix.Length + _defaultLinkText.Length + _defaultLinkUri.Length + _linkSeparator.Length; index < _rtb.Text.Length; ++index)
{
_rtb.GetLink(index).Should().BeNull();
}
}
+ [Test]
+ public void GetLink_should_return_uri_if_text_contains_hash()
+ {
+ SetupLink(prefix: string.Empty, linkText: "#hash", uri: _defaultLinkUri, suffix: string.Empty);
+ _rtb.GetLink(0).Should().Be(_defaultLinkUri);
+ }
+
+ [Test]
+ public void GetLink_should_return_uri_if_uri_contains_hash()
+ {
+ string uri = _defaultLinkUri + "#hash";
+ SetupLink(prefix: string.Empty, linkText: _defaultLinkText, uri: uri, suffix: string.Empty);
+ _rtb.GetLink(0).Should().Be(uri);
+ }
+
+ [Test]
+ public void GetLink_should_return_uri_if_text_and_uri_contain_hash()
+ {
+ string uri = _defaultLinkUri + "#hash";
+ SetupLink(prefix: string.Empty, linkText: "#text", uri: uri, suffix: string.Empty);
+ _rtb.GetLink(0).Should().Be(uri);
+ }
+
[Test]
public void GetLink_should_return_uri_if_at_link()
{