From 6b7e3cdc2054e2f0db733a1d209c8641d5a071af Mon Sep 17 00:00:00 2001 From: "Brandon McGinty (chatgpt)" Date: Sun, 9 Aug 2026 18:10:25 -0400 Subject: [PATCH] Guard empty OpenAL capture buffers --- gumble/go-openal/openal/alcCore.go | 77 +++++++++++++++----------- gumble/go-openal/openal/openal_test.go | 9 +++ 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/gumble/go-openal/openal/alcCore.go b/gumble/go-openal/openal/alcCore.go index 82f4d83..644875a 100644 --- a/gumble/go-openal/openal/alcCore.go +++ b/gumble/go-openal/openal/alcCore.go @@ -56,7 +56,7 @@ const ( DefaultDeviceSpecifier = 0x1004 DeviceSpecifier = 0x1005 Extensions = 0x1006 - AllDevicesSpecifier = 0x1013 + AllDevicesSpecifier = 0x1013 ) // ? @@ -78,30 +78,30 @@ const ( CaptureSamples = 0x312 ) -//warning: this function does not free internal pointers -//warning: memory leak +// warning: this function does not free internal pointers +// warning: memory leak func GetStrings(param int32) []string { -start := C.alcGetString(nil,C.ALenum(param)) -ptr := unsafe.Pointer(start) -if ptr == nil { -return nil -} -ret := make([]string,0) -offset := uint(0) -for { -slen := uint(C.strlen((*C.char)(ptr))) -if slen==0 { -break -} -ret=append(ret,C.GoStringN((*C.char)(ptr),C.int(slen))) -ptr = unsafe.Pointer(uintptr(ptr) + uintptr(slen+1)) -offset+=(slen+1) -} -ptr = unsafe.Pointer(uintptr(ptr) - uintptr(offset)) -//This should be freeable; I've tried everything I can think of to free the returned pointer. -//need to make sure alcchar doesn't have a weird free thingie, but that's all I can think of. -//C.free(unsafe.Pointer(start)) -return ret + start := C.alcGetString(nil, C.ALenum(param)) + ptr := unsafe.Pointer(start) + if ptr == nil { + return nil + } + ret := make([]string, 0) + offset := uint(0) + for { + slen := uint(C.strlen((*C.char)(ptr))) + if slen == 0 { + break + } + ret = append(ret, C.GoStringN((*C.char)(ptr), C.int(slen))) + ptr = unsafe.Pointer(uintptr(ptr) + uintptr(slen+1)) + offset += (slen + 1) + } + ptr = unsafe.Pointer(uintptr(ptr) - uintptr(offset)) + // This should be freeable; I've tried everything I can think of to free the returned pointer. + // need to make sure alcchar doesn't have a weird free thingie, but that's all I can think of. + // C.free(unsafe.Pointer(start)) + return ret } type Device struct { @@ -141,7 +141,7 @@ func OpenDevice(name string) *Device { p := C.CString(name) h := C.walcOpenDevice(p) C.free(unsafe.Pointer(p)) - if h==nil { + if h == nil { return nil } return &Device{uintptr((unsafe.Pointer)(h))} @@ -160,13 +160,16 @@ func (self *Device) CreateContext() *Context { // TODO: really a method? // TODO: attrlist support c := C.alcCreateContext(self.cHandle(), nil) - if c==nil { -return nil -} + if c == nil { + return nil + } return &Context{uintptr(unsafe.Pointer(c))} } func (self *Device) GetIntegerv(param uint32, size uint32) (result []int32) { + if size == 0 { + return []int32{} + } result = make([]int32, size) C.walcGetIntegerv(self.cHandle(), C.ALCenum(param), C.ALCsizei(size), unsafe.Pointer(&result[0])) return @@ -187,9 +190,9 @@ func CaptureOpenDevice(name string, freq uint32, format Format, size uint32) *Ca p := C.CString(name) h := C.walcCaptureOpenDevice(p, C.ALCuint(freq), C.ALCenum(format), C.ALCsizei(size)) C.free(unsafe.Pointer(p)) - if h==nil { -return nil -} + if h == nil { + return nil + } return &CaptureDevice{Device{uintptr(unsafe.Pointer(h))}, uint32(format.SampleSize())} } @@ -213,10 +216,16 @@ func (self *CaptureDevice) CaptureStop() { } func (self *CaptureDevice) CaptureTo(data []byte) { + if len(data) == 0 { + return + } C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))/self.sampleSize)) } func (self *CaptureDevice) CaptureToInt16(data []int16) { + if len(data) == 0 { + return + } C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*2/self.sampleSize)) } @@ -229,10 +238,16 @@ func (self *CaptureDevice) CaptureMono16To(data []int16) { } func (self *CaptureDevice) CaptureStereo8To(data [][2]byte) { + if len(data) == 0 { + return + } C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*2/self.sampleSize)) } func (self *CaptureDevice) CaptureStereo16To(data [][2]int16) { + if len(data) == 0 { + return + } C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*4/self.sampleSize)) } diff --git a/gumble/go-openal/openal/openal_test.go b/gumble/go-openal/openal/openal_test.go index 052e8ce..9a6e0af 100644 --- a/gumble/go-openal/openal/openal_test.go +++ b/gumble/go-openal/openal/openal_test.go @@ -45,6 +45,15 @@ func TestEmptySliceAPIsDoNotPanic(t *testing.T) { source.Getiv(0, nil) source.QueueBuffers(nil) source.UnqueueBuffers(nil) + var device openal.Device + if got := device.GetIntegerv(0, 0); len(got) != 0 { + t.Fatalf("got %d integers", len(got)) + } + var capture openal.CaptureDevice + capture.CaptureTo(nil) + capture.CaptureToInt16(nil) + capture.CaptureStereo8To(nil) + capture.CaptureStereo16To(nil) var listener openal.Listener listener.Setfv(0, nil) listener.Setiv(0, nil)