github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/fatbin/footer_test.go (about)

     1  // Copyright 2019 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package fatbin
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"testing"
    11  )
    12  
    13  func TestReadWriteFooter(t *testing.T) {
    14  	for _, sz := range []int64{0, 12, 1e12, 1e13 + 4} {
    15  		var b bytes.Buffer
    16  		if _, err := writeFooter(&b, sz); err != nil {
    17  			t.Error(err)
    18  			continue
    19  		}
    20  		off, err := readFooter(bytes.NewReader(b.Bytes()), int64(b.Len()))
    21  		if err != nil {
    22  			t.Error(err)
    23  			continue
    24  		}
    25  		if got, want := off, sz; got != want {
    26  			t.Errorf("got %v, want %v", got, want)
    27  		}
    28  
    29  		padded := paddedReaderAt{bytes.NewReader(b.Bytes()), int64(sz) * 100}
    30  		off, err = readFooter(padded, int64(sz)*100+int64(b.Len()))
    31  		if err != nil {
    32  			t.Error(err)
    33  			continue
    34  		}
    35  		if got, want := off, sz; got != want {
    36  			t.Errorf("got %v, want %v", got, want)
    37  		}
    38  	}
    39  }
    40  
    41  func TestCorruptedFooter(t *testing.T) {
    42  	var b bytes.Buffer
    43  	if _, err := writeFooter(&b, 1234); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	n := b.Len()
    47  	for i := 0; i < n; i++ {
    48  		if i >= n-12 && i < n-8 {
    49  			continue //skip magic
    50  		}
    51  		p := make([]byte, b.Len())
    52  		copy(p, b.Bytes())
    53  		p[i]++
    54  		_, err := readFooter(bytes.NewReader(p), int64(len(p)))
    55  		if got, want := err, ErrCorruptedImage; got != want {
    56  			t.Errorf("got %v, want %v", got, want)
    57  		}
    58  	}
    59  }
    60  
    61  type paddedReaderAt struct {
    62  	io.ReaderAt
    63  	N int64
    64  }
    65  
    66  func (r paddedReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
    67  	off -= r.N
    68  	for i := range p {
    69  		p[i] = 0
    70  	}
    71  	switch {
    72  	case off < -int64(len(p)):
    73  		return len(p), nil
    74  	case off < 0:
    75  		p = p[-off:]
    76  		off = 0
    77  	}
    78  	return r.ReaderAt.ReadAt(p, off)
    79  }