Skip to content

Commit

Permalink
Replaced a NullReferedeException that was lost in the interop layer w… (
Browse files Browse the repository at this point in the history
#12528)

Replaced a NullReferenceException that was lost in the interop layer with an HRESULT error code recommended in the docs - https://learn.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-idataobject-getdatahere#return-value. The HRESULT is not bubbled up through OleFlushClipboard either, this API returns S_OK even when the data wasn't set. In this case we end up with format being set successfully, but data is actually missing.
  • Loading branch information
Tanya-Solyanik authored Nov 22, 2024
1 parent 200451f commit 441fb2a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ namespace System.Windows.Forms.Design;
/// </summary>
internal class ButtonBaseDesigner : ControlDesigner
{
// private DesignerActionListCollection _actionlists;

public ButtonBaseDesigner()
{
AutoResizeHandles = true;
Expand All @@ -31,7 +29,6 @@ public override void InitializeNewComponent(IDictionary? defaultValues)
{
// Dev10 Bug 685319: We should set the UseVisualStyleBackColor to trun only
// when this property has not been set/changed by user
//
if (!prop.ShouldSerializeValue(Component))
{
prop.SetValue(Component, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,16 @@ HRESULT Com.IDataObject.Interface.GetDataHere(FORMATETC* pformatetc, STGMEDIUM*
return HRESULT.DV_E_FORMATETC;
}

object? data = _dataObject.GetData(format);
if (_dataObject.GetData(format) is not object data)
{
return HRESULT.E_UNEXPECTED;
}

if (((TYMED)pformatetc->tymed).HasFlag(TYMED.TYMED_HGLOBAL))
{
try
{
return SaveDataToHGLOBAL(data!, format, ref *pmedium);
return SaveDataToHGLOBAL(data, format, ref *pmedium);
}
catch (NotSupportedException ex)
{
Expand Down Expand Up @@ -314,7 +317,7 @@ DataFormats.DibConstant when data is Image
_ when format == DataFormats.SerializableConstant || data is ISerializable || data.GetType().IsSerializable
#pragma warning restore
=> SaveObjectToHGLOBAL(ref medium.hGlobal, data, RestrictDeserializationToSafeTypes(format)),
_ => HRESULT.E_FAIL
_ => HRESULT.E_UNEXPECTED
};

private static HRESULT SaveObjectToHGLOBAL(ref HGLOBAL hglobal, object data, bool restrictSerialization)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,26 @@ public void Clipboard_SetData_Invoke_GetReturnsExpected(string format, object? d
[InlineData(null)]
public void Clipboard_SetData_EmptyOrWhitespaceFormat_ThrowsArgumentException(string? format)
{
Action action = () => Clipboard.SetData(format!, data: null!);
Action action = () => Clipboard.SetData(format!, "data");
action.Should().Throw<ArgumentException>().WithParameterName("format");
}

[WinFormsFact]
public void Clipboard_SetData_null_Success()
public void Clipboard_SetData_null_NotThrow()
{
Action action = () => Clipboard.SetData("MyData", data: null!);
action.Should().NotThrow();
try
{
Action action = () => Clipboard.SetData("MyData", data: null!);
action.Should().NotThrow();
// Clipboard flushes format only, content is not stored.
// GetData will hit "Data on clipboard is invalid (0x800401D3 (CLIPBRD_E_BAD_DATA))"
Clipboard.ContainsData("MyData").Should().BeTrue();
Clipboard.GetData("MyData").Should().BeNull();
}
finally
{
Clipboard.Clear();
}
}

[WinFormsTheory]
Expand All @@ -264,8 +275,7 @@ public void Clipboard_SetDataObject_InvokeObjectIComDataObject_GetReturnsExpecte
DataObject dataObject = new(data);
Clipboard.SetDataObject(dataObject);

var actual = Clipboard.GetDataObject();
Assert.NotNull(actual);
DataObject actual = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Subject;
actual.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
Expand All @@ -279,8 +289,7 @@ public void Clipboard_SetDataObject_InvokeObjectBoolNotIComDataObject_GetReturns
{
Clipboard.SetDataObject(data, copy);

var dataObject = Clipboard.GetDataObject();
Assert.NotNull(dataObject);
DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Subject;
dataObject.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
Expand Down

0 comments on commit 441fb2a

Please sign in to comment.