From 821f8bfd95835fed19a743b38b91620f3be4098b Mon Sep 17 00:00:00 2001 From: Matteo Kloiber Date: Wed, 15 Apr 2015 13:35:12 +0200 Subject: [PATCH] Fixes unsafe pointer madness. `func uiEvt(e termbox.Event) Event` used to change the type of termbox.Event to Event by using some pointer-cast magic[1], which could cause an overflow if `termbox.Event` changes its structure. I'd rather just have `type Event termbox.Event` but that would break backwards compatibility. Warning: A buffer overflow could cause a serious security issue but it is very unlikely that anyone could exploit that (though not impossbible). You'd need to push a upstream update to termbox, which would tweak termbox.Event's structure. Still, this issue should be fixed and unsafe should never be used. [1] it used to get the address of termbox.Event and just cast a Event pointer --- events.go | 15 +++++++++++++-- events_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 events_test.go diff --git a/events.go b/events.go index f5c3dc0..23a189b 100644 --- a/events.go +++ b/events.go @@ -9,7 +9,6 @@ package termui import "github.com/nsf/termbox-go" -import "unsafe" /***********************************termbox-go**************************************/ @@ -133,7 +132,19 @@ const ( // convert termbox.Event to termui.Event func uiEvt(e termbox.Event) Event { - return *(*Event)(unsafe.Pointer(&e)) + event := Event{} + event.Type = EventType(e.Type) + event.Mod = Modifier(e.Mod) + event.Key = Key(e.Key) + event.Ch = e.Ch + event.Width = e.Width + event.Height = e.Height + event.Err = e.Err + event.MouseX = e.MouseX + event.MouseY = e.MouseY + event.N = e.N + + return event } var evtChs = make([]chan Event, 0) diff --git a/events_test.go b/events_test.go new file mode 100644 index 0000000..1137b1d --- /dev/null +++ b/events_test.go @@ -0,0 +1,28 @@ +// Copyright 2015 Zack Guo . All rights reserved. +// Use of this source code is governed by a MIT license that can +// be found in the LICENSE file. +// +// Portions of this file uses [termbox-go](https://github.com/nsf/termbox-go/blob/54b74d087b7c397c402d0e3b66d2ccb6eaf5c2b4/api_common.go) +// by [authors](https://github.com/nsf/termbox-go/blob/master/AUTHORS) +// under [license](https://github.com/nsf/termbox-go/blob/master/LICENSE) + +package termui + +import ( + "errors" + "testing" + + termbox "github.com/nsf/termbox-go" + "github.com/stretchr/testify/assert" +) + +type boxEvent termbox.Event + +func TestUiEvt(t *testing.T) { + err := errors.New("This is a mock error") + event := boxEvent{3, 5, 2, 'H', 200, 500, err, 50, 30, 2} + expetced := Event{3, 5, 2, 'H', 200, 500, err, 50, 30, 2} + + // We need to do that ugly casting so that vet does not complain + assert.Equal(t, uiEvt(termbox.Event(event)), expetced) +}