// 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"
	"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 := os.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 := os.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 := os.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))
}
