Skip to content

Commit

Permalink
When AppContext switch caching is disabled, default switch value was …
Browse files Browse the repository at this point in the history
…not stored, we were lucky with switches that have "false" as a default
  • Loading branch information
Tanya-Solyanik committed Nov 14, 2024
1 parent fd9aec1 commit 18e6274
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 54 deletions.
12 changes: 0 additions & 12 deletions src/Common/tests/TestUtilities/AppContextSwitchNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,4 @@ public const string EnableUnsafeBinaryFormatterSerialization
/// </summary>
public const string LocalAppContext_DisableCaching
= "TestSwitch.LocalAppContext.DisableCaching";

/// <summary>
/// The switch that controls whether or not the <see cref="BinaryFormatter"/> is enabled in the Clipboard.
/// </summary>
public const string ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName
= "Windows.ClipboardDragDrop.EnableUnsafeBinaryFormatterSerialization";

/// <summary>
/// The switch that controls whether or not the System.Windows.Forms.BinaryFormat.Deserializer is enabled in the Clipboard.
/// </summary>
public const string ClipboardDragDropEnableNrbfSerializationSwitchName
= "Windows.ClipboardDragDrop.EnableNrbfSerialization";
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,58 +96,62 @@ private static bool GetSwitchValue(string switchName, ref int cachedSwitchValue)
{
cachedSwitchValue = isSwitchEnabled ? 1 /*true*/ : -1 /*false*/;
}
else if (!hasSwitch)
{
AppContext.SetSwitch(switchName, isSwitchEnabled);
}

return isSwitchEnabled;
}

static bool GetSwitchDefaultValue(string switchName)
private static bool GetSwitchDefaultValue(string switchName)
{
if (TargetFrameworkName is not { } framework)
{
if (TargetFrameworkName is not { } framework)
{
return false;
}
return false;
}

if (switchName == NoClientNotificationsSwitchName)
{
return false;
}
if (switchName == NoClientNotificationsSwitchName)
{
return false;
}

if (switchName == TreeNodeCollectionAddRangeRespectsSortOrderSwitchName)
{
return true;
}
if (switchName == TreeNodeCollectionAddRangeRespectsSortOrderSwitchName)
{
return true;
}

if (switchName == ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName)
if (switchName == ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName)
{
return false;
}

if (switchName == ClipboardDragDropEnableNrbfSerializationSwitchName)
{
return true;
}

if (framework.Version.Major >= 8)
{
// Behavior changes added in .NET 8

if (switchName == ScaleTopLevelFormMinMaxSizeForDpiSwitchName)
{
return false;
return true;
}

if (switchName == ClipboardDragDropEnableNrbfSerializationSwitchName)
if (switchName == TrackBarModernRenderingSwitchName)
{
return true;
}

if (framework.Version.Major >= 8)
if (switchName == ServicePointManagerCheckCrlSwitchName)
{
// Behavior changes added in .NET 8

if (switchName == ScaleTopLevelFormMinMaxSizeForDpiSwitchName)
{
return true;
}

if (switchName == TrackBarModernRenderingSwitchName)
{
return true;
}

if (switchName == ServicePointManagerCheckCrlSwitchName)
{
return true;
}
return true;
}

return false;
}

return false;
}

/// <summary>
Expand Down Expand Up @@ -256,7 +260,6 @@ public static bool ClipboardDragDropEnableUnsafeBinaryFormatterSerialization
public static bool ClipboardDragDropEnableNrbfSerialization
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get =>
GetCachedSwitchValue(ClipboardDragDropEnableNrbfSerializationSwitchName, ref s_clipboardDragDropEnableNrbfSerialization);
get => GetCachedSwitchValue(ClipboardDragDropEnableNrbfSerializationSwitchName, ref s_clipboardDragDropEnableNrbfSerialization);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace System;

