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

Null reference in v2 in FindDeepestView #3667

Closed
tznind opened this issue Aug 17, 2024 · 4 comments · Fixed by #3668
Closed

Null reference in v2 in FindDeepestView #3667

tznind opened this issue Aug 17, 2024 · 4 comments · Fixed by #3668
Labels

Comments

@tznind
Copy link
Collaborator

tznind commented Aug 17, 2024

Describe the bug
FindDeepestView can crash when a view has null Margin e.g. MenuBar (in below code start is a MenuBar
image

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Terminal.Gui
  StackTrace:
   at Terminal.Gui.View.FindDeepestView(View start, Point& location) in Terminal.Gui\View.cs:line 2160
@tig
Copy link
Collaborator

tig commented Aug 17, 2024

The only way this can happen is if BeginInit/EndInit was not called on start.

@tig
Copy link
Collaborator

tig commented Aug 18, 2024

The only way this can happen is if BeginInit/EndInit was not called on start.

I take that back. That's old/fake news.

It should not be possible for those to be null if the View constructor was called:

    public View ()
    {
        SetupAdornments ();
        SetupKeyboard ();

        //SetupMouse ();
        SetupText ();
    }

    private void SetupAdornments ()
    {
        //// TODO: Move this to Adornment as a static factory method
        if (this is not Adornment)
        {
            Margin = new (this);
            Border = new (this);
            Padding = new (this);
        }
    }

... Unless the View was disposed...

    private void DisposeAdornments ()
    {
        Margin?.Dispose ();
        Margin = null;
        Border?.Dispose ();
        Border = null;
        Padding?.Dispose ();
        Padding = null;
    }

@BDisp
Copy link
Collaborator

BDisp commented Aug 18, 2024

For sure is that the case. View was already disposed.

@tznind
Copy link
Collaborator Author

tznind commented Aug 18, 2024

Indeed the view being disposed is the bug. Bug originates in TopLevel which seems to have code that dispose the view on Remove.

Remove is not the same as getting rid of permenantly. There are many cases where you might want to remove a view e.g. to add it to a different view. It should not dispose things.

    [Fact]
    public void no_dispose_menu ()
    {
        var mb = new MenuBar ();
        var tl = new Toplevel ();

        Assert.False (mb.WasDisposed);
        tl.Add (mb);
        Assert.False (mb.WasDisposed);
        tl.Remove (mb);
        
        // Currently fails here
        Assert.False (mb.WasDisposed);
    }

BDisp added a commit to BDisp/Terminal.Gui that referenced this issue Aug 18, 2024
@tig tig closed this as completed in #3668 Aug 19, 2024
@tig tig closed this as completed in 9635a43 Aug 19, 2024
tig added a commit that referenced this issue Aug 19, 2024
…r-remove-fix

Fixes #3667. Null reference in v2 in FindDeepestView.
tznind added a commit to gui-cs/TerminalGuiDesigner that referenced this issue Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: ✅ Done
3 participants