Skip to content

Commit d9e4f0b

Browse files
committed
run on STJ
1 parent c4c4076 commit d9e4f0b

50 files changed

Lines changed: 2383 additions & 1817 deletions

File tree

Some content is hidden

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

src/libraries/Common/src/Polyfills/EncodingPolyfills.cs

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,29 @@ namespace System.Text;
1010
/// <summary>Provides downlevel polyfills for span-based Encoding APIs.</summary>
1111
internal static class EncodingPolyfills
1212
{
13-
public static unsafe int GetByteCount(this Encoding encoding, ReadOnlySpan<char> chars)
13+
public static int GetByteCount(this Encoding encoding, ReadOnlySpan<char> chars)
1414
{
15-
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
15+
// SAFETY-TODO: review this unsafe usage.
16+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
17+
unsafe
1618
{
17-
return encoding.GetByteCount(charsPtr, chars.Length);
19+
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
20+
{
21+
return encoding.GetByteCount(charsPtr, chars.Length);
22+
}
1823
}
1924
}
2025

21-
public static unsafe int GetCharCount(this Encoding encoding, ReadOnlySpan<byte> bytes)
26+
public static int GetCharCount(this Encoding encoding, ReadOnlySpan<byte> bytes)
2227
{
23-
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
28+
// SAFETY-TODO: review this unsafe usage.
29+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
30+
unsafe
2431
{
25-
return encoding.GetCharCount(bytesPtr, bytes.Length);
32+
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
33+
{
34+
return encoding.GetCharCount(bytesPtr, bytes.Length);
35+
}
2636
}
2737
}
2838

@@ -31,29 +41,44 @@ public static int GetBytes(this Encoding encoding, string str, Span<byte> bytes)
3141
return GetBytes(encoding, str.AsSpan(), bytes);
3242
}
3343

34-
public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan<char> chars, Span<byte> bytes)
44+
public static int GetBytes(this Encoding encoding, ReadOnlySpan<char> chars, Span<byte> bytes)
3545
{
36-
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
37-
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
46+
// SAFETY-TODO: review this unsafe usage.
47+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
48+
unsafe
3849
{
39-
return encoding.GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length);
50+
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
51+
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
52+
{
53+
return encoding.GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length);
54+
}
4055
}
4156
}
4257

43-
public static unsafe int GetChars(this Encoding encoding, ReadOnlySpan<byte> bytes, Span<char> chars)
58+
public static int GetChars(this Encoding encoding, ReadOnlySpan<byte> bytes, Span<char> chars)
4459
{
45-
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
46-
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
60+
// SAFETY-TODO: review this unsafe usage.
61+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
62+
unsafe
4763
{
48-
return encoding.GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length);
64+
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
65+
fixed (char* charsPtr = &GetNonNullPinnableReference(chars))
66+
{
67+
return encoding.GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length);
68+
}
4969
}
5070
}
5171

52-
public static unsafe string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
72+
public static string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
5373
{
54-
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
74+
// SAFETY-TODO: review this unsafe usage.
75+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
76+
unsafe
5577
{
56-
return encoding.GetString(bytesPtr, bytes.Length);
78+
fixed (byte* bytesPtr = &GetNonNullPinnableReference(bytes))
79+
{
80+
return encoding.GetString(bytesPtr, bytes.Length);
81+
}
5782
}
5883
}
5984

@@ -73,9 +98,14 @@ public static bool TryGetChars(this Encoding encoding, ReadOnlySpan<byte> bytes,
7398
}
7499

75100
[MethodImpl(MethodImplOptions.AggressiveInlining)]
76-
private static unsafe ref readonly T GetNonNullPinnableReference<T>(ReadOnlySpan<T> buffer)
101+
private static ref readonly T GetNonNullPinnableReference<T>(ReadOnlySpan<T> buffer)
77102
{
78-
// Based on the internal implementation from MemoryMarshal.
79-
return ref buffer.Length != 0 ? ref MemoryMarshal.GetReference(buffer) : ref Unsafe.AsRef<T>((void*)1);
103+
// SAFETY-TODO: review this unsafe usage.
104+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
105+
unsafe
106+
{
107+
// Based on the internal implementation from MemoryMarshal.
108+
return ref buffer.Length != 0 ? ref MemoryMarshal.GetReference(buffer) : ref Unsafe.AsRef<T>((void*)1);
109+
}
80110
}
81111
}

