]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: allow cgo to pass strings or []bytes bigger than 1<<30
authorKeith Randall <khr@golang.org>
Wed, 20 Jul 2022 19:46:33 +0000 (12:46 -0700)
committerKeith Randall <khr@google.com>
Wed, 20 Jul 2022 23:32:27 +0000 (23:32 +0000)
There's no real reason to limit to 1<<30 bytes. Maybe it would catch
some mistakes, but probably ones that would quickly manifest in other
ways.

We can't use the fancy new unsafe.Slice function because this code
may still be generated for people with 1.16 or earlier in their go.mod file.
Use unsafe shenanigans instead.

Fixes #53965
Fixes #53958

Change-Id: Ibfa095192f50276091d6c2532e8ccd7832b57ca8
Reviewed-on: https://go-review.googlesource.com/c/go/+/418557
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/cgo/out.go

index d6740028da9162ec8d9befaa848d565698e278f7..119eca2be79e8cce2d3787573c5164d4fa7cc2b7 100644 (file)
@@ -1653,10 +1653,18 @@ const cStringDef = `
 // freed, such as by calling C.free (be sure to include stdlib.h
 // if C.free is needed).
 func _Cfunc_CString(s string) *_Ctype_char {
+       if len(s)+1 <= 0 {
+               panic("string too large")
+       }
        p := _cgo_cmalloc(uint64(len(s)+1))
-       pp := (*[1<<30]byte)(p)
-       copy(pp[:], s)
-       pp[len(s)] = 0
+       sliceHeader := struct {
+               p   unsafe.Pointer
+               len int
+               cap int
+       }{p, len(s)+1, len(s)+1}
+       b := *(*[]byte)(unsafe.Pointer(&sliceHeader))
+       copy(b, s)
+       b[len(s)] = 0
        return (*_Ctype_char)(p)
 }
 `
@@ -1670,8 +1678,13 @@ const cBytesDef = `
 // if C.free is needed).
 func _Cfunc_CBytes(b []byte) unsafe.Pointer {
        p := _cgo_cmalloc(uint64(len(b)))
-       pp := (*[1<<30]byte)(p)
-       copy(pp[:], b)
+       sliceHeader := struct {
+               p   unsafe.Pointer
+               len int
+               cap int
+       }{p, len(b), len(b)}
+       s := *(*[]byte)(unsafe.Pointer(&sliceHeader))
+       copy(s, b)
        return p
 }
 `