Skip to content

Commit c86ab0b

Browse files
committed
[src] Fix the first rule of unsafe coding practices.
Don't do this: ```cs unsafe void UnreliableCode(ref int x) { int* nativePointer = (int*)Unsafe.AsPointer(ref x); nativePointer[0] = 42; } ``` The reason being is that the GC can move the 'ref int' argument (which doesn't seem right at first glance, but objects can be moved by the GC, and the 'ref int' argument can point to an integer field inside an object). The proper pattern is: ```cs unsafe void ReliableCode(ref int x) { fixed (int* ptr = &x) { ptr[0] = 42; } } ``` So update everything to use this pattern instead. References: * https://github.com/dotnet/designs/blob/67ad92c511d8f6a2b8b500bd6f13f865b163e282/accepted/2025/memory-safety/unsafe-code-guidelines.md#1-untracked-managed-pointers-unsafeaspointer-and-friends
1 parent c26c900 commit c86ab0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+802
-492
lines changed

src/Accelerate/vImageTypes.cs

Lines changed: 120 additions & 80 deletions
Large diffs are not rendered by default.

src/AudioToolbox/AudioConverter.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -977,14 +977,16 @@ AudioStreamPacketDependencyDescription [] packetDependencies
977977
unsafe {
978978
fixed (AudioStreamPacketDependencyDescription* packetDependenciesPtr = packetDependencies) {
979979
fixed (AudioStreamPacketDescription* packetDescriptionPtr = packetDescriptions) {
980-
return AudioConverterFillComplexBufferWithPacketDependencies (
981-
GetCheckedHandle (),
982-
&FillComplexBufferShared,
983-
(IntPtr) this_handle,
984-
(uint*) Unsafe.AsPointer<int> (ref outputDataPacketSize),
985-
(IntPtr) outputData,
986-
packetDescriptionPtr,
987-
packetDependenciesPtr);
980+
fixed (int* outputDataPacketSizePtr = &outputDataPacketSize) {
981+
return AudioConverterFillComplexBufferWithPacketDependencies (
982+
GetCheckedHandle (),
983+
&FillComplexBufferShared,
984+
(IntPtr) this_handle,
985+
(uint*) outputDataPacketSizePtr,
986+
(IntPtr) outputData,
987+
packetDescriptionPtr,
988+
packetDependenciesPtr);
989+
}
988990
}
989991
}
990992
}

