diff --git a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.SparseFile.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.SparseFile.Tests.cs index 29c87ea91ae70f..9aa19894fea1db 100644 --- a/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.SparseFile.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarReader/TarReader.SparseFile.Tests.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; -using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -34,13 +35,10 @@ private static void WriteSparseEntry(TarWriter writer, string realName, long rea ["GNU.sparse.name"] = realName, }; var entry = new PaxTarEntry(TarEntryType.RegularFile, "GNUSparseFile.0/" + realName, gnuSparseAttributes); - // Inject GNU.sparse.realsize into the internal _header.ExtendedAttributes dictionary via - // reflection, bypassing the public ReadOnlyDictionary façade and constructor validation. - // This allows intentionally-invalid archives (negative realsize) to be constructed for tests. - var headerField = typeof(TarEntry).GetField("_header", BindingFlags.NonPublic | BindingFlags.Instance)!; - var header = headerField.GetValue(entry)!; - var eaProp = header.GetType().GetProperty("ExtendedAttributes", BindingFlags.NonPublic | BindingFlags.Instance)!; - var ea = (Dictionary)eaProp.GetValue(header)!; + // Inject GNU.sparse.realsize into the internal EA dictionary via UnsafeAccessor, bypassing + // the public ReadOnlyDictionary façade and constructor validation. This allows + // intentionally-invalid archives (negative realsize) to be constructed for tests. + var ea = (Dictionary)ReadOnlyDictionaryAccessors.GetInnerDictionary((ReadOnlyDictionary)entry.ExtendedAttributes); ea["GNU.sparse.realsize"] = realSize.ToString(); entry.DataStream = new MemoryStream(rawSparseData); writer.WriteEntry(entry); @@ -546,6 +544,12 @@ private static void VerifyExpandedContent(byte[] buf, long realSize, (long Offse Assert.Equal(0, buf[i]); } } + + private static class ReadOnlyDictionaryAccessors where TKey : notnull + { + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "m_dictionary")] + public static extern ref IDictionary GetInnerDictionary(ReadOnlyDictionary d); + } } // Minimal non-seekable stream wrapper for testing.