Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2 - Null reference in SelectedTab setter during RemoveTab call #3365

Open
tznind opened this issue Mar 31, 2024 · 8 comments
Open

v2 - Null reference in SelectedTab setter during RemoveTab call #3365

tznind opened this issue Mar 31, 2024 · 8 comments
Labels

Comments

@tznind
Copy link
Collaborator

tznind commented Mar 31, 2024

Describe the bug

I am updating designer from v2 pre.250 to v2 pre.710.

It seems there has been some changes to TabView, I am now getting a null reference in RemoveTab (within the setter on SelectedTab).

null-ref-tab-select

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Terminal.Gui
  StackTrace:>	Terminal.Gui.dll!Terminal.Gui.TabView.SelectedTab.set(Terminal.Gui.Tab value) Line 501	C#
 	Terminal.Gui.dll!Terminal.Gui.TabView.RemoveTab(Terminal.Gui.Tab tab) Line 698	C#
 	TerminalGuiDesigner.dll!TerminalGuiDesigner.TabViewExtensions.ReOrderTabs(Terminal.Gui.TabView tabView, Terminal.Gui.Tab[] newOrder) Line 58	C#
 	TerminalGuiDesigner.dll!TerminalGuiDesigner.Operations.TabOperations.MoveTabOperation..ctor.AnonymousMethod__0_1(Terminal.Gui.TabView v, Terminal.Gui.Tab[] a) Line 23	C#
 	TerminalGuiDesigner.dll!TerminalGuiDesigner.Operations.Generics.MoveOperation<Terminal.Gui.TabView, Terminal.Gui.Tab>.DoImpl() Line 108	C#
 	TerminalGuiDesigner.dll!TerminalGuiDesigner.Operations.Operation.Do() Line 48	C#
 	UnitTests.dll!UnitTests.Operations.MoveTabOperationTests.TestMoveTab_DoUndo.AnonymousMethod__0(TerminalGuiDesigner.Design d, Terminal.Gui.TabView v) Line 57	C#
 	UnitTests.dll!UnitTests.Tests.RoundTrip<Terminal.Gui.Window, Terminal.Gui.TabView>(System.Action<TerminalGuiDesigner.Design, Terminal.Gui.TabView> adjust, out Terminal.Gui.TabView viewOut, string caller) Line 105	C#
 	UnitTests.dll!UnitTests.Operations.MoveTabOperationTests.TestMoveTab_DoUndo(int idxToMove, int adjustment, int expectedNewIndex, bool expectPossible) Line 41	C#


To Reproduce
Run TestMoveTab_DoUndo in TGD

Expected behavior
No crash

@BDisp
Copy link
Collaborator

BDisp commented Mar 31, 2024

That isn't the current code.

public Tab SelectedTab
{
get => _selectedTab;
set
{
UnSetCurrentTabs ();
Tab old = _selectedTab;
if (_selectedTab is { })
{
if (_selectedTab.View is { })
{
// remove old content
_contentView.Remove (_selectedTab.View);
}
}
_selectedTab = value;
if (value is { })
{
// add new content
if (_selectedTab.View is { })
{
_contentView.Add (_selectedTab.View);
}
}
EnsureSelectedTabIsVisible ();
if (old != value)
{
if (old?.HasFocus == true)
{
SelectedTab.SetFocus ();
}
OnSelectedTabChanged (old, value);
}
}
}

@tznind
Copy link
Collaborator Author

tznind commented Mar 31, 2024

Strange, I get this in 710 and 720, maybe 2.0.0-pre.720 was released from a different branch?

@BDisp
Copy link
Collaborator

BDisp commented Mar 31, 2024

Strange, I get this in 710 and 720, maybe 2.0.0-pre.720 was released from a different branch?

I don't know. You have to wait from the @tig response.

@tznind
Copy link
Collaborator Author

tznind commented Mar 31, 2024

I think my source mapping is off. I have added Terminal.Gui as a submodule and checked out v2_develop. I still get the error (so nuget package probably is latest version) but I now see the correct code:

image

@BDisp
Copy link
Collaborator

BDisp commented Mar 31, 2024

Good catch. Maybe the value is null and setting the _selectedTab to null.

@tznind
Copy link
Collaborator Author

tznind commented Mar 31, 2024

Here is a unit test

[Fact]
public void RemoveTab_ThatHasFocus ()
{
    TabView tv = GetTabView (out Tab tab1, out Tab tab2);

    tv.SelectedTab = tab2;
    tab2.HasFocus = true;

    Assert.Equal (2, tv.Tabs.Count);
    foreach(var t in tv.Tabs.ToArray())
    {
        tv.RemoveTab(t);
    }

    Assert.Equal (0, tv.Tabs.Count);

    // Shutdown must be called to safely clean up Application if Init has been called
    Application.Shutdown ();
}
 Terminal.Gui.ViewsTests.TabViewTests.RemoveTab_ThatHasFocus
   Source: TabViewTests.cs line 30
   Duration: 388 ms

  Message: 
System.NullReferenceException : Object reference not set to an instance of an object.

  Stack Trace: 
TabView.set_SelectedTab(Tab value) line 180
TabView.RemoveTab(Tab tab) line 360
TabViewTests.RemoveTab_ThatHasFocus() line 40
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

@BDisp
Copy link
Collaborator

BDisp commented Mar 31, 2024

Even if old?.HasFocus == true that doesn't mean that there is currently any tab. Do you think SelectedTab?.SetFocus (); is enough?

@tznind
Copy link
Collaborator Author

tznind commented Mar 31, 2024 via email

@tig tig added the bug label Apr 1, 2024
tig added a commit that referenced this issue Apr 14, 2024
Fixes #3365 - Fix null reference removing tab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

3 participants