Skip to content

Commit aa0ad4a

Browse files
authored
#2235 - Invalid UTF‑16 surrogate sequences in comment text are now sanitized before XML generation to prevent XmlException. (#2241)
1 parent c009761 commit aa0ad4a

3 files changed

Lines changed: 54 additions & 0 deletions

File tree

src/EPPlus/ExcelWorksheet.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Date Author Change
5858
using OfficeOpenXml.Core.RangeQuadTree;
5959
using OfficeOpenXml.Data.QueryTable;
6060
using OfficeOpenXml.Data.Connection.IOHandlers;
61+
using System.Security.Permissions;
6162

6263
namespace OfficeOpenXml
6364
{
@@ -2636,6 +2637,10 @@ private void UpdateCommentRichText()
26362637
{
26372638
foreach (ExcelComment comment in _comments)
26382639
{
2640+
foreach(var rt in comment.RichText)
2641+
{
2642+
rt.Text = StringUtil.SanitizeUtf16(rt.Text);
2643+
}
26392644
var textNode = comment._commentHelper.GetNode("d:text");
26402645
textNode.InnerXml = comment.RichText.GetXML();
26412646
}

src/EPPlus/Utils/StringUtil.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,5 +149,41 @@ static IEnumerable<int> EnumerateRunes(string input)
149149
}
150150
}
151151
}
152+
153+
internal static string SanitizeUtf16(string s)
154+
{
155+
if (string.IsNullOrEmpty(s)) return s;
156+
157+
var sb = new StringBuilder(s.Length);
158+
159+
for (int i = 0; i < s.Length; i++)
160+
{
161+
char c = s[i];
162+
163+
if (char.IsHighSurrogate(c))
164+
{
165+
if (i + 1 < s.Length && char.IsLowSurrogate(s[i + 1]))
166+
{
167+
sb.Append(c);
168+
sb.Append(s[i + 1]);
169+
i++;
170+
}
171+
else
172+
{
173+
sb.Append('\uFFFD');
174+
}
175+
}
176+
else if (char.IsLowSurrogate(c))
177+
{
178+
sb.Append('\uFFFD');
179+
}
180+
else
181+
{
182+
sb.Append(c);
183+
}
184+
}
185+
186+
return sb.ToString();
187+
}
152188
}
153189
}

src/EPPlusTest/Issues/PackageIssues.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,18 @@ public void s908()
140140
SaveAndCleanup(package);
141141
}
142142
}
143+
144+
[TestMethod]
145+
public void i2235()
146+
{
147+
using var package = OpenTemplatePackage("SurrogatePairs.xlsx");
148+
var sheet = package.Workbook.Worksheets[0];
149+
sheet.Cells["A8"].Value = "hello \uDC00";
150+
sheet.Cells["A9"].Value = "hello 2 \uDFFF\uDFFF";
151+
sheet.Cells["A10"].AddComment("testing testing \uDFFF\uDFFF");
152+
sheet.Cells["A11"].Value = "End test";
153+
sheet.Calculate(o => o.EnableUnicodeAwareStringOperations = true);
154+
SaveAndCleanup(package);
155+
}
143156
}
144157
}

0 commit comments

Comments
 (0)