Skip to content

Commit 254666f

Browse files
committed
Add missing clearing of pooled arrays
1 parent 959c8e5 commit 254666f

File tree

8 files changed

+61
-0
lines changed

8 files changed

+61
-0
lines changed

src/Components/Components/src/NavigationManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ protected async ValueTask<bool> NotifyLocationChangingAsync(string uri, string?
447447
}
448448
finally
449449
{
450+
locationChangingHandlersCopy.AsSpan(0, handlerCount).Clear();
450451
ArrayPool<Func<LocationChangingContext, ValueTask>>.Shared.Return(locationChangingHandlersCopy);
451452
}
452453
}

src/Components/Endpoints/src/FormMapping/Converters/CollectionAdapters/ArrayPoolBufferAdapter.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Buffers;
5+
using System.Runtime.CompilerServices;
56

67
namespace Microsoft.AspNetCore.Components.Endpoints.FormMapping;
78

@@ -17,7 +18,14 @@ public static PooledBuffer Add(ref PooledBuffer buffer, TElement element)
1718
{
1819
var newBuffer = ArrayPool<TElement>.Shared.Rent(buffer.Data.Length * 2);
1920
Array.Copy(buffer.Data, newBuffer, buffer.Data.Length);
21+
22+
if (RuntimeHelpers.IsReferenceOrContainsReferences<TElement>())
23+
{
24+
buffer.Data.AsSpan(0, buffer.Count).Clear();
25+
}
26+
2027
ArrayPool<TElement>.Shared.Return(buffer.Data);
28+
2129
buffer.Data = newBuffer;
2230
}
2331

@@ -28,7 +36,14 @@ public static PooledBuffer Add(ref PooledBuffer buffer, TElement element)
2836
public static TCollection ToResult(PooledBuffer buffer)
2937
{
3038
var result = TCollectionFactory.ToResultCore(buffer.Data, buffer.Count);
39+
40+
if (RuntimeHelpers.IsReferenceOrContainsReferences<TElement>())
41+
{
42+
buffer.Data.AsSpan(0, buffer.Count).Clear();
43+
}
44+
3145
ArrayPool<TElement>.Shared.Return(buffer.Data);
46+
3247
return result;
3348
}
3449

src/Components/Endpoints/src/FormMapping/PrefixResolver.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void Dispose()
3838
{
3939
if (_sortedKeys != null)
4040
{
41+
_sortedKeys.AsSpan(0, _length).Clear();
4142
ArrayPool<FormKey>.Shared.Return(_sortedKeys);
4243
}
4344
}

src/Middleware/OutputCaching/src/OutputCacheEntryFormatter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public static async ValueTask StoreAsync(string key, OutputCacheEntry value, Has
4949
await bufferStore.SetAsync(key, new(buffer.GetCommittedMemory()), CopyToLeasedMemory(tags, out var lease), duration, cancellationToken);
5050
if (lease is not null)
5151
{
52+
if (tags is not null)
53+
{
54+
lease.AsSpan(0, tags.Count).Clear();
55+
}
56+
5257
ArrayPool<string>.Shared.Return(lease);
5358
}
5459
}

src/Middleware/OutputCaching/src/RecyclableArrayBufferWriter.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Buffers;
55
using System.Diagnostics;
6+
using System.Runtime.CompilerServices;
67

78
namespace Microsoft.AspNetCore.OutputCaching;
89

@@ -32,10 +33,16 @@ public RecyclableArrayBufferWriter()
3233
public void Dispose()
3334
{
3435
var tmp = _buffer;
36+
var count = _index;
3537
_index = 0;
3638
_buffer = Array.Empty<T>();
3739
if (tmp.Length != 0)
3840
{
41+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
42+
{
43+
tmp.AsSpan(0, count).Clear();
44+
}
45+
3946
ArrayPool<T>.Shared.Return(tmp);
4047
}
4148
}
@@ -120,6 +127,11 @@ private void CheckAndResizeBuffer(int sizeHint)
120127
oldArray.AsSpan(0, _index).CopyTo(_buffer);
121128
if (oldArray.Length != 0)
122129
{
130+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
131+
{
132+
oldArray.AsSpan(0, _index).Clear();
133+
}
134+
123135
ArrayPool<T>.Shared.Return(oldArray);
124136
}
125137
}

src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Buffers;
55
using Newtonsoft.Json;
6+
using System.Runtime.CompilerServices;
67

78
namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson;
89

@@ -26,6 +27,11 @@ public void Return(T[]? array)
2627
{
2728
ArgumentNullException.ThrowIfNull(array);
2829

30+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
31+
{
32+
array.AsSpan().Clear();
33+
}
34+
2935
_inner.Return(array);
3036
}
3137
}

src/Shared/ValueStringBuilder/ValueListBuilder.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ public void Dispose()
6060
if (toReturn != null)
6161
{
6262
_arrayFromPool = null;
63+
64+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
65+
{
66+
toReturn.AsSpan(0, _pos).Clear();
67+
}
68+
6369
ArrayPool<T>.Shared.Return(toReturn);
6470
}
6571
}
@@ -95,6 +101,11 @@ private void Grow(int additionalCapacityRequired = 1)
95101
_span = _arrayFromPool = array;
96102
if (toReturn != null)
97103
{
104+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
105+
{
106+
toReturn.AsSpan(0, _pos).Clear();
107+
}
108+
98109
ArrayPool<T>.Shared.Return(toReturn);
99110
}
100111
}

src/SignalR/common/Shared/JsonUtils.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Buffers;
66
using System.Globalization;
77
using System.IO;
8+
using System.Runtime.CompilerServices;
89
using Newtonsoft.Json;
910
using Newtonsoft.Json.Linq;
1011

@@ -216,6 +217,15 @@ public void Return(T[]? array)
216217
return;
217218
}
218219

220+
#if NET
221+
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
222+
#else
223+
if (!typeof(T).IsPrimitive)
224+
#endif
225+
{
226+
array.AsSpan().Clear();
227+
}
228+
219229
_inner.Return(array);
220230
}
221231
}

0 commit comments

Comments
 (0)