flate_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. // Copyright 2009 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. // This test tests some internals of the flate package.
  5. // The tests in package compress/gzip serve as the
  6. // end-to-end test of the decompressor.
  7. package flate
  8. import (
  9. "archive/zip"
  10. "bytes"
  11. "compress/flate"
  12. "encoding/hex"
  13. "fmt"
  14. "io/ioutil"
  15. "testing"
  16. )
  17. // The following test should not panic.
  18. func TestIssue5915(t *testing.T) {
  19. bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
  20. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  21. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
  22. var h huffmanDecoder
  23. if h.init(bits) {
  24. t.Fatalf("Given sequence of bits is bad, and should not succeed.")
  25. }
  26. }
  27. // The following test should not panic.
  28. func TestIssue5962(t *testing.T) {
  29. bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
  30. 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
  31. var h huffmanDecoder
  32. if h.init(bits) {
  33. t.Fatalf("Given sequence of bits is bad, and should not succeed.")
  34. }
  35. }
  36. // The following test should not panic.
  37. func TestIssue6255(t *testing.T) {
  38. bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
  39. bits2 := []int{11, 13}
  40. var h huffmanDecoder
  41. if !h.init(bits1) {
  42. t.Fatalf("Given sequence of bits is good and should succeed.")
  43. }
  44. if h.init(bits2) {
  45. t.Fatalf("Given sequence of bits is bad and should not succeed.")
  46. }
  47. }
  48. func TestInvalidEncoding(t *testing.T) {
  49. // Initialize Huffman decoder to recognize "0".
  50. var h huffmanDecoder
  51. if !h.init([]int{1}) {
  52. t.Fatal("Failed to initialize Huffman decoder")
  53. }
  54. // Initialize decompressor with invalid Huffman coding.
  55. var f decompressor
  56. f.r = bytes.NewReader([]byte{0xff})
  57. _, err := f.huffSym(&h)
  58. if err == nil {
  59. t.Fatal("Should have rejected invalid bit sequence")
  60. }
  61. }
  62. func TestRegressions(t *testing.T) {
  63. // Test fuzzer regressions
  64. data, err := ioutil.ReadFile("testdata/regression.zip")
  65. if err != nil {
  66. t.Fatal(err)
  67. }
  68. zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. for _, tt := range zr.File {
  73. data, err := tt.Open()
  74. if err != nil {
  75. t.Fatal(err)
  76. }
  77. data1, err := ioutil.ReadAll(data)
  78. if err != nil {
  79. t.Fatal(err)
  80. }
  81. for level := 0; level <= 9; level++ {
  82. t.Run(fmt.Sprint(tt.Name+"-level", 1), func(t *testing.T) {
  83. buf := new(bytes.Buffer)
  84. fw, err := NewWriter(buf, level)
  85. if err != nil {
  86. t.Error(err)
  87. }
  88. n, err := fw.Write(data1)
  89. if n != len(data1) {
  90. t.Error("short write")
  91. }
  92. if err != nil {
  93. t.Error(err)
  94. }
  95. err = fw.Close()
  96. if err != nil {
  97. t.Error(err)
  98. }
  99. fr1 := NewReader(buf)
  100. data2, err := ioutil.ReadAll(fr1)
  101. if err != nil {
  102. t.Error(err)
  103. }
  104. if bytes.Compare(data1, data2) != 0 {
  105. t.Error("not equal")
  106. }
  107. // Do it again...
  108. buf.Reset()
  109. fw.Reset(buf)
  110. n, err = fw.Write(data1)
  111. if n != len(data1) {
  112. t.Error("short write")
  113. }
  114. if err != nil {
  115. t.Error(err)
  116. }
  117. err = fw.Close()
  118. if err != nil {
  119. t.Error(err)
  120. }
  121. fr1 = flate.NewReader(buf)
  122. data2, err = ioutil.ReadAll(fr1)
  123. if err != nil {
  124. t.Error(err)
  125. }
  126. if bytes.Compare(data1, data2) != 0 {
  127. t.Error("not equal")
  128. }
  129. })
  130. }
  131. t.Run(tt.Name+"stateless", func(t *testing.T) {
  132. // Split into two and use history...
  133. buf := new(bytes.Buffer)
  134. err = StatelessDeflate(buf, data1[:len(data1)/2], false, nil)
  135. if err != nil {
  136. t.Error(err)
  137. }
  138. // Use top half as dictionary...
  139. dict := data1[:len(data1)/2]
  140. err = StatelessDeflate(buf, data1[len(data1)/2:], true, dict)
  141. if err != nil {
  142. t.Error(err)
  143. }
  144. t.Log(buf.Len())
  145. fr1 := NewReader(buf)
  146. data2, err := ioutil.ReadAll(fr1)
  147. if err != nil {
  148. t.Error(err)
  149. }
  150. if bytes.Compare(data1, data2) != 0 {
  151. fmt.Printf("want:%x\ngot: %x\n", data1, data2)
  152. t.Error("not equal")
  153. }
  154. })
  155. }
  156. }
  157. func TestInvalidBits(t *testing.T) {
  158. oversubscribed := []int{1, 2, 3, 4, 4, 5}
  159. incomplete := []int{1, 2, 4, 4}
  160. var h huffmanDecoder
  161. if h.init(oversubscribed) {
  162. t.Fatal("Should reject oversubscribed bit-length set")
  163. }
  164. if h.init(incomplete) {
  165. t.Fatal("Should reject incomplete bit-length set")
  166. }
  167. }
  168. func TestStreams(t *testing.T) {
  169. // To verify any of these hexstrings as valid or invalid flate streams
  170. // according to the C zlib library, you can use the Python wrapper library:
  171. // >>> hex_string = "010100feff11"
  172. // >>> import zlib
  173. // >>> zlib.decompress(hex_string.decode("hex"), -15) # Negative means raw DEFLATE
  174. // '\x11'
  175. testCases := []struct {
  176. desc string // Description of the stream
  177. stream string // Hexstring of the input DEFLATE stream
  178. want string // Expected result. Use "fail" to expect failure
  179. }{{
  180. "degenerate HCLenTree",
  181. "05e0010000000000100000000000000000000000000000000000000000000000" +
  182. "00000000000000000004",
  183. "fail",
  184. }, {
  185. "complete HCLenTree, empty HLitTree, empty HDistTree",
  186. "05e0010400000000000000000000000000000000000000000000000000000000" +
  187. "00000000000000000010",
  188. "fail",
  189. }, {
  190. "empty HCLenTree",
  191. "05e0010000000000000000000000000000000000000000000000000000000000" +
  192. "00000000000000000010",
  193. "fail",
  194. }, {
  195. "complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
  196. "000100feff000de0010400000000100000000000000000000000000000000000" +
  197. "0000000000000000000000000000002c",
  198. "fail",
  199. }, {
  200. "complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
  201. "000100feff000de0010000000000000000000000000000000000000000000000" +
  202. "00000000000000000610000000004070",
  203. "fail",
  204. }, {
  205. "complete HCLenTree, empty HLitTree, empty HDistTree",
  206. "05e0010400000000100400000000000000000000000000000000000000000000" +
  207. "0000000000000000000000000008",
  208. "fail",
  209. }, {
  210. "complete HCLenTree, empty HLitTree, degenerate HDistTree",
  211. "05e0010400000000100400000000000000000000000000000000000000000000" +
  212. "0000000000000000000800000008",
  213. "fail",
  214. }, {
  215. "complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
  216. "05e0010400000000100000000000000000000000000000000000000000000000" +
  217. "0000000000000000001c",
  218. "fail",
  219. }, {
  220. "complete HCLenTree, complete HLitTree, too large HDistTree",
  221. "edff870500000000200400000000000000000000000000000000000000000000" +
  222. "000000000000000000080000000000000004",
  223. "fail",
  224. }, {
  225. "complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
  226. "edfd870500000000200400000000000000000000000000000000000000000000" +
  227. "000000000000000000e8b100",
  228. "fail",
  229. }, {
  230. "complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
  231. "05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
  232. "ffffffffffffffffff07000000fe01",
  233. "",
  234. }, {
  235. "complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
  236. "05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
  237. "ffffffffffffffffff07000000fc03",
  238. "fail",
  239. }, {
  240. "complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
  241. "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
  242. "ffffffffffffffffff07f00f",
  243. "fail",
  244. }, {
  245. "complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
  246. "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
  247. "fffffffffcffffffff07f00f",
  248. "fail",
  249. }, {
  250. "complete HCLenTree, complete HLitTree with single code, empty HDistTree",
  251. "05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
  252. "ffffffffffffffffff07f00f",
  253. "01",
  254. }, {
  255. "complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
  256. "05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
  257. "ffffffffffffffffff07807f",
  258. "01",
  259. }, {
  260. "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
  261. "000100feff000de0010400000000100000000000000000000000000000000000" +
  262. "0000000000000000000000000000003c",
  263. "00000000",
  264. }, {
  265. "complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
  266. "05e0010400000000100000000000000000000000000000000000000000000000" +
  267. "0000000000000000000c",
  268. "",
  269. }, {
  270. "complete HCLenTree, degenerate HLitTree, empty HDistTree",
  271. "05e0010400000000100000000000000000000000000000000000000000000000" +
  272. "00000000000000000004",
  273. "",
  274. }, {
  275. "complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
  276. "edfd870500000000200400000000000000000000000000000000000000000000" +
  277. "000000000000000000e8b000",
  278. "",
  279. }, {
  280. "complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
  281. "ede0010400000000100000000000000000000000000000000000000000000000" +
  282. "0000000000000000000400004000",
  283. "",
  284. }, {
  285. "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
  286. "000100feff00ede0010400000000100000000000000000000000000000000000" +
  287. "000000000000000000000000000000040000407f00",
  288. "0000000000000000000000000000000000000000000000000000000000000000" +
  289. "0000000000000000000000000000000000000000000000000000000000000000" +
  290. "0000000000000000000000000000000000000000000000000000000000000000" +
  291. "0000000000000000000000000000000000000000000000000000000000000000" +
  292. "0000000000000000000000000000000000000000000000000000000000000000" +
  293. "0000000000000000000000000000000000000000000000000000000000000000" +
  294. "0000000000000000000000000000000000000000000000000000000000000000" +
  295. "0000000000000000000000000000000000000000000000000000000000000000" +
  296. "000000",
  297. }, {
  298. "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
  299. "0cc2010d00000082b0ac4aff0eb07d27060000ffff",
  300. "616263616263",
  301. }, {
  302. "fixed block, use reserved symbol 287",
  303. "33180700",
  304. "fail",
  305. }, {
  306. "raw block",
  307. "010100feff11",
  308. "11",
  309. }, {
  310. "issue 10426 - over-subscribed HCLenTree causes a hang",
  311. "344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
  312. "fail",
  313. }, {
  314. "issue 11030 - empty HDistTree unexpectedly leads to error",
  315. "05c0070600000080400fff37a0ca",
  316. "",
  317. }, {
  318. "issue 11033 - empty HDistTree unexpectedly leads to error",
  319. "050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
  320. "b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
  321. "3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
  322. "c6d7",
  323. }}
  324. for i, tc := range testCases {
  325. data, err := hex.DecodeString(tc.stream)
  326. if err != nil {
  327. t.Fatal(err)
  328. }
  329. data, err = ioutil.ReadAll(NewReader(bytes.NewReader(data)))
  330. if tc.want == "fail" {
  331. if err == nil {
  332. t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
  333. }
  334. } else {
  335. if err != nil {
  336. t.Errorf("#%d (%s): %v", i, tc.desc, err)
  337. continue
  338. }
  339. if got := hex.EncodeToString(data); got != tc.want {
  340. t.Errorf("#%d (%s):\ngot %q\nwant %q", i, tc.desc, got, tc.want)
  341. }
  342. }
  343. }
  344. }