From 387646029eec6678cdb383b5f80d31595db9b5fd Mon Sep 17 00:00:00 2001 From: b-long Date: Thu, 4 Jun 2026 17:40:51 -0400 Subject: [PATCH] Fix SIGABRT crash when converting 0-length Go []byte to Python bytes (#359) `Slice_byte_to_bytes` indexed `s[0]` unconditionally, causing a runtime panic on empty slices. Guard with an early return via `PyBytes_FromStringAndSize(nil, 0)` which the CPython API handles correctly. --- _examples/gobytes/test.py | 7 +++++++ bind/gen_slice.go | 5 +++++ main_test.go | 2 ++ 3 files changed, 14 insertions(+) diff --git a/_examples/gobytes/test.py b/_examples/gobytes/test.py index 09887bc4..a5ad7183 100644 --- a/_examples/gobytes/test.py +++ b/_examples/gobytes/test.py @@ -15,4 +15,11 @@ print("Python bytes to Go: ", go.Slice_byte.from_bytes(a)) print("Go bytes to Python: ", bytes(go.Slice_byte([3, 4, 5]))) +# Regression test for issue #359: 0-length slice must not crash +empty = gobytes.CreateBytes(0) +print("Go empty slice: ", empty) +empty_bytes = bytes(empty) +assert empty_bytes == b"", f"expected b'', got {empty_bytes!r}" +print("Go empty bytes to Python: ", empty_bytes) + print("OK") diff --git a/bind/gen_slice.go b/bind/gen_slice.go index 1c16180c..e0ad3362 100644 --- a/bind/gen_slice.go +++ b/bind/gen_slice.go @@ -411,6 +411,11 @@ otherwise parameter is a python list that we copy from g.gofile.Printf("func Slice_byte_to_bytes(handle CGoHandle) *C.PyObject {\n") g.gofile.Indent() g.gofile.Printf("s := deptrFromHandle_Slice_byte(handle)\n") + g.gofile.Printf("if len(s) == 0 {\n") + g.gofile.Indent() + g.gofile.Printf("return C.PyBytes_FromStringAndSize(nil, 0)\n") + g.gofile.Outdent() + g.gofile.Printf("}\n") g.gofile.Printf("ptr := unsafe.Pointer(&s[0])\n") g.gofile.Printf("size := len(s)\n") if WindowsOS { diff --git a/main_test.go b/main_test.go index 1127698c..77b0fb3e 100644 --- a/main_test.go +++ b/main_test.go @@ -282,6 +282,8 @@ Go slice: go.Slice_byte len: 10 handle: 1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] gobytes.HashBytes from Go bytes: gobytes.Array_4_byte len: 4 handle: 2 [12, 13, 81, 81] Python bytes to Go: go.Slice_byte len: 4 handle: 3 [0, 1, 2, 3] Go bytes to Python: b'\x03\x04\x05' +Go empty slice: go.Slice_byte len: 0 handle: 5 [] +Go empty bytes to Python: b'' OK `), })