src/libraries/Common/src/Polyfills/SinglePolyfills.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ internal static class SinglePolyfills
1111
extension(float)
1212
{
1313
[MethodImpl(MethodImplOptions.AggressiveInlining)]
14-
public static unsafe bool IsFinite(float f)
14+
public static bool IsFinite(float f)
1515
{
16-
uint bits = *(uint*)&f;
17-
return (~bits & 0x7F80_0000U) != 0;
16+
// SAFETY-TODO: review this unsafe usage.
17+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
18+
unsafe
19+
{
20+
uint bits = *(uint*)&f;
21+
return (~bits & 0x7F80_0000U) != 0;
22+
}
1823
}
1924
}
2025
}

src/libraries/Common/src/Polyfills/StringBuilderPolyfills.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ internal static class StringBuilderPolyfills
1111
extension(StringBuilder stringBuilder)
1212
{
1313
/// <summary>Polyfill for StringBuilder.Append(ReadOnlySpan&lt;char&gt;) which is not available on .NET Standard 2.0.</summary>
14-
public unsafe StringBuilder Append(ReadOnlySpan<char> span)
14+
public StringBuilder Append(ReadOnlySpan<char> span)
1515
{
16-
fixed (char* ptr = &MemoryMarshal.GetReference(span))
16+
// SAFETY-TODO: review this unsafe usage.
17+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
18+
unsafe
1719
{
18-
return stringBuilder.Append(ptr, span.Length);
20+
fixed (char* ptr = &MemoryMarshal.GetReference(span))
21+
{
22+
return stringBuilder.Append(ptr, span.Length);
23+
}
1924
}
2025
}
2126
}

src/libraries/Common/src/System/Text/AsciiPolyfills.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,44 @@ public static bool IsValid(string value)
1313
return IsValid(value.AsSpan());
1414
}
1515

16-
public static unsafe bool IsValid(ReadOnlySpan<char> value)
16+
public static bool IsValid(ReadOnlySpan<char> value)
1717
{
18-
fixed (char* src = value)
18+
// SAFETY-TODO: review this unsafe usage.
19+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
20+
unsafe
1921
{
20-
uint* ptrUInt32 = (uint*)src;
21-
int length = value.Length;
22-
23-
while (length >= 4)
22+
fixed (char* src = value)
2423
{
25-
if (!AllCharsInUInt32AreAscii(ptrUInt32[0] | ptrUInt32[1]))
24+
uint* ptrUInt32 = (uint*)src;
25+
int length = value.Length;
26+
27+
while (length >= 4)
2628
{
27-
return false;
28-
}
29+
if (!AllCharsInUInt32AreAscii(ptrUInt32[0] | ptrUInt32[1]))
30+
{
31+
return false;
32+
}
2933

30-
ptrUInt32 += 2;
31-
length -= 4;
32-
}
34+
ptrUInt32 += 2;
35+
length -= 4;
36+
}
3337

34-
char* ptrChar = (char*)ptrUInt32;
35-
while (length-- > 0)
36-
{
37-
char ch = *ptrChar++;
38-
if (ch >= 0x80)
38+
char* ptrChar = (char*)ptrUInt32;
39+
while (length-- > 0)
3940
{
40-
return false;
41+
char ch = *ptrChar++;
42+
if (ch >= 0x80)
43+
{
44+
return false;
45+
}
4146
}
4247
}
43-
}
4448

45-
return true;
49+
return true;
4650

47-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
48-
static bool AllCharsInUInt32AreAscii(uint value) => (value & ~0x007F_007Fu) == 0;
51+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
52+
static bool AllCharsInUInt32AreAscii(uint value) => (value & ~0x007F_007Fu) == 0;
53+
}
4954
}
5055
}
5156
}

src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -257,37 +257,42 @@ private static unsafe Rune ChangeCaseCultureAware(Rune rune, TextInfo textInfo,
257257
}
258258
}
259259
#else
260-
private static unsafe Rune ChangeCaseCultureAware(Rune rune, CultureInfo culture, bool toUpper)
260+
private static Rune ChangeCaseCultureAware(Rune rune, CultureInfo culture, bool toUpper)
261261
{
262-
Debug.Assert(culture != null, "This should've been checked by the caller.");
262+
// SAFETY-TODO: review this unsafe usage.
263+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
264+
unsafe
265+
{
266+
Debug.Assert(culture != null, "This should've been checked by the caller.");
263267

264-
Span<char> original = stackalloc char[MaxUtf16CharsPerRune]; // worst case scenario = 2 code units (for a surrogate pair)
265-
Span<char> modified = stackalloc char[MaxUtf16CharsPerRune]; // case change should preserve UTF-16 code unit count
268+
Span<char> original = stackalloc char[MaxUtf16CharsPerRune]; // worst case scenario = 2 code units (for a surrogate pair)
269+
Span<char> modified = stackalloc char[MaxUtf16CharsPerRune]; // case change should preserve UTF-16 code unit count
266270

267-
int charCount = rune.EncodeToUtf16(original);
268-
original = original.Slice(0, charCount);
269-
modified = modified.Slice(0, charCount);
271+
int charCount = rune.EncodeToUtf16(original);
272+
original = original.Slice(0, charCount);
273+
modified = modified.Slice(0, charCount);
270274

271-
if (toUpper)
272-
{
273-
MemoryExtensions.ToUpper(original, modified, culture);
274-
}
275-
else
276-
{
277-
MemoryExtensions.ToLower(original, modified, culture);
278-
}
275+
if (toUpper)
276+
{
277+
MemoryExtensions.ToUpper(original, modified, culture);
278+
}
279+
else
280+
{
281+
MemoryExtensions.ToLower(original, modified, culture);
282+
}
279283

280-
// We use simple case folding rules, which disallows moving between the BMP and supplementary
281-
// planes when performing a case conversion. The helper methods which reconstruct a Rune
282-
// contain debug asserts for this condition.
284+
// We use simple case folding rules, which disallows moving between the BMP and supplementary
285+
// planes when performing a case conversion. The helper methods which reconstruct a Rune
286+
// contain debug asserts for this condition.
283287

284-
if (rune.IsBmp)
285-
{
286-
return UnsafeCreate(modified[0]);
287-
}
288-
else
289-
{
290-
return UnsafeCreate(UnicodeUtility.GetScalarFromUtf16SurrogatePair(modified[0], modified[1]));
288+
if (rune.IsBmp)
289+
{
290+
return UnsafeCreate(modified[0]);
291+
}
292+
else
293+
{
294+
return UnsafeCreate(UnicodeUtility.GetScalarFromUtf16SurrogatePair(modified[0], modified[1]));
295+
}
291296
}
292297
}
293298
#endif
@@ -793,21 +798,26 @@ public int EncodeToUtf8(Span<byte> destination)
793798
/// <param name="other">The rune to compare with the current instance.</param>
794799
/// <param name="comparisonType">One of the enumeration values that specifies the rules to use in the comparison.</param>
795800
/// <returns><see langword="true"/> if the current instance and <paramref name="other"/> are equal; otherwise, <see langword="false"/>.</returns>
796-
public unsafe bool Equals(Rune other, StringComparison comparisonType)
801+
public bool Equals(Rune other, StringComparison comparisonType)
797802
{
798-
if (comparisonType is StringComparison.Ordinal)
803+
// SAFETY-TODO: review this unsafe usage.
804+
// Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
805+
unsafe
799806
{
800-
return this == other;
801-
}
807+
if (comparisonType is StringComparison.Ordinal)
808+
{
809+
return this == other;
810+
}
802811

803-
// Convert this to span
804-
ReadOnlySpan<char> thisChars = AsSpan(stackalloc char[MaxUtf16CharsPerRune]);
812+
// Convert this to span
813+
ReadOnlySpan<char> thisChars = AsSpan(stackalloc char[MaxUtf16CharsPerRune]);
805814

806-
// Convert other to span
807-
ReadOnlySpan<char> otherChars = other.AsSpan(stackalloc char[MaxUtf16CharsPerRune]);
815+
// Convert other to span
816+
ReadOnlySpan<char> otherChars = other.AsSpan(stackalloc char[MaxUtf16CharsPerRune]);
808817

809-
// Compare span equality
810-
return thisChars.Equals(otherChars, comparisonType);
818+
// Compare span equality
819+
return thisChars.Equals(otherChars, comparisonType);
820+
}
811821
}
812822

813823
public override int GetHashCode() => Value;

src/libraries/System.Text.Json/src/System.Text.Json.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6+
<EnableUnsafeMethodModifierAnalyzer>true</EnableUnsafeMethodModifierAnalyzer>
67
<!-- For this project, we want warnings if there are public APIs/types without properly formatted XML comments. -->
78
<SkipIntellisenseNoWarnCS1591>true</SkipIntellisenseNoWarnCS1591>
89
<NoWarn>$(NoWarn);CS8969</NoWarn>

0 commit comments

Comments
 (0)