src/AudioToolbox/AudioFile.cs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,13 +1270,15 @@ unsafe extern static OSStatus AudioFileReadPacketData (
12701270
{
12711271
OSStatus r;
12721272
fixed (AudioStreamPacketDescription* pdesc = descriptions) {
1273-
r = AudioFileReadPacketData (Handle,
1274-
useCache ? (byte) 1 : (byte) 0,
1275-
(int*) Unsafe.AsPointer<int> (ref count),
1276-
pdesc,
1277-
inStartingPacket,
1278-
(int*) Unsafe.AsPointer<int> (ref nPackets),
1279-
buffer);
1273+
fixed (int* countPtr = &count, nPacketsPtr = &nPackets) {
1274+
r = AudioFileReadPacketData (Handle,
1275+
useCache ? (byte) 1 : (byte) 0,
1276+
countPtr,
1277+
pdesc,
1278+
inStartingPacket,
1279+
nPacketsPtr,
1280+
buffer);
1281+
}
12801282
}
12811283

12821284
error = (AudioFileError) r;
@@ -1556,7 +1558,9 @@ public AudioFileError WritePackets (bool useCache, int numBytes, AudioStreamPack
15561558

15571559
unsafe {
15581560
fixed (AudioStreamPacketDescription* packetDescriptionsPtr = packetDescriptions) {
1559-
return AudioFileWritePackets (Handle, useCache ? (byte) 1 : (byte) 0, numBytes, packetDescriptionsPtr, startingPacket, (int*) Unsafe.AsPointer<int> (ref numPackets), buffer);
1561+
fixed (int* numPacketsPtr = &numPackets) {
1562+
return AudioFileWritePackets (Handle, useCache ? (byte) 1 : (byte) 0, numBytes, packetDescriptionsPtr, startingPacket, numPacketsPtr, buffer);
1563+
}
15601564
}
15611565
}
15621566
}
@@ -1600,15 +1604,17 @@ public AudioFileError WritePackets (bool useCache, AudioStreamPacketDescription
16001604
unsafe {
16011605
fixed (AudioStreamPacketDescription* packetDescriptionsPtr = packetDescriptions) {
16021606
fixed (AudioStreamPacketDependencyDescription* packetDependenciesPtr = packetDependencies) {
1603-
return AudioFileWritePacketsWithDependencies (
1604-
GetCheckedHandle (),
1605-
useCache.AsByte (),
1606-
(uint) numBytes,
1607-
packetDescriptionsPtr,
1608-
packetDependenciesPtr,
1609-
startingPacket,
1610-
(uint*) Unsafe.AsPointer<int> (ref numPackets),
1611-
buffer);
1607+
fixed (int* numPacketsPtr = &numPackets) {
1608+
return AudioFileWritePacketsWithDependencies (
1609+
GetCheckedHandle (),
1610+
useCache.AsByte (),
1611+
(uint) numBytes,
1612+
packetDescriptionsPtr,
1613+
packetDependenciesPtr,
1614+
startingPacket,
1615+
(uint*) numPacketsPtr,
1616+
buffer);
1617+
}
16121618
}
16131619
}
16141620
}
@@ -1715,7 +1721,8 @@ public AudioFileError GetUserDataSize (uint userDataId, int index, out ulong siz
17151721
{
17161722
size = 0;
17171723
unsafe {
1718-
return (AudioFileError) AudioFileGetUserDataSize64 (Handle, userDataId, index, (ulong*) Unsafe.AsPointer<ulong> (ref size));
1724+
fixed (ulong* sizePtr = &size)
1725+
return (AudioFileError) AudioFileGetUserDataSize64 (Handle, userDataId, index, sizePtr);
17191726
}
17201727
}
17211728

@@ -1749,7 +1756,8 @@ public int GetUserData (int userDataID, int index, ref int size, IntPtr userData
17491756
#endif
17501757
{
17511758
unsafe {
1752-
return AudioFileGetUserData (Handle, userDataID, index, (int*) Unsafe.AsPointer<int> (ref size), userData);
1759+
fixed (int* sizePtr = &size)
1760+
return AudioFileGetUserData (Handle, userDataID, index, sizePtr, userData);
17531761
}
17541762
}
17551763

@@ -1785,7 +1793,8 @@ public AudioFileError GetUserData (AudioFileChunkType chunkType, int index, ref
17851793
public AudioFileError GetUserData (uint userDataId, int index, long offset, ref int size, IntPtr userData)
17861794
{
17871795
unsafe {
1788-
return (AudioFileError) AudioFileGetUserDataAtOffset (Handle, userDataId, index, offset, (int*) Unsafe.AsPointer<int> (ref size), userData);
1796+
fixed (int* sizePtr = &size)
1797+
return (AudioFileError) AudioFileGetUserDataAtOffset (Handle, userDataId, index, offset, sizePtr, userData);
17891798
}
17901799
}
17911800

@@ -1931,7 +1940,9 @@ public bool GetPropertyInfo (AudioFileProperty property, out int size, out int w
19311940
size = default;
19321941
writable = default;
19331942
unsafe {
1934-
error = AudioFileGetPropertyInfo (Handle, property, (int*) Unsafe.AsPointer<int> (ref size), (int*) Unsafe.AsPointer<int> (ref writable));
1943+
fixed (int* sizePtr = &size, writablePtr = &writable) {
1944+
error = AudioFileGetPropertyInfo (Handle, property, sizePtr, writablePtr);
1945+
}
19351946
}
19361947
return error == AudioFileError.Success;
19371948
}
@@ -1959,7 +1970,8 @@ public bool GetPropertyInfo (AudioFileProperty property, out int size, out bool
19591970
size = default;
19601971

19611972
unsafe {
1962-
error = AudioFileGetPropertyInfo (Handle, property, (int*) Unsafe.AsPointer<int> (ref size), &writableValue);
1973+
fixed (int* sizePtr = &size)
1974+
error = AudioFileGetPropertyInfo (Handle, property, sizePtr, &writableValue);
19631975
}
19641976
writable = writableValue != 0;
19651977

@@ -1988,7 +2000,8 @@ public bool IsPropertyWritable (AudioFileProperty property)
19882000
public bool GetProperty (AudioFileProperty property, ref int dataSize, IntPtr outdata)
19892001
{
19902002
unsafe {
1991-
return AudioFileGetProperty (Handle, property, (int*) Unsafe.AsPointer<int> (ref dataSize), outdata) == 0;
2003+
fixed (int* dataSizePtr = &dataSize)
2004+
return AudioFileGetProperty (Handle, property, dataSizePtr, outdata) == 0;
19922005
}
19932006
}
19942007

@@ -2007,9 +2020,11 @@ public IntPtr GetProperty (AudioFileProperty property, out int size)
20072020
return IntPtr.Zero;
20082021

20092022
unsafe {
2010-
var rv = AudioFileGetProperty (Handle, property, (int*) Unsafe.AsPointer<int> (ref size), buffer);
2011-
if (rv == 0)
2012-
return buffer;
2023+
fixed (int* sizePtr = &size) {
2024+
var rv = AudioFileGetProperty (Handle, property, sizePtr, buffer);
2025+
if (rv == 0)
2026+
return buffer;
2027+
}
20132028
}
20142029
Marshal.FreeHGlobal (buffer);
20152030
return IntPtr.Zero;

src/AudioToolbox/AudioFileGlobalInfo.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,28 @@ public static HFSTypeCode[] AllHFSTypeCodes {
240240
static bool TryGetGlobalInfoSize (AudioFileGlobalProperty propertyId, out uint size)
241241
{
242242
size = 0;
243-
var rv = AudioFileGetGlobalInfoSize (propertyId, 0, null, (uint*) Unsafe.AsPointer<uint> (ref size));
244-
return rv == 0;
243+
fixed (uint* sizePtr = &size) {
244+
var rv = AudioFileGetGlobalInfoSize (propertyId, 0, null, sizePtr);
245+
return rv == 0;
246+
}
245247
}
246248

247249
static bool TryGetGlobalInfoSize (AudioFileGlobalProperty propertyId, AudioFileType fileType, out uint size)
248250
{
249251
size = 0;
250-
var rv = AudioFileGetGlobalInfoSize (propertyId, sizeof (AudioFileType), (void*) &fileType, (uint*) Unsafe.AsPointer<uint> (ref size));
251-
return rv == 0;
252+
fixed (uint* sizePtr = &size) {
253+
var rv = AudioFileGetGlobalInfoSize (propertyId, sizeof (AudioFileType), (void*) &fileType, sizePtr);
254+
return rv == 0;
255+
}
252256
}
253257

254258
static bool TryGetGlobalInfoSize (AudioFileGlobalProperty propertyId, AudioFileTypeAndFormatID audioFileTypeAndFormatId, out uint size)
255259
{
256260
size = 0;
257-
var rv = AudioFileGetGlobalInfoSize (propertyId, (uint) sizeof (AudioFileTypeAndFormatID), (void*) &audioFileTypeAndFormatId, (uint*) Unsafe.AsPointer<uint> (ref size));
258-
return rv == 0;
261+
fixed (uint* sizePtr = &size) {
262+
var rv = AudioFileGetGlobalInfoSize (propertyId, (uint) sizeof (AudioFileTypeAndFormatID), (void*) &audioFileTypeAndFormatId, sizePtr);
263+
return rv == 0;
264+
}
259265
}
260266

261267
[DllImport (Constants.AudioToolboxLibrary)]
@@ -304,17 +310,20 @@ static bool TryGetGlobalInfo (AudioFileGlobalProperty propertyId, AudioFileType
304310
{
305311
var size = (uint) sizeof (IntPtr);
306312
outPropertyData = default;
307-
var rv = AudioFileGetGlobalInfo (propertyId, sizeof (AudioFileType), &fileType, &size, (IntPtr*) Unsafe.AsPointer<IntPtr> (ref outPropertyData));
308-
return rv == 0;
309-
313+
fixed (IntPtr* outPropertyDataPtr = &outPropertyData) {
314+
var rv = AudioFileGetGlobalInfo (propertyId, sizeof (AudioFileType), &fileType, &size, outPropertyDataPtr);
315+
return rv == 0;
316+
}
310317
}
311318

312319
static bool TryGetGlobalInfo (AudioFileGlobalProperty propertyId, out IntPtr outPropertyData)
313320
{
314321
var size = (uint) sizeof (IntPtr);
315322
outPropertyData = default;
316-
var rv = AudioFileGetGlobalInfo (propertyId, 0, null, &size, (IntPtr*) Unsafe.AsPointer<IntPtr> (ref outPropertyData));
317-
return rv == 0;
323+
fixed (IntPtr* outPropertyDataPtr = &outPropertyData) {
324+
var rv = AudioFileGetGlobalInfo (propertyId, 0, null, &size, outPropertyDataPtr);
325+
return rv == 0;
326+
}
318327
}
319328
}
320329

src/AudioToolbox/AudioFileStream.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,8 @@ public AudioFileStreamStatus Seek (long packetOffset, out long dataByteOffset, o
474474
int v = 0;
475475
dataByteOffset = 0;
476476
unsafe {
477-
LastError = AudioFileStreamSeek (handle, packetOffset, (long*) Unsafe.AsPointer<long> (ref dataByteOffset), &v);
477+
fixed (long* dataByteOffsetPtr = &dataByteOffset)
478+
LastError = AudioFileStreamSeek (handle, packetOffset, dataByteOffsetPtr, &v);
478479
}
479480
if (LastError != AudioFileStreamStatus.Ok) {
480481
isEstimate = false;
@@ -502,7 +503,8 @@ static AudioFileStreamStatus AudioFileStreamGetPropertyInfo (
502503
AudioFileStreamStatus rv;
503504
outPropertyDataSize = 0;
504505
unsafe {
505-
rv = AudioFileStreamGetPropertyInfo (inAudioFileStream, inPropertyID, (int*) Unsafe.AsPointer<int> (ref outPropertyDataSize), &writable);
506+
fixed (int* outPropertyDataSizePtr = &outPropertyDataSize)
507+
rv = AudioFileStreamGetPropertyInfo (inAudioFileStream, inPropertyID, outPropertyDataSizePtr, &writable);
506508
}
507509
isWritable = writable != 0;
508510
return rv;
@@ -530,7 +532,8 @@ public bool GetProperty (AudioFileStreamProperty property, ref int dataSize, Int
530532
if (outPropertyData == IntPtr.Zero)
531533
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (outPropertyData));
532534
unsafe {
533-
return AudioFileStreamGetProperty (handle, property, (int*) Unsafe.AsPointer<int> (ref dataSize), outPropertyData) == 0;
535+
fixed (int* dataSizePtr = &dataSize)
536+
return AudioFileStreamGetProperty (handle, property, dataSizePtr, outPropertyData) == 0;
534537
}
535538
}
536539

@@ -565,7 +568,8 @@ public IntPtr GetProperty (AudioFileStreamProperty property, out int size)
565568
return IntPtr.Zero;
566569

567570
unsafe {
568-
LastError = AudioFileStreamGetProperty (handle, property, (int*) Unsafe.AsPointer<int> (ref size), buffer);
571+
fixed (int* sizePtr = &size)
572+
LastError = AudioFileStreamGetProperty (handle, property, sizePtr, buffer);
569573
}
570574
if (LastError == 0)
571575
return buffer;

0 commit comments

Comments
 (0)