diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/Zstandard/ZstandardDictionary.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/Zstandard/ZstandardDictionary.cs index 5672690ae458f0..110d164beffa77 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/Zstandard/ZstandardDictionary.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/Zstandard/ZstandardDictionary.cs @@ -127,23 +127,30 @@ public static ZstandardDictionary Train(ReadOnlySpan samples, ReadOnlySpan ArgumentOutOfRangeException.ThrowIfLessThan(maxDictionarySize, 256, nameof(maxDictionarySize)); - byte[] dictionaryBuffer = new byte[maxDictionarySize]; - - nuint dictSize; - - unsafe + byte[] dictionaryBuffer = ArrayPool.Shared.Rent(maxDictionarySize); + try { - fixed (byte* samplesPtr = &MemoryMarshal.GetReference(samples)) - fixed (byte* dictPtr = dictionaryBuffer) - fixed (nuint* lengthsAsNuintPtr = &MemoryMarshal.GetReference(lengthsAsNuint)) + nuint dictSize; + + unsafe { - dictSize = Interop.Zstd.ZDICT_trainFromBuffer( - dictPtr, (nuint)maxDictionarySize, - samplesPtr, lengthsAsNuintPtr, (uint)sampleLengths.Length); + fixed (byte* samplesPtr = &MemoryMarshal.GetReference(samples)) + fixed (byte* dictPtr = dictionaryBuffer) + fixed (nuint* lengthsAsNuintPtr = &MemoryMarshal.GetReference(lengthsAsNuint)) + { + dictSize = Interop.Zstd.ZDICT_trainFromBuffer( + dictPtr, (nuint)maxDictionarySize, + samplesPtr, lengthsAsNuintPtr, (uint)sampleLengths.Length); + } + + ZstandardUtils.ThrowIfError(dictSize); + return Create(dictionaryBuffer.AsSpan(0, (int)dictSize)); } - - ZstandardUtils.ThrowIfError(dictSize); - return Create(dictionaryBuffer.AsSpan(0, (int)dictSize)); + } + finally + { + // Clear before returning: the trained dictionary is derived from caller-supplied samples. + ArrayPool.Shared.Return(dictionaryBuffer, clearArray: true); } } finally