// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Tests that cgo detects invalid pointer passing at runtime.

package errorstest

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

// ptrTest is the tests without the boilerplate.
type ptrTest struct {
	name      string   // for reporting
	c         string   // the cgo comment
	imports   []string // a list of imports
	support   string   // supporting functions
	body      string   // the body of the main function
	extra     []extra  // extra files
	fail      bool     // whether the test should fail
	expensive bool     // whether the test requires the expensive check
}

type extra struct {
	name     string
	contents string
}

var ptrTests = []ptrTest{
	{
		// Passing a pointer to a struct that contains a Go pointer.
		name: "ptr1",
		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
		body: `C.f(&C.s{new(C.int)})`,
		fail: true,
	},
	{
		// Passing a pointer to a struct that contains a Go pointer.
		name: "ptr2",
		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
		body: `p := &C.s{new(C.int)}; C.f(p)`,
		fail: true,
	},
	{
		// Passing a pointer to an int field of a Go struct
		// that (irrelevantly) contains a Go pointer.
		name: "ok1",
		c:    `struct s { int i; int *p; }; void f(int *p) {}`,
		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`,
		fail: false,
	},
	{
		// Passing a pointer to a pointer field of a Go struct.
		name: "ptr-field",
		c:    `struct s { int i; int *p; }; void f(int **p) {}`,
		body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`,
		fail: true,
	},
	{
		// Passing a pointer to a pointer field of a Go
		// struct, where the field does not contain a Go
		// pointer, but another field (irrelevantly) does.
		name: "ptr-field-ok",
		c:    `struct s { int *p1; int *p2; }; void f(int **p) {}`,
		body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`,
		fail: false,
	},
	{
		// Passing the address of a slice with no Go pointers.
		name:    "slice-ok-1",
		c:       `void f(void **p) {}`,
		imports: []string{"unsafe"},
		body:    `s := []unsafe.Pointer{nil}; C.f(&s[0])`,
		fail:    false,
	},
	{
		// Passing the address of a slice with a Go pointer.
		name:    "slice-ptr-1",
		c:       `void f(void **p) {}`,
		imports: []string{"unsafe"},
		body:    `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`,
		fail:    true,
	},
	{
		// Passing the address of a slice with a Go pointer,
		// where we are passing the address of an element that
		// is not a Go pointer.
		name:    "slice-ptr-2",
		c:       `void f(void **p) {}`,
		imports: []string{"unsafe"},
		body:    `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`,
		fail:    true,
	},
	{
		// Passing the address of a slice that is an element
		// in a struct only looks at the slice.
		name:    "slice-ok-2",
		c:       `void f(void **p) {}`,
		imports: []string{"unsafe"},
		support: `type S struct { p *int; s []unsafe.Pointer }`,
		body:    `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`,
		fail:    false,
	},
	{
		// Passing the address of a slice of an array that is
		// an element in a struct, with a type conversion.
		name:    "slice-ok-3",
		c:       `void f(void* p) {}`,
		imports: []string{"unsafe"},
		support: `type S struct { p *int; a [4]byte }`,
		body:    `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`,
		fail:    false,
	},
	{
		// Passing the address of a slice of an array that is
		// an element in a struct, with a type conversion.
		name:    "slice-ok-4",
		c:       `typedef void* PV; void f(PV p) {}`,
		imports: []string{"unsafe"},
		support: `type S struct { p *int; a [4]byte }`,
		body:    `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
		fail:    false,
	},
	{
		// Passing the address of a static variable with no
		// pointers doesn't matter.
		name:    "varok",
		c:       `void f(char** parg) {}`,
		support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`,
		body:    `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`,
		fail:    false,
	},
	{
		// Passing the address of a static variable with
		// pointers does matter.
		name:    "var",
		c:       `void f(char*** parg) {}`,
		support: `var hello = [...]*C.char{new(C.char)}`,
		body:    `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`,
		fail:    true,
	},
	{
		// Storing a Go pointer into C memory should fail.
		name: "barrier",
		c: `#include <stdlib.h>
                    char **f1() { return malloc(sizeof(char*)); }
                    void f2(char **p) {}`,
		body:      `p := C.f1(); *p = new(C.char); C.f2(p)`,
		fail:      true,
		expensive: true,
	},
	{
		// Storing a Go pointer into C memory by assigning a
		// large value should fail.
		name: "barrier-struct",
		c: `#include <stdlib.h>
                    struct s { char *a[10]; };
                    struct s *f1() { return malloc(sizeof(struct s)); }
                    void f2(struct s *p) {}`,
		body:      `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`,
		fail:      true,
		expensive: true,
	},
	{
		// Storing a Go pointer into C memory using a slice
		// copy should fail.
		name: "barrier-slice",
		c: `#include <stdlib.h>
                    struct s { char *a[10]; };
                    struct s *f1() { return malloc(sizeof(struct s)); }
                    void f2(struct s *p) {}`,
		body:      `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`,
		fail:      true,
		expensive: true,
	},
	{
		// A very large value uses a GC program, which is a
		// different code path.
		name: "barrier-gcprog-array",
		c: `#include <stdlib.h>
                    struct s { char *a[32769]; };
                    struct s *f1() { return malloc(sizeof(struct s)); }
                    void f2(struct s *p) {}`,
		body:      `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`,
		fail:      true,
		expensive: true,
	},
	{
		// Similar case, with a source on the heap.
		name: "barrier-gcprog-array-heap",
		c: `#include <stdlib.h>
                    struct s { char *a[32769]; };
                    struct s *f1() { return malloc(sizeof(struct s)); }
                    void f2(struct s *p) {}
                    void f3(void *p) {}`,
		imports:   []string{"unsafe"},
		body:      `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`,
		fail:      true,
		expensive: true,
	},
	{
		// A GC program with a struct.
		name: "barrier-gcprog-struct",
		c: `#include <stdlib.h>
                    struct s { char *a[32769]; };
                    struct s2 { struct s f; };
                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
                    void f2(struct s2 *p) {}`,
		body:      `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`,
		fail:      true,
		expensive: true,
	},
	{
		// Similar case, with a source on the heap.
		name: "barrier-gcprog-struct-heap",
		c: `#include <stdlib.h>
                    struct s { char *a[32769]; };
                    struct s2 { struct s f; };
                    struct s2 *f1() { return malloc(sizeof(struct s2)); }
                    void f2(struct s2 *p) {}
                    void f3(void *p) {}`,
		imports:   []string{"unsafe"},
		body:      `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`,
		fail:      true,
		expensive: true,
	},
	{
		// Exported functions may not return Go pointers.
		name: "export1",
		c:    `extern unsigned char *GoFn();`,
		support: `//export GoFn
                          func GoFn() *byte { return new(byte) }`,
		body: `C.GoFn()`,
		fail: true,
	},
	{
		// Returning a C pointer is fine.
		name: "exportok",
		c: `#include <stdlib.h>
                    extern unsigned char *GoFn();`,
		support: `//export GoFn
                          func GoFn() *byte { return (*byte)(C.malloc(1)) }`,
		body: `C.GoFn()`,
	},
	{
		// Passing a Go string is fine.
		name: "pass-string",
		c: `#include <stddef.h>
                    typedef struct { const char *p; ptrdiff_t n; } gostring;
                    gostring f(gostring s) { return s; }`,
		imports: []string{"unsafe"},
		body:    `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
	},
	{
		// Passing a slice of Go strings fails.
		name:    "pass-string-slice",
		c:       `void f(void *p) {}`,
		imports: []string{"strings", "unsafe"},
		support: `type S struct { a [1]string }`,
		body:    `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`,
		fail:    true,
	},
	{
		// Exported functions may not return strings.
		name:    "ret-string",
		c:       `extern void f();`,
		imports: []string{"strings"},
		support: `//export GoStr
                          func GoStr() string { return strings.Repeat("a", 2) }`,
		body: `C.f()`,
		extra: []extra{
			{
				"call.c",
				`#include <stddef.h>
                                 typedef struct { const char *p; ptrdiff_t n; } gostring;
                                 extern gostring GoStr();
                                 void f() { GoStr(); }`,
			},
		},
		fail: true,
	},
	{
		// Don't check non-pointer data.
		// Uses unsafe code to get a pointer we shouldn't check.
		// Although we use unsafe, the uintptr represents an integer
		// that happens to have the same representation as a pointer;
		// that is, we are testing something that is not unsafe.
		name: "ptrdata1",
		c: `#include <stdlib.h>
                    void f(void* p) {}`,
		imports: []string{"unsafe"},
		support: `type S struct { p *int; a [8*8]byte; u uintptr }`,
		body:    `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`,
		fail:    false,
	},
	{
		// Like ptrdata1, but with a type that uses a GC program.
		name: "ptrdata2",
		c: `#include <stdlib.h>
                    void f(void* p) {}`,
		imports: []string{"unsafe"},
		support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
		body:    `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`,
		fail:    false,
	},
	{
		// Check deferred pointers when they are used, not
		// when the defer statement is run.
		name: "defer",
		c:    `typedef struct s { int *p; } s; void f(s *ps) {}`,
		body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`,
		fail: true,
	},
	{
		// Check a pointer to a union if the union has any
		// pointer fields.
		name:    "union1",
		c:       `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`,
		imports: []string{"unsafe"},
		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
		fail:    true,
	},
	{
		// Don't check a pointer to a union if the union does
		// not have any pointer fields.
		// Like ptrdata1 above, the uintptr represents an
		// integer that happens to have the same
		// representation as a pointer.
		name:    "union2",
		c:       `typedef union { unsigned long i; } u; void f(u *pu) {}`,
		imports: []string{"unsafe"},
		body:    `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
		fail:    false,
	},
	{
		// Test preemption while entering a cgo call. Issue #21306.
		name:    "preempt-during-call",
		c:       `void f() {}`,
		imports: []string{"runtime", "sync"},
		body:    `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
		fail:    false,
	},
}

func TestPointerChecks(t *testing.T) {
	for _, pt := range ptrTests {
		pt := pt
		t.Run(pt.name, func(t *testing.T) {
			testOne(t, pt)
		})
	}
}

func testOne(t *testing.T, pt ptrTest) {
	t.Parallel()

	gopath, err := ioutil.TempDir("", filepath.Base(t.Name()))
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(gopath)

	src := filepath.Join(gopath, "src")
	if err := os.Mkdir(src, 0777); err != nil {
		t.Fatal(err)
	}

	name := filepath.Join(src, fmt.Sprintf("%s.go", filepath.Base(t.Name())))
	f, err := os.Create(name)
	if err != nil {
		t.Fatal(err)
	}

	b := bufio.NewWriter(f)
	fmt.Fprintln(b, `package main`)
	fmt.Fprintln(b)
	fmt.Fprintln(b, `/*`)
	fmt.Fprintln(b, pt.c)
	fmt.Fprintln(b, `*/`)
	fmt.Fprintln(b, `import "C"`)
	fmt.Fprintln(b)
	for _, imp := range pt.imports {
		fmt.Fprintln(b, `import "`+imp+`"`)
	}
	if len(pt.imports) > 0 {
		fmt.Fprintln(b)
	}
	if len(pt.support) > 0 {
		fmt.Fprintln(b, pt.support)
		fmt.Fprintln(b)
	}
	fmt.Fprintln(b, `func main() {`)
	fmt.Fprintln(b, pt.body)
	fmt.Fprintln(b, `}`)

	if err := b.Flush(); err != nil {
		t.Fatalf("flushing %s: %v", name, err)
	}
	if err := f.Close(); err != nil {
		t.Fatalf("closing %s: %v", name, err)
	}

	for _, e := range pt.extra {
		if err := ioutil.WriteFile(filepath.Join(src, e.name), []byte(e.contents), 0644); err != nil {
			t.Fatalf("writing %s: %v", e.name, err)
		}
	}

	args := func(cmd *exec.Cmd) string {
		return strings.Join(cmd.Args, " ")
	}

	cmd := exec.Command("go", "build")
	cmd.Dir = src
	cmd.Env = addEnv("GOPATH", gopath)
	buf, err := cmd.CombinedOutput()
	if err != nil {
		t.Logf("%#q:\n%s", args(cmd), buf)
		t.Fatalf("failed to build: %v", err)
	}

	exe := filepath.Join(src, filepath.Base(src))
	cmd = exec.Command(exe)
	cmd.Dir = src

	if pt.expensive {
		cmd.Env = cgocheckEnv("1")
		buf, err := cmd.CombinedOutput()
		if err != nil {
			t.Logf("%#q:\n%s", args(cmd), buf)
			if pt.fail {
				t.Fatalf("test marked expensive, but failed when not expensive: %v", err)
			} else {
				t.Errorf("failed unexpectedly with GODEBUG=cgocheck=1: %v", err)
			}
		}

		cmd = exec.Command(exe)
		cmd.Dir = src
	}

	if pt.expensive {
		cmd.Env = cgocheckEnv("2")
	}

	buf, err = cmd.CombinedOutput()
	if pt.fail {
		if err == nil {
			t.Logf("%#q:\n%s", args(cmd), buf)
			t.Fatalf("did not fail as expected")
		} else if !bytes.Contains(buf, []byte("Go pointer")) {
			t.Logf("%#q:\n%s", args(cmd), buf)
			t.Fatalf("did not print expected error (failed with %v)", err)
		}
	} else {
		if err != nil {
			t.Logf("%#q:\n%s", args(cmd), buf)
			t.Fatalf("failed unexpectedly: %v", err)
		}

		if !pt.expensive {
			// Make sure it passes with the expensive checks.
			cmd := exec.Command(exe)
			cmd.Dir = src
			cmd.Env = cgocheckEnv("2")
			buf, err := cmd.CombinedOutput()
			if err != nil {
				t.Logf("%#q:\n%s", args(cmd), buf)
				t.Fatalf("failed unexpectedly with expensive checks: %v", err)
			}
		}
	}

	if pt.fail {
		cmd = exec.Command(exe)
		cmd.Dir = src
		cmd.Env = cgocheckEnv("0")
		buf, err := cmd.CombinedOutput()
		if err != nil {
			t.Logf("%#q:\n%s", args(cmd), buf)
			t.Fatalf("failed unexpectedly with GODEBUG=cgocheck=0: %v", err)
		}
	}
}

func cgocheckEnv(val string) []string {
	return addEnv("GODEBUG", "cgocheck="+val)
}

func addEnv(key, val string) []string {
	env := []string{key + "=" + val}
	look := key + "="
	for _, e := range os.Environ() {
		if !strings.HasPrefix(e, look) {
			env = append(env, e)
		}
	}
	return env
}
