Skip to content

Commit a5f25d0

Browse files
authored
Fix StackOverflowException on StringUtil.Create (#259)
* Fix StackOverflowException on StringUtil.Create `Span<byte> buffer = stackalloc byte[(int)sequence.Length];` * Refactor StringUtil.Create to remove unsafe code Replaces unsafe pointer usage in StringUtil.Create with safe Encoding.GetString overloads. Also changes length check from ushort.MaxValue to short.MaxValue for consistency. Encoding.GetString(ReadOnlySpan<byte>) available with .NET Standard 2.1
1 parent c6c7b15 commit a5f25d0

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

Src/SmtpServer/Protocol/SmtpParser.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,23 +1099,35 @@ public bool TryMakeMailbox(ref TokenReader reader, out IMailbox mailbox)
10991099

11001100
if (reader.TryMake(TryMakeDomain, out var domain))
11011101
{
1102-
mailbox = CreateMailbox(localpart, domain);
1102+
mailbox = CreateMailbox(localpart, domain) ?? throw new SmtpResponseException(SmtpResponse.MailboxNameNotAllowed);
11031103
return true;
11041104
}
11051105

11061106
if (reader.TryMake(TryMakeAddressLiteral, out var address))
11071107
{
1108-
mailbox = CreateMailbox(localpart, address);
1108+
mailbox = CreateMailbox(localpart, address) ?? throw new SmtpResponseException(SmtpResponse.MailboxNameNotAllowed);
11091109
return true;
11101110
}
11111111

11121112
return false;
11131113

11141114
static Mailbox CreateMailbox(ReadOnlySequence<byte> localpart, ReadOnlySequence<byte> domainOrAddress)
11151115
{
1116-
var user = Regex.Unescape(StringUtil.Create(localpart, Encoding.UTF8).Trim('"'));
1116+
var tempLocalpart = StringUtil.Create(localpart, Encoding.UTF8)?.Trim('"');
1117+
if (tempLocalpart == null)
1118+
{
1119+
return null;
1120+
}
1121+
1122+
var tempDomain = StringUtil.Create(domainOrAddress);
1123+
if (tempDomain == null)
1124+
{
1125+
return null;
1126+
}
1127+
1128+
var unescapedLocalpart = Regex.Unescape(tempLocalpart);
11171129

1118-
return new Mailbox(user, StringUtil.Create(domainOrAddress));
1130+
return new Mailbox(unescapedLocalpart, tempDomain);
11191131
}
11201132
}
11211133

Src/SmtpServer/Text/StringUtil.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ internal static string Create(ReadOnlySequence<byte> sequence)
1111
return Create(sequence, Encoding.ASCII);
1212
}
1313

14-
internal static unsafe string Create(ReadOnlySequence<byte> sequence, Encoding encoding)
14+
internal static string Create(ReadOnlySequence<byte> sequence, Encoding encoding)
1515
{
1616
if (sequence.Length == 0)
1717
{
1818
return null;
1919
}
2020

21-
if (sequence.IsSingleSegment)
21+
if (sequence.Length > short.MaxValue)
2222
{
23-
var span = sequence.First.Span;
23+
return null;
24+
}
2425

25-
fixed (byte* ptr = span)
26-
{
27-
return encoding.GetString(ptr, span.Length);
28-
}
26+
if (sequence.IsSingleSegment)
27+
{
28+
return encoding.GetString(sequence.First.Span);
2929
}
3030
else
3131
{
@@ -43,10 +43,7 @@ internal static unsafe string Create(ReadOnlySequence<byte> sequence, Encoding e
4343
}
4444
}
4545

46-
fixed (byte* ptr = buffer)
47-
{
48-
return encoding.GetString(ptr, buffer.Length);
49-
}
46+
return encoding.GetString(buffer);
5047
}
5148
}
5249

0 commit comments

Comments
 (0)