Skip to content

Commit b24d011

Browse files
authored
[BUG] fix pooled array leak in string marshalling (#1)
* fix pooled array leak in string marshalling * fix pooled array leak in string marshalling
1 parent 3240596 commit b24d011

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

sources/Core/SilkMarshal.cs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,30 @@ public static ref readonly byte StringToNative(ReadOnlySpan<char> str, nint char
8585
{
8686
var maxCharCount = Encoding.UTF8.GetMaxByteCount(str.Length) + 1;
8787
byte[]? arr = null;
88-
var utf8 = maxCharCount > 256
89-
? arr = ArrayPool<byte>.Shared.Rent(maxCharCount)
90-
: stackalloc byte[maxCharCount];
91-
if (Utf8.FromUtf16(str, utf8, out _, out var bytesWritten) != OperationStatus.Done)
88+
try
9289
{
93-
throw new ArgumentException("Failed to convert to UTF8", nameof(str));
94-
}
90+
var utf8 = maxCharCount > 256
91+
? arr = ArrayPool<byte>.Shared.Rent(maxCharCount)
92+
: stackalloc byte[maxCharCount];
93+
if (Utf8.FromUtf16(str, utf8, out _, out var bytesWritten) != OperationStatus.Done)
94+
{
95+
throw new ArgumentException("Failed to convert to UTF8", nameof(str));
96+
}
9597

96-
utf8 = utf8[..(bytesWritten + 1)];
97-
utf8[bytesWritten] = 0;
98-
var ret = new byte[utf8.Length];
99-
utf8.CopyTo(ret);
100-
if (arr is not null)
98+
utf8 = utf8[..(bytesWritten + 1)];
99+
utf8[bytesWritten] = 0;
100+
var ret = new byte[utf8.Length];
101+
utf8.CopyTo(ret);
102+
103+
return ret;
104+
}
105+
finally
101106
{
102-
ArrayPool<byte>.Shared.Return(arr);
107+
if (arr is not null)
108+
{
109+
ArrayPool<byte>.Shared.Return(arr);
110+
}
103111
}
104-
return ret;
105112
}
106113
case 2:
107114
{
@@ -114,19 +121,26 @@ public static ref readonly byte StringToNative(ReadOnlySpan<char> str, nint char
114121
{
115122
var maxCharCount = Encoding.UTF32.GetMaxByteCount(str.Length) + 4;
116123
byte[]? arr = null;
117-
var utf32 = maxCharCount > 256
118-
? arr = ArrayPool<byte>.Shared.Rent(maxCharCount)
119-
: stackalloc byte[maxCharCount];
120-
var bytesWritten = Encoding.UTF32.GetBytes(str, utf32);
121-
utf32 = utf32[..(bytesWritten + 4)];
122-
Unsafe.As<byte, int>(ref utf32[bytesWritten]) = 0;
123-
var ret = new byte[utf32.Length];
124-
utf32.CopyTo(ret);
125-
if (arr is not null)
124+
try
125+
{
126+
var utf32 = maxCharCount > 256
127+
? arr = ArrayPool<byte>.Shared.Rent(maxCharCount)
128+
: stackalloc byte[maxCharCount];
129+
var bytesWritten = Encoding.UTF32.GetBytes(str, utf32);
130+
utf32 = utf32[..(bytesWritten + 4)];
131+
Unsafe.As<byte, int>(ref utf32[bytesWritten]) = 0;
132+
var ret = new byte[utf32.Length];
133+
utf32.CopyTo(ret);
134+
135+
return ret;
136+
}
137+
finally
126138
{
127-
ArrayPool<byte>.Shared.Return(arr);
139+
if (arr is not null)
140+
{
141+
ArrayPool<byte>.Shared.Return(arr);
142+
}
128143
}
129-
return ret;
130144
}
131145
default:
132146
{

0 commit comments

Comments
 (0)