Merge pull request #337 from libgit2/cmn/go16-blob-pointer
Work around the finnicky 1.6 CGo pointer checks
This commit is contained in:
commit
e1467c0641
|
@ -10,6 +10,8 @@ go:
|
||||||
- 1.3
|
- 1.3
|
||||||
- 1.4
|
- 1.4
|
||||||
- 1.5
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- 1.7
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
|
17
blob.go
17
blob.go
|
@ -37,15 +37,24 @@ func (repo *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) {
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
var id C.git_oid
|
var id C.git_oid
|
||||||
var ptr unsafe.Pointer
|
var size C.size_t
|
||||||
|
|
||||||
|
// Go 1.6 added some increased checking of passing pointer to
|
||||||
|
// C, but its check depends on its expectations of waht we
|
||||||
|
// pass to the C function, so unless we take the address of
|
||||||
|
// its contents at the call site itself, it can fail when
|
||||||
|
// 'data' is a slice of a slice.
|
||||||
|
//
|
||||||
|
// When we're given an empty slice, create a dummy one where 0
|
||||||
|
// isn't out of bounds.
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
ptr = unsafe.Pointer(&data[0])
|
size = C.size_t(len(data))
|
||||||
} else {
|
} else {
|
||||||
ptr = unsafe.Pointer(nil)
|
data = []byte{0}
|
||||||
|
size = C.size_t(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
ecode := C.git_blob_create_frombuffer(&id, repo.ptr, ptr, C.size_t(len(data)))
|
ecode := C.git_blob_create_frombuffer(&id, repo.ptr, unsafe.Pointer(&data[0]), size)
|
||||||
if ecode < 0 {
|
if ecode < 0 {
|
||||||
return nil, MakeGitError(ecode)
|
return nil, MakeGitError(ecode)
|
||||||
}
|
}
|
||||||
|
|
24
blob_test.go
24
blob_test.go
|
@ -1,9 +1,21 @@
|
||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type bufWrapper struct {
|
||||||
|
buf [64]byte
|
||||||
|
pointer []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func doublePointerBytes() []byte {
|
||||||
|
o := &bufWrapper{}
|
||||||
|
o.pointer = o.buf[0:10]
|
||||||
|
return o.pointer[0:1]
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateBlobFromBuffer(t *testing.T) {
|
func TestCreateBlobFromBuffer(t *testing.T) {
|
||||||
repo := createTestRepo(t)
|
repo := createTestRepo(t)
|
||||||
defer cleanupTestRepo(t, repo)
|
defer cleanupTestRepo(t, repo)
|
||||||
|
@ -14,4 +26,16 @@ func TestCreateBlobFromBuffer(t *testing.T) {
|
||||||
if id.String() != "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" {
|
if id.String() != "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391" {
|
||||||
t.Fatal("Empty buffer did not deliver empty blob id")
|
t.Fatal("Empty buffer did not deliver empty blob id")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, data := range []([]byte){[]byte("hello there"), doublePointerBytes()} {
|
||||||
|
id, err = repo.CreateBlobFromBuffer(data)
|
||||||
|
checkFatal(t, err)
|
||||||
|
|
||||||
|
blob, err := repo.LookupBlob(id)
|
||||||
|
checkFatal(t, err)
|
||||||
|
if !bytes.Equal(blob.Contents(), data) {
|
||||||
|
t.Fatal("Loaded bytes don't match original bytes:",
|
||||||
|
blob.Contents(), "!=", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue