github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/klauspost/compress/flate/inflate_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package flate
     6  
     7  import (
     8  	"bytes"
     9  	"crypto/rand"
    10  	"io"
    11  	"io/ioutil"
    12  	"strconv"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  func TestReset(t *testing.T) {
    18  	ss := []string{
    19  		"lorem ipsum izzle fo rizzle",
    20  		"the quick brown fox jumped over",
    21  	}
    22  
    23  	deflated := make([]bytes.Buffer, 2)
    24  	for i, s := range ss {
    25  		w, _ := NewWriter(&deflated[i], 1)
    26  		w.Write([]byte(s))
    27  		w.Close()
    28  	}
    29  
    30  	inflated := make([]bytes.Buffer, 2)
    31  
    32  	f := NewReader(&deflated[0])
    33  	io.Copy(&inflated[0], f)
    34  	f.(Resetter).Reset(&deflated[1], nil)
    35  	io.Copy(&inflated[1], f)
    36  	f.Close()
    37  
    38  	for i, s := range ss {
    39  		if s != inflated[i].String() {
    40  			t.Errorf("inflated[%d]:\ngot  %q\nwant %q", i, inflated[i], s)
    41  		}
    42  	}
    43  }
    44  
    45  // Tests ported from zlib/test/infcover.c
    46  type infTest struct {
    47  	hex string
    48  	id  string
    49  	n   int
    50  }
    51  
    52  var infTests = []infTest{
    53  	infTest{"0 0 0 0 0", "invalid stored block lengths", 1},
    54  	infTest{"3 0", "fixed", 0},
    55  	infTest{"6", "invalid block type", 1},
    56  	infTest{"1 1 0 fe ff 0", "stored", 0},
    57  	infTest{"fc 0 0", "too many length or distance symbols", 1},
    58  	infTest{"4 0 fe ff", "invalid code lengths set", 1},
    59  	infTest{"4 0 24 49 0", "invalid bit length repeat", 1},
    60  	infTest{"4 0 24 e9 ff ff", "invalid bit length repeat", 1},
    61  	infTest{"4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1},
    62  	infTest{"4 80 49 92 24 49 92 24 71 ff ff 93 11 0", "invalid literal/lengths set", 1},
    63  	infTest{"4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1},
    64  	infTest{"4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1},
    65  	infTest{"2 7e ff ff", "invalid distance code", 1},
    66  	infTest{"c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1},
    67  
    68  	// also trailer mismatch just in inflate()
    69  	infTest{"1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1},
    70  	infTest{"1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", "incorrect length check", -1},
    71  	infTest{"5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0},
    72  	infTest{"5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", "long code", 0},
    73  	infTest{"ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0},
    74  	infTest{"ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", "long distance and extra", 0},
    75  	infTest{"ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0},
    76  }
    77  
    78  func TestInflate(t *testing.T) {
    79  	for _, test := range infTests {
    80  		hex := strings.Split(test.hex, " ")
    81  		data := make([]byte, len(hex))
    82  		for i, h := range hex {
    83  			b, _ := strconv.ParseInt(h, 16, 32)
    84  			data[i] = byte(b)
    85  		}
    86  		buf := bytes.NewReader(data)
    87  		r := NewReader(buf)
    88  
    89  		_, err := io.Copy(ioutil.Discard, r)
    90  		if (test.n == 0 && err == nil) || (test.n != 0 && err != nil) {
    91  			t.Logf("%q: OK:", test.id)
    92  			t.Logf(" - got %v", err)
    93  			continue
    94  		}
    95  
    96  		if test.n == 0 && err != nil {
    97  			t.Errorf("%q: Expected no error, but got %v", test.id, err)
    98  			continue
    99  		}
   100  
   101  		if test.n != 0 && err == nil {
   102  			t.Errorf("%q:Expected an error, but got none", test.id)
   103  			continue
   104  		}
   105  		t.Fatal(test.n, err)
   106  	}
   107  
   108  	for _, test := range infOutTests {
   109  		hex := strings.Split(test.hex, " ")
   110  		data := make([]byte, len(hex))
   111  		for i, h := range hex {
   112  			b, _ := strconv.ParseInt(h, 16, 32)
   113  			data[i] = byte(b)
   114  		}
   115  		buf := bytes.NewReader(data)
   116  		r := NewReader(buf)
   117  
   118  		_, err := io.Copy(ioutil.Discard, r)
   119  		if test.err == (err != nil) {
   120  			t.Logf("%q: OK:", test.id)
   121  			t.Logf(" - got %v", err)
   122  			continue
   123  		}
   124  
   125  		if test.err == false && err != nil {
   126  			t.Errorf("%q: Expected no error, but got %v", test.id, err)
   127  			continue
   128  		}
   129  
   130  		if test.err && err == nil {
   131  			t.Errorf("%q: Expected an error, but got none", test.id)
   132  			continue
   133  		}
   134  		t.Fatal(test.err, err)
   135  	}
   136  
   137  }
   138  
   139  // Tests ported from zlib/test/infcover.c
   140  // Since zlib inflate is push (writer) instead of pull (reader)
   141  // some of the window size tests have been removed, since they
   142  // are irrelevant.
   143  type infOutTest struct {
   144  	hex    string
   145  	id     string
   146  	step   int
   147  	win    int
   148  	length int
   149  	err    bool
   150  }
   151  
   152  var infOutTests = []infOutTest{
   153  	infOutTest{"2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, false},
   154  	infOutTest{"63 18 5 40 c 0", "window wrap", 3, -8, 300, false},
   155  	infOutTest{"e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68 ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, true},
   156  	infOutTest{"25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, true},
   157  	infOutTest{"3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, true},
   158  	infOutTest{"1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, true},
   159  	infOutTest{"d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", "fast 2nd level codes and too far back", 0, -8, 258, true},
   160  	infOutTest{"63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, false},
   161  	infOutTest{"63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", "contiguous and wrap around window", 6, -8, 259, false},
   162  	infOutTest{"63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, false},
   163  	infOutTest{"1f 8b 0 0", "bad gzip method", 0, 31, 0, true},
   164  	infOutTest{"1f 8b 8 80", "bad gzip flags", 0, 31, 0, true},
   165  	infOutTest{"77 85", "bad zlib method", 0, 15, 0, true},
   166  	infOutTest{"78 9c", "bad zlib window size", 0, 8, 0, true},
   167  	infOutTest{"1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, true},
   168  	infOutTest{"1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", 0, 47, 0, true},
   169  	infOutTest{"78 90", "bad zlib header check", 0, 47, 0, true},
   170  	infOutTest{"8 b8 0 0 0 1", "need dictionary", 0, 8, 0, true},
   171  	infOutTest{"63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, false},
   172  	infOutTest{"3 0", "use fixed blocks", 0, -15, 1, false},
   173  	infOutTest{"", "bad window size", 0, 1, 0, true},
   174  }
   175  
   176  func TestWriteTo(t *testing.T) {
   177  	input := make([]byte, 100000)
   178  	n, err := rand.Read(input)
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	if n != len(input) {
   183  		t.Fatal("did not fill buffer")
   184  	}
   185  	compressed := &bytes.Buffer{}
   186  	w, err := NewWriter(compressed, -2)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	n, err = w.Write(input)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  	if n != len(input) {
   195  		t.Fatal("did not fill buffer")
   196  	}
   197  	w.Close()
   198  	buf := compressed.Bytes()
   199  
   200  	dec := NewReader(bytes.NewBuffer(buf))
   201  	// ReadAll does not use WriteTo, but we wrap it in a NopCloser to be sure.
   202  	readall, err := ioutil.ReadAll(ioutil.NopCloser(dec))
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  	if len(readall) != len(input) {
   207  		t.Fatal("did not decompress everything")
   208  	}
   209  
   210  	dec = NewReader(bytes.NewBuffer(buf))
   211  	wtbuf := &bytes.Buffer{}
   212  	written, err := dec.(io.WriterTo).WriteTo(wtbuf)
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  	if written != int64(len(input)) {
   217  		t.Error("Returned length did not match, expected", len(input), "got", written)
   218  	}
   219  	if wtbuf.Len() != len(input) {
   220  		t.Error("Actual Length did not match, expected", len(input), "got", wtbuf.Len())
   221  	}
   222  	if bytes.Compare(wtbuf.Bytes(), input) != 0 {
   223  		t.Fatal("output did not match input")
   224  	}
   225  }