From b731919f97512e27a492f44942238c21f442c8d0 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Mon, 21 Nov 2022 13:25:24 +0900 Subject: [PATCH] Fix panic when size 0 passed to malloc --- src/runtime/arch_tinygowasm_malloc.go | 8 ++++++++ tests/runtime_wasi/malloc_test.go | 29 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/runtime/arch_tinygowasm_malloc.go b/src/runtime/arch_tinygowasm_malloc.go index f7f0c5a2..06ae96ca 100644 --- a/src/runtime/arch_tinygowasm_malloc.go +++ b/src/runtime/arch_tinygowasm_malloc.go @@ -13,6 +13,9 @@ var allocs = make(map[uintptr][]byte) //export malloc func libc_malloc(size uintptr) unsafe.Pointer { + if size == 0 { + return nil + } buf := make([]byte, size) ptr := unsafe.Pointer(&buf[0]) allocs[uintptr(ptr)] = buf @@ -39,6 +42,11 @@ func libc_calloc(nmemb, size uintptr) unsafe.Pointer { //export realloc func libc_realloc(oldPtr unsafe.Pointer, size uintptr) unsafe.Pointer { + if size == 0 { + libc_free(oldPtr) + return nil + } + // It's hard to optimize this to expand the current buffer with our GC, but // it is theoretically possible. For now, just always allocate fresh. buf := make([]byte, size) diff --git a/tests/runtime_wasi/malloc_test.go b/tests/runtime_wasi/malloc_test.go index 06b197f1..eb655b42 100644 --- a/tests/runtime_wasi/malloc_test.go +++ b/tests/runtime_wasi/malloc_test.go @@ -125,3 +125,32 @@ func TestMallocFree(t *testing.T) { }) } } + +func TestMallocEmpty(t *testing.T) { + ptr := libc_malloc(0) + if ptr != nil { + t.Errorf("expected nil pointer, got %p", ptr) + } +} + +func TestCallocEmpty(t *testing.T) { + ptr := libc_calloc(0, 1) + if ptr != nil { + t.Errorf("expected nil pointer, got %p", ptr) + } + ptr = libc_calloc(1, 0) + if ptr != nil { + t.Errorf("expected nil pointer, got %p", ptr) + } +} + +func TestReallocEmpty(t *testing.T) { + ptr := libc_malloc(1) + if ptr == nil { + t.Error("expected pointer but was nil") + } + ptr = libc_realloc(ptr, 0) + if ptr != nil { + t.Errorf("expected nil pointer, got %p", ptr) + } +}