package buildstep import ( "os" "path/filepath" "reflect" "testing" ) func pe(offset int, magic string) []byte { b := make([]byte, 0x100) copy(b, "MZ") b[0x3c] = byte(offset) copy(b[offset:], magic) return b } func TestExecutableKindTellsProgramsFromText(t *testing.T) { // issue 1577 for _, c := range []struct { name string head []byte want string }{ {"elf", []byte("\x7fELF\x02\x01\x01"), "ELF"}, {"mach-o 64", []byte{0xcf, 0xfa, 0xed, 0xfe, 7, 0, 0, 1}, "Mach-O"}, {"mach-o 32 big", []byte{0xfe, 0xed, 0xfa, 0xce, 0, 0, 0, 7}, "Mach-O"}, {"fat mach-o", []byte{0xca, 0xfe, 0xba, 0xbe, 0, 0, 0, 2}, "Mach-O"}, {"java class", []byte{0xca, 0xfe, 0xba, 0xbe, 0, 0, 0, 0x34}, ""}, {"pe", pe(0x80, "PE\x00\x00"), "PE"}, {"mz text", []byte("MZ is a text file starting with two letters"), ""}, {"mz without a pe header", pe(0x80, "XX\x00\x00"), ""}, {"text", []byte("package main"), ""}, {"empty", nil, ""}, } { if got := ExecutableKind(c.head); got != c.want { t.Errorf("%s: kind = %q, want %q", c.name, got, c.want) } } } func TestProgramsInNamesTheAddedAndModifiedRegularFilesThatArePrograms(t *testing.T) { // issue 1577 dir := t.TempDir() write := func(name string, b []byte) { if err := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, name), b, 0o755); err != nil { t.Fatal(err) } } write("m/prog", []byte("\x7fELF\x02\x01")) write("m/notes", []byte("plain text")) write("m/mac", []byte{0xcf, 0xfa, 0xed, 0xfe, 7, 0, 0, 1}) if err := os.Symlink("prog", filepath.Join(dir, "m/link")); err != nil { t.Fatal(err) } line := func(mode, path string) string { return ":000000 " + mode + " 0000 1111 A\x00" + path + "\x00" } for _, c := range []struct { name, raw string want []Program }{ {"none", "", []Program{}}, {"a program and a text", line("100755", "m/prog") + line("100644", "m/notes"), []Program{{"m/prog", "ELF", ""}}}, {"two programs", line("100644", "m/prog") + line("100755", "m/mac"), []Program{{"m/prog", "ELF", ""}, {"m/mac", "Mach-O", ""}}}, {"a symlink and a submodule are not read", line("120000", "m/link") + line("160000", "m/sub"), []Program{}}, {"a path the tree lacks", line("100644", "m/gone"), []Program{}}, } { if got := programsIn(dir, c.raw); !reflect.DeepEqual(got, c.want) { t.Errorf("%s: programs = %v, want %v", c.name, got, c.want) } } }