fyne-io/terminal

panic: runtime error: index out of range [-2]

Closed this issue ยท 3 comments

Hello. First of all, awesome tool and library btw <3. I'm not sure if this can considered a bug, but since it panics I thought I'd share what I tried to do.

I was just trying out the local-shell usage given in the README with the following code.

package main

import (
	"image/color"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"github.com/fyne-io/terminal"
)

func guessCellSize() fyne.Size {
	cell := canvas.NewText("M", color.White)
	cell.TextStyle.Monospace = true

	return cell.MinSize()
}

func main() {
	a := app.New()
	w := a.NewWindow("TabContainer Widget")
	t := terminal.New()
	w.SetContent(t)

	// cellSize := guessCellSize()
	// w.Resize(fyne.NewSize(cellSize.Width*80, cellSize.Height*24))
	// w.Canvas().Focus(t)

	go func() {
		err := t.RunLocalShell()
		if err != nil {
			fyne.LogError("Failure in terminal", err)
		}
		w.Close()
		a.Quit()
	}()
	w.ShowAndRun()
}

Trying to run this will cause a panic

$  go run .\main.go
panic: runtime error: index out of range [-2]

goroutine 21 [running]:
github.com/fyne-io/terminal.(*Terminal).handleOutputChar(0xc0000c0000, 0x57)
        C:/Users/91892/go/pkg/mod/github.com/fyne-io/terminal@v0.0.0-20220212001655-58bffee6364f/output.go:128 +0x3a7
github.com/fyne-io/terminal.(*Terminal).handleOutput(0xc0000c0000, {0xc00044a000, 0xdb, 0xc0000adf68?})
        C:/Users/91892/go/pkg/mod/github.com/fyne-io/terminal@v0.0.0-20220212001655-58bffee6364f/output.go:108 +0x4d8
github.com/fyne-io/terminal.(*Terminal).run(0xc0000c0000)
        C:/Users/91892/go/pkg/mod/github.com/fyne-io/terminal@v0.0.0-20220212001655-58bffee6364f/term.go:237 +0x130
github.com/fyne-io/terminal.(*Terminal).RunLocalShell(0xc0000c0000)
        C:/Users/91892/go/pkg/mod/github.com/fyne-io/terminal@v0.0.0-20220212001655-58bffee6364f/term.go:254 +0x52
main.main.func1()
        C:/Users/91892/golang/win/bug/main.go:30 +0x45
created by main.main
        C:/Users/91892/golang/win/bug/main.go:29 +0x10e
exit status 2

I tried to debug it, and found that in output.go,

func (t *Terminal) handleOutputChar(r rune) {
	if t.cursorCol >= int(t.config.Columns) || t.cursorRow >= int(t.config.Rows) {
		return // TODO handle wrap?
	}
	for len(t.content.Rows)-1 < t.cursorRow {
		t.content.Rows = append(t.content.Rows, widget.TextGridRow{})
	}

	cellStyle := &widget.CustomTextGridStyle{FGColor: t.currentFG, BGColor: t.currentBG}
	for len(t.content.Rows[t.cursorRow].Cells)-1 < t.cursorCol {    // <------ here the `t.content.Rows` is empty and `t.cursorRow` is -2, which seems to cause the panic ?
		newCell := widget.TextGridCell{
			Rune:  ' ',
			Style: cellStyle,
		}
		t.content.Rows[t.cursorRow].Cells = append(t.content.Rows[t.cursorRow].Cells, newCell)
	}

Though being a noob, I am not sure how that is being set to negative value.

But regardless, if I properly set the win size using

...
cellSize := guessCellSize()
w.Resize(fyne.NewSize(cellSize.Width*80, cellSize.Height*24))
w.Canvas().Focus(t)
...

it works fine ๐Ÿ‘ . Just wanted to share this.

Thanks

Hello. First of all, awesome tool and library btw <3

Thank you so much :)

I'm not sure if this can considered a bug, but since it panics I thought I'd share what I tried to do.

Quite right - it should never crash, just like all of Fyne :)

Thanks for the report. We should more gracefully handle the impossibly small size corner case.
Or we could decide that a larger minimum size is required for a terminal widget ;)

Yeah ๐Ÿ˜„

Fixed, thanks for the report :).