mirror of
https://github.com/taigrr/arc
synced 2025-01-18 04:33:13 -08:00
171 lines
3.1 KiB
Go
171 lines
3.1 KiB
Go
// Copyright (C) 2016 - Will Glozer. All rights reserved.
|
|
|
|
package archive
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"crypto/rand"
|
|
"io"
|
|
"io/ioutil"
|
|
"testing"
|
|
)
|
|
|
|
func TestCreateArchive(t *testing.T) {
|
|
entries := []*tar.Header{
|
|
{Name: "foo", Size: 0},
|
|
{Name: "bar", Size: 1<<16 - 1},
|
|
{Name: "baz", Size: 64},
|
|
}
|
|
key := randomKey()
|
|
|
|
buf, dat, err := createArchive(key, entries)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
r, err := NewReader(buf, key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for i, e := range entries {
|
|
switch next, err := r.Next(); {
|
|
case err != nil:
|
|
t.Fatal(err)
|
|
case e.Name != next.Name:
|
|
t.Fatalf("expected entry name %s got %s", e.Name, next.Name)
|
|
case e.Size != next.Size:
|
|
t.Fatalf("expected entry size %d got %d", e.Size, next.Size)
|
|
}
|
|
|
|
switch b, err := ioutil.ReadAll(r); {
|
|
case err != nil:
|
|
t.Fatal(err)
|
|
case int(e.Size) != len(b):
|
|
t.Fatalf("expected to read %d bytes got %d", e.Size, len(b))
|
|
case !bytes.Equal(b, dat[i]):
|
|
t.Fatalf("expected content '%v' got '%v'", b, dat[i])
|
|
}
|
|
}
|
|
|
|
if !r.Verify() {
|
|
t.Fatal("archive verify failed")
|
|
}
|
|
}
|
|
|
|
func TestVerifyArchive(t *testing.T) {
|
|
entries := []*tar.Header{
|
|
{Name: "foo", Size: 32},
|
|
{Name: "bar", Size: 64},
|
|
}
|
|
key := randomKey()
|
|
|
|
buf, _, err := createArchive(key, entries)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if valid, _ := Verify(buf, key); !valid {
|
|
t.Fatal("archive verify failed")
|
|
}
|
|
}
|
|
|
|
func TestVerifyFailWrongKey(t *testing.T) {
|
|
entries := []*tar.Header{
|
|
{Name: "foo", Size: 32},
|
|
{Name: "bar", Size: 64},
|
|
}
|
|
key := randomKey()
|
|
|
|
buf, _, err := createArchive(key, entries)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
key[0] = ^key[0]
|
|
|
|
if valid, _ := Verify(buf, key); valid {
|
|
t.Fatal("verified invalid archive")
|
|
}
|
|
}
|
|
|
|
func TestVerifyFailByteFlip(t *testing.T) {
|
|
entries := []*tar.Header{
|
|
{Name: "foo", Size: 32},
|
|
{Name: "bar", Size: 64},
|
|
}
|
|
key := randomKey()
|
|
|
|
buf, _, err := createArchive(key, entries)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
archive := buf.Bytes()
|
|
for i, b := range archive {
|
|
archive[i] = ^archive[i]
|
|
|
|
r := bytes.NewReader(archive)
|
|
if valid, _ := Verify(r, key); valid {
|
|
t.Fatal("verified invalid archive at", i)
|
|
}
|
|
|
|
archive[i] = b
|
|
}
|
|
}
|
|
|
|
func TestWriterInvariants(t *testing.T) {
|
|
_, _, err := createArchive(make([]byte, 31), nil)
|
|
if err == nil {
|
|
t.Fatalf("created archive with 31 byte key")
|
|
}
|
|
}
|
|
|
|
func createArchive(key []byte, entries []*tar.Header) (*Buffer, [][]byte, error) {
|
|
buf := &Buffer{}
|
|
|
|
arc, err := NewWriter(buf, key)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
dat := make([][]byte, len(entries))
|
|
|
|
for i, e := range entries {
|
|
err := arc.Add(e)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
dat[i] = make([]byte, e.Size)
|
|
_, err = rand.Read(dat[i])
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
err = arc.Copy(bytes.NewReader(dat[i]), e.Size)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
|
|
tag, _ := arc.Finish()
|
|
copy(buf.Bytes()[0:16], tag)
|
|
|
|
return buf, dat, nil
|
|
}
|
|
|
|
type Buffer struct {
|
|
bytes.Buffer
|
|
}
|
|
|
|
func randomKey() []byte {
|
|
key := make([]byte, 32)
|
|
_, err := io.ReadFull(rand.Reader, key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return key
|
|
}
|