public readonly ref struct BinaryFormatterInClipboardDragDropScope
{
private readonly AppContextSwitchScope _switchScope;
private readonly WinFormsAppContextSwitchScope _switchScope;

public BinaryFormatterInClipboardDragDropScope(bool enable)
{
Monitor.Enter(typeof(BinaryFormatterInClipboardDragDropScope));
_switchScope = new(AppContextSwitchNames.ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName, enable);
_switchScope = new(WinFormsAppContextSwitchNames.ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName, enable);
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace System;

public readonly ref struct NrbfSerializerInClipboardDragDropScope
{
private readonly AppContextSwitchScope _switchScope;
private readonly WinFormsAppContextSwitchScope _switchScope;

public NrbfSerializerInClipboardDragDropScope(bool enable)
{
Monitor.Enter(typeof(NrbfSerializerInClipboardDragDropScope));
_switchScope = new(AppContextSwitchNames.ClipboardDragDropEnableNrbfSerializationSwitchName, enable);
_switchScope = new(WinFormsAppContextSwitchNames.ClipboardDragDropEnableNrbfSerializationSwitchName, enable);
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.Serialization.Formatters.Binary;

namespace System;

public static class WinFormsAppContextSwitchNames
Expand Down Expand Up @@ -50,4 +52,16 @@ public const string ServicePointManagerCheckCrl
/// </summary>
public const string TreeNodeCollectionAddRangeRespectsSortOrder
= "System.Windows.Forms.ApplyParentFontToMenus";

/// <summary>
/// The switch that controls whether or not the <see cref="BinaryFormatter"/> is enabled in the Clipboard.
/// </summary>
public const string ClipboardDragDropEnableUnsafeBinaryFormatterSerializationSwitchName
= "Windows.ClipboardDragDrop.EnableUnsafeBinaryFormatterSerialization";

/// <summary>
/// The switch that controls whether or not the System.Windows.Forms.BinaryFormat.Deserializer is enabled in the Clipboard.
/// </summary>
public const string ClipboardDragDropEnableNrbfSerializationSwitchName
= "Windows.ClipboardDragDrop.EnableNrbfSerialization";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Windows.Forms.Primitives;

namespace System;

/// <summary>
/// Scope for temporarily setting an <see cref="AppContext"/> switch. Use in a <see langword="using"/> statement.
/// </summary>
/// <remarks>
/// <para>
/// It is recommended to create wrappers for this struct for both simplicity and to allow adding synchronization.
/// See <see cref="BinaryFormatterScope"/> for an example of doing this.
/// </para>
/// </remarks>
public readonly ref struct WinFormsAppContextSwitchScope
{
private readonly string _switchName;
private readonly bool _originalState;

public WinFormsAppContextSwitchScope(string switchName, bool enable)
{
if (!AppContext.TryGetSwitch(AppContextSwitchNames.LocalAppContext_DisableCaching, out bool isEnabled)
|| !isEnabled)
{
// It doesn't make sense to try messing with AppContext switches if they are going to be cached.
throw new InvalidOperationException("LocalAppContext switch caching is not disabled.");
}

if (!AppContext.TryGetSwitch(switchName, out _originalState))
{
var getDefaultValue = typeof(LocalAppContextSwitches).TestAccessor().CreateDelegate<Func<string, bool>>("GetSwitchDefaultValue");
_originalState = getDefaultValue(switchName);
}

AppContext.SetSwitch(switchName, enable);
if (!AppContext.TryGetSwitch(switchName, out isEnabled) || isEnabled != enable)
{
throw new InvalidOperationException($"Could not set {switchName} to {enable}.");
}

_switchName = switchName;
}

public void Dispose()
{
AppContext.SetSwitch(_switchName, _originalState);
if (!AppContext.TryGetSwitch(_switchName, out bool isEnabled) || isEnabled != _originalState)
{
throw new InvalidOperationException($"Could not reset {_switchName} to {_originalState}.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace System.Windows.Forms.Tests;
// Note: each registered Clipboard format is an OS singleton
// and we should not run this test at the same time as other tests using the same format.
[Collection("Sequential")]
[UISettings(MaxAttempts = 3)] // Try up to 3 times before failing.
// [UISettings(MaxAttempts = 3)] // Try up to 3 times before failing.
public class ClipboardTests
{
#pragma warning disable WFDEV005 // Type or member is obsolete
Expand Down Expand Up @@ -659,6 +659,8 @@ public void Clipboard_BinaryFormatter_AppContextSwitch()
{
LocalAppContextSwitches.ClipboardDragDropEnableUnsafeBinaryFormatterSerialization.Should().BeFalse();
}

LocalAppContextSwitches.ClipboardDragDropEnableUnsafeBinaryFormatterSerialization.Should().BeFalse();
}

[WinFormsFact]
Expand All @@ -678,6 +680,8 @@ public void Clipboard_NrbfSerializer_AppContextSwitch()
{
LocalAppContextSwitches.ClipboardDragDropEnableNrbfSerialization.Should().BeTrue();
}

LocalAppContextSwitches.ClipboardDragDropEnableNrbfSerialization.Should().BeTrue();
}

[WinFormsFact]
Expand Down

0 comments on commit 18e6274

Please sign in to comment.