// Copyright 2020 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.

package errorstest

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

// A manually modified object file could pass unexpected characters
// into the files generated by cgo.

const magicInput = "abcdefghijklmnopqrstuvwxyz0123"
const magicReplace = "\n//go:cgo_ldflag \"-badflag\"\n//"

const cSymbol = "BadSymbol" + magicInput + "Name"
const cDefSource = "int " + cSymbol + " = 1;"
const cRefSource = "extern int " + cSymbol + "; int F() { return " + cSymbol + "; }"

// goSource is the source code for the trivial Go file we use.
// We will replace TMPDIR with the temporary directory name.
const goSource = `
package main

// #cgo LDFLAGS: TMPDIR/cbad.o TMPDIR/cbad.so
// extern int F();
import "C"

func main() {
	println(C.F())
}
`

func TestBadSymbol(t *testing.T) {
	dir := t.TempDir()

	mkdir := func(base string) string {
		ret := filepath.Join(dir, base)
		if err := os.Mkdir(ret, 0755); err != nil {
			t.Fatal(err)
		}
		return ret
	}

	cdir := mkdir("c")
	godir := mkdir("go")

	makeFile := func(mdir, base, source string) string {
		ret := filepath.Join(mdir, base)
		if err := ioutil.WriteFile(ret, []byte(source), 0644); err != nil {
			t.Fatal(err)
		}
		return ret
	}

	cDefFile := makeFile(cdir, "cdef.c", cDefSource)
	cRefFile := makeFile(cdir, "cref.c", cRefSource)

	ccCmd := cCompilerCmd(t)

	cCompile := func(arg, base, src string) string {
		out := filepath.Join(cdir, base)
		run := append(ccCmd, arg, "-o", out, src)
		output, err := exec.Command(run[0], run[1:]...).CombinedOutput()
		if err != nil {
			t.Log(run)
			t.Logf("%s", output)
			t.Fatal(err)
		}
		if err := os.Remove(src); err != nil {
			t.Fatal(err)
		}
		return out
	}

	// Build a shared library that defines a symbol whose name
	// contains magicInput.

	cShared := cCompile("-shared", "c.so", cDefFile)

	// Build an object file that refers to the symbol whose name
	// contains magicInput.

	cObj := cCompile("-c", "c.o", cRefFile)

	// Rewrite the shared library and the object file, replacing
	// magicInput with magicReplace. This will have the effect of
	// introducing a symbol whose name looks like a cgo command.
	// The cgo tool will use that name when it generates the
	// _cgo_import.go file, thus smuggling a magic //go:cgo_ldflag
	// pragma into a Go file. We used to not check the pragmas in
	// _cgo_import.go.

	rewrite := func(from, to string) {
		obj, err := ioutil.ReadFile(from)
		if err != nil {
			t.Fatal(err)
		}

		if bytes.Count(obj, []byte(magicInput)) == 0 {
			t.Fatalf("%s: did not find magic string", from)
		}

		if len(magicInput) != len(magicReplace) {
			t.Fatalf("internal test error: different magic lengths: %d != %d", len(magicInput), len(magicReplace))
		}

		obj = bytes.ReplaceAll(obj, []byte(magicInput), []byte(magicReplace))

		if err := ioutil.WriteFile(to, obj, 0644); err != nil {
			t.Fatal(err)
		}
	}

	cBadShared := filepath.Join(godir, "cbad.so")
	rewrite(cShared, cBadShared)

	cBadObj := filepath.Join(godir, "cbad.o")
	rewrite(cObj, cBadObj)

	goSourceBadObject := strings.ReplaceAll(goSource, "TMPDIR", godir)
	makeFile(godir, "go.go", goSourceBadObject)

	makeFile(godir, "go.mod", "module badsym")

	// Try to build our little package.
	cmd := exec.Command("go", "build", "-ldflags=-v")
	cmd.Dir = godir
	output, err := cmd.CombinedOutput()

	// The build should fail, but we want it to fail because we
	// detected the error, not because we passed a bad flag to the
	// C linker.

	if err == nil {
		t.Errorf("go build succeeded unexpectedly")
	}

	t.Logf("%s", output)

	for _, line := range bytes.Split(output, []byte("\n")) {
		if bytes.Contains(line, []byte("dynamic symbol")) && bytes.Contains(line, []byte("contains unsupported character")) {
			// This is the error from cgo.
			continue
		}

		// We passed -ldflags=-v to see the external linker invocation,
		// which should not include -badflag.
		if bytes.Contains(line, []byte("-badflag")) {
			t.Error("output should not mention -badflag")
		}

		// Also check for compiler errors, just in case.
		// GCC says "unrecognized command line option".
		// clang says "unknown argument".
		if bytes.Contains(line, []byte("unrecognized")) || bytes.Contains(output, []byte("unknown")) {
			t.Error("problem should have been caught before invoking C linker")
		}
	}
}

func cCompilerCmd(t *testing.T) []string {
	cc := []string{goEnv(t, "CC")}

	out := goEnv(t, "GOGCCFLAGS")
	quote := '\000'
	start := 0
	lastSpace := true
	backslash := false
	s := string(out)
	for i, c := range s {
		if quote == '\000' && unicode.IsSpace(c) {
			if !lastSpace {
				cc = append(cc, s[start:i])
				lastSpace = true
			}
		} else {
			if lastSpace {
				start = i
				lastSpace = false
			}
			if quote == '\000' && !backslash && (c == '"' || c == '\'') {
				quote = c
				backslash = false
			} else if !backslash && quote == c {
				quote = '\000'
			} else if (quote == '\000' || quote == '"') && !backslash && c == '\\' {
				backslash = true
			} else {
				backslash = false
			}
		}
	}
	if !lastSpace {
		cc = append(cc, s[start:])
	}
	return cc
}

func goEnv(t *testing.T, key string) string {
	out, err := exec.Command("go", "env", key).CombinedOutput()
	if err != nil {
		t.Logf("go env %s\n", key)
		t.Logf("%s", out)
		t.Fatal(err)
	}
	return strings.TrimSpace(string(out))
}
