// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package elf

import (
	"bytes"
	"debug/elf"
	"encoding/binary"
	"reflect"
	"testing"
)

func Test_elfIdentifierFromReaderAt_BadElfFile(t *testing.T) {
	tests := []struct {
		name     string
		contents string
	}{
		{
			name:     "empty",
			contents: "",
		},
		{
			name:     "text",
			contents: "#!/bin/bash\necho foobar",
		},
		{
			name:     "empty elf",
			contents: emptyElfFile(),
		},
		{
			name:     "short section header",
			contents: shortSectionHeaderElfFile(),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			buf := bytes.NewReader([]byte(tt.contents))
			_, err := elfIdentifierFromReaderAt(buf, "<>", false)
			if err == nil {
				t.Errorf("expected error reading bad elf file without allowMissing")
			}
			_, err = elfIdentifierFromReaderAt(buf, "<>", true)
			if err != nil {
				t.Errorf("expected no error reading bad elf file with allowMissing, got %q", err.Error())
			}
		})
	}
}

func Test_readNote(t *testing.T) {
	note := []byte{
		0x04, 0x00, 0x00, 0x00,
		0x10, 0x00, 0x00, 0x00,
		0x03, 0x00, 0x00, 0x00,
		0x47, 0x4e, 0x55, 0x00,
		0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7,
	}

	descs, err := readNote(bytes.NewBuffer(note), binary.LittleEndian)
	if err != nil {
		t.Fatalf("unexpected error in readNote: %s", err)
	}

	expectedDescs := map[string][]byte{
		"GNU\x00": []byte{0xca, 0xaf, 0x44, 0xd2, 0x82, 0x78, 0x68, 0xfe, 0xc0, 0x90, 0xa3, 0x43, 0x85, 0x36, 0x6c, 0xc7},
	}

	if !reflect.DeepEqual(descs, expectedDescs) {
		t.Errorf("incorrect return, want %#v got %#v", expectedDescs, descs)
	}
}

// emptyElfFile returns an elf file header with no program headers or sections.
func emptyElfFile() string {
	ident := [elf.EI_NIDENT]byte{}
	identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT])
	binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF"))
	binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64)
	binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB)
	binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT)
	binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX)
	binary.Write(identBuf, binary.LittleEndian, make([]byte, 8))

	header := elf.Header64{
		Ident:     ident,
		Type:      uint16(elf.ET_EXEC),
		Machine:   uint16(elf.EM_X86_64),
		Version:   uint32(elf.EV_CURRENT),
		Entry:     0,
		Phoff:     uint64(binary.Size(elf.Header64{})),
		Shoff:     uint64(binary.Size(elf.Header64{})),
		Flags:     0,
		Ehsize:    uint16(binary.Size(elf.Header64{})),
		Phentsize: 0x38,
		Phnum:     0,
		Shentsize: 0x40,
		Shnum:     0,
		Shstrndx:  0,
	}

	buf := &bytes.Buffer{}
	binary.Write(buf, binary.LittleEndian, header)
	return buf.String()
}

// shortSectionHeader returns an elf file header with a section header that extends past the end of
// the file.
func shortSectionHeaderElfFile() string {
	ident := [elf.EI_NIDENT]byte{}
	identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT])
	binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF"))
	binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64)
	binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB)
	binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT)
	binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX)
	binary.Write(identBuf, binary.LittleEndian, make([]byte, 8))

	header := elf.Header64{
		Ident:     ident,
		Type:      uint16(elf.ET_EXEC),
		Machine:   uint16(elf.EM_X86_64),
		Version:   uint32(elf.EV_CURRENT),
		Entry:     0,
		Phoff:     uint64(binary.Size(elf.Header64{})),
		Shoff:     uint64(binary.Size(elf.Header64{})),
		Flags:     0,
		Ehsize:    uint16(binary.Size(elf.Header64{})),
		Phentsize: 0x38,
		Phnum:     0,
		Shentsize: 0x40,
		Shnum:     1,
		Shstrndx:  0,
	}

	buf := &bytes.Buffer{}
	binary.Write(buf, binary.LittleEndian, header)
	binary.Write(buf, binary.LittleEndian, []byte{0})
	return buf.String()
}
