Import upstream version 0.5.10
Debian Janitor
2 years ago
0 | # For most projects, this workflow file will not need changing; you simply need | |
1 | # to commit it to your repository. | |
2 | # | |
3 | # You may wish to alter this file to override the set of languages analyzed, | |
4 | # or to provide custom queries or build logic. | |
5 | # | |
6 | # ******** NOTE ******** | |
7 | # We have attempted to detect the languages in your repository. Please check | |
8 | # the `language` matrix defined below to confirm you have the correct set of | |
9 | # supported CodeQL languages. | |
10 | # | |
11 | name: "CodeQL" | |
12 | ||
13 | on: | |
14 | push: | |
15 | branches: [ master ] | |
16 | pull_request: | |
17 | # The branches below must be a subset of the branches above | |
18 | branches: [ master ] | |
19 | schedule: | |
20 | - cron: '22 20 * * 3' | |
21 | ||
22 | jobs: | |
23 | analyze: | |
24 | name: Analyze | |
25 | runs-on: ubuntu-latest | |
26 | ||
27 | strategy: | |
28 | fail-fast: false | |
29 | matrix: | |
30 | language: [ 'go' ] | |
31 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] | |
32 | # Learn more: | |
33 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed | |
34 | ||
35 | steps: | |
36 | - name: Checkout repository | |
37 | uses: actions/checkout@v2 | |
38 | ||
39 | # Initializes the CodeQL tools for scanning. | |
40 | - name: Initialize CodeQL | |
41 | uses: github/codeql-action/init@v1 | |
42 | with: | |
43 | languages: ${{ matrix.language }} | |
44 | # If you wish to specify custom queries, you can do so here or in a config file. | |
45 | # By default, queries listed here will override any specified in a config file. | |
46 | # Prefix the list here with "+" to use these queries and those in the config file. | |
47 | # queries: ./path/to/local/query, your-org/your-repo/queries@main | |
48 | ||
49 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). | |
50 | # If this step fails, then you should remove it and run the build manually (see below) | |
51 | - name: Autobuild | |
52 | uses: github/codeql-action/autobuild@v1 | |
53 | ||
54 | # âšī¸ Command-line programs to run using the OS shell. | |
55 | # đ https://git.io/JvXDl | |
56 | ||
57 | # âī¸ If the Autobuild fails above, remove it and uncomment the following three lines | |
58 | # and modify them (or add more) to build your code if your project | |
59 | # uses a compiled language | |
60 | ||
61 | #- run: | | |
62 | # make bootstrap | |
63 | # make release | |
64 | ||
65 | - name: Perform CodeQL Analysis | |
66 | uses: github/codeql-action/analyze@v1 |
0 | Copyright (c) 2014-2016 Ulrich Kunitz | |
0 | Copyright (c) 2014-2021 Ulrich Kunitz | |
1 | 1 | All rights reserved. |
2 | 2 | |
3 | 3 | Redistribution and use in source and binary forms, with or without |
0 | # Security Policy | |
1 | ||
2 | ## Supported Versions | |
3 | ||
4 | Currently the last minor version v0.5.x is supported. | |
5 | ||
6 | ## Reporting a Vulnerability | |
7 | ||
8 | Report a vulnerability by creating a Github issue at | |
9 | <https://github.com/ulikunitz/xz/issues>. Expect a response in a week. |
0 | 0 | # TODO list |
1 | ||
2 | ## Release v0.5.x | |
3 | ||
4 | 1. Support check flag in gxz command. | |
1 | 5 | |
2 | 6 | ## Release v0.6 |
3 | 7 | |
4 | 8 | 1. Review encoder and check for lzma improvements under xz. |
5 | 9 | 2. Fix binary tree matcher. |
6 | 3. Compare compression ratio with xz tool using comparable parameters | |
7 | and optimize parameters | |
8 | 4. Do some optimizations | |
9 | - rename operation action and make it a simple type of size 8 | |
10 | - make maxMatches, wordSize parameters | |
11 | - stop searching after a certain length is found (parameter sweetLen) | |
10 | 3. Compare compression ratio with xz tool using comparable parameters and optimize parameters | |
11 | 4. rename operation action and make it a simple type of size 8 | |
12 | 5. make maxMatches, wordSize parameters | |
13 | 6. stop searching after a certain length is found (parameter sweetLen) | |
12 | 14 | |
13 | 15 | ## Release v0.7 |
14 | 16 | |
15 | 17 | 1. Optimize code |
16 | 18 | 2. Do statistical analysis to get linear presets. |
17 | 19 | 3. Test sync.Pool compatability for xz and lzma Writer and Reader |
18 | 3. Fuzz optimized code. | |
20 | 4. Fuzz optimized code. | |
19 | 21 | |
20 | 22 | ## Release v0.8 |
21 | 23 | |
39 | 41 | |
40 | 42 | ## Package lzma |
41 | 43 | |
42 | ### Release v0.6 | |
43 | ||
44 | - Rewrite Encoder into a simple greedy one-op-at-a-time encoder | |
45 | including | |
46 | + simple scan at the dictionary head for the same byte | |
47 | + use the killer byte (requiring matches to get longer, the first | |
48 | test should be the byte that would make the match longer) | |
49 | ||
44 | ### v0.6 | |
45 | ||
46 | * Rewrite Encoder into a simple greedy one-op-at-a-time encoder including | |
47 | * simple scan at the dictionary head for the same byte | |
48 | * use the killer byte (requiring matches to get longer, the first test should be the byte that would make the match longer) | |
50 | 49 | |
51 | 50 | ## Optimizations |
52 | 51 | |
53 | - There may be a lot of false sharing in lzma.State; check whether this | |
54 | can be improved by reorganizing the internal structure of it. | |
55 | - Check whether batching encoding and decoding improves speed. | |
52 | * There may be a lot of false sharing in lzma. State; check whether this can be improved by reorganizing the internal structure of it. | |
53 | ||
54 | * Check whether batching encoding and decoding improves speed. | |
56 | 55 | |
57 | 56 | ### DAG optimizations |
58 | 57 | |
59 | - Use full buffer to create minimal bit-length above range encoder. | |
60 | - Might be too slow (see v0.4) | |
58 | * Use full buffer to create minimal bit-length above range encoder. | |
59 | * Might be too slow (see v0.4) | |
61 | 60 | |
62 | 61 | ### Different match finders |
63 | 62 | |
64 | - hashes with 2, 3 characters additional to 4 characters | |
65 | - binary trees with 2-7 characters (uint64 as key, use uint32 as | |
63 | * hashes with 2, 3 characters additional to 4 characters | |
64 | * binary trees with 2-7 characters (uint64 as key, use uint32 as | |
65 | ||
66 | 66 | pointers into a an array) |
67 | - rb-trees with 2-7 characters (uint64 as key, use uint32 as pointers | |
67 | ||
68 | * rb-trees with 2-7 characters (uint64 as key, use uint32 as pointers | |
69 | ||
68 | 70 | into an array with bit-steeling for the colors) |
69 | 71 | |
70 | 72 | ## Release Procedure |
71 | 73 | |
72 | - execute goch -l for all packages; probably with lower param like 0.5. | |
73 | - check orthography with gospell | |
74 | - Write release notes in doc/relnotes. | |
75 | - Update README.md | |
76 | - xb copyright . in xz directory to ensure all new files have Copyright | |
77 | header | |
78 | - VERSION=<version> go generate github.com/ulikunitz/xz/... to update | |
79 | version files | |
80 | - Execute test for Linux/amd64, Linux/x86 and Windows/amd64. | |
81 | - Update TODO.md - write short log entry | |
82 | - git checkout master && git merge dev | |
83 | - git tag -a <version> | |
84 | - git push | |
74 | * execute goch -l for all packages; probably with lower param like 0.5. | |
75 | * check orthography with gospell | |
76 | * Write release notes in doc/relnotes. | |
77 | * Update README.md | |
78 | * xb copyright . in xz directory to ensure all new files have Copyright header | |
79 | * `VERSION=<version> go generate github.com/ulikunitz/xz/...` to update version files | |
80 | * Execute test for Linux/amd64, Linux/x86 and Windows/amd64. | |
81 | * Update TODO.md - write short log entry | |
82 | * `git checkout master && git merge dev` | |
83 | * `git tag -a <version>` | |
84 | * `git push` | |
85 | 85 | |
86 | 86 | ## Log |
87 | ||
88 | ### 2021-02-02 | |
89 | ||
90 | Mituo Heijo has fuzzed xz and found a bug in the function readIndexBody. The | |
91 | function allocated a slice of records immediately after reading the value | |
92 | without further checks. Since the number has been too large the make function | |
93 | did panic. The fix is to check the number against the expected number of records | |
94 | before allocating the records. | |
95 | ||
96 | ### 2020-12-17 | |
97 | ||
98 | Release v0.5.9 fixes warnings, a typo and adds SECURITY.md. | |
99 | ||
100 | One fix is interesting. | |
101 | ||
102 | ```go | |
103 | const ( | |
104 | a byte = 0x1 | |
105 | b = 0x2 | |
106 | ) | |
107 | ``` | |
108 | ||
109 | The constants a and b don't have the same type. Correct is | |
110 | ||
111 | ```go | |
112 | const ( | |
113 | a byte = 0x1 | |
114 | b byte = 0x2 | |
115 | ) | |
116 | ``` | |
117 | ||
118 | ### 2020-08-19 | |
119 | ||
120 | Release v0.5.8 fixes issue | |
121 | [issue #35](https://github.com/ulikunitz/xz/issues/35). | |
122 | ||
123 | ### 2020-02-24 | |
124 | ||
125 | Release v0.5.7 supports the check-ID None and fixes | |
126 | [issue #27](https://github.com/ulikunitz/xz/issues/27). | |
87 | 127 | |
88 | 128 | ### 2019-02-20 |
89 | 129 | |
193 | 233 | |
194 | 234 | ### 2015-06-04 |
195 | 235 | |
196 | It has been a productive day. I improved the interface of lzma.Reader | |
197 | and lzma.Writer and fixed the error handling. | |
236 | It has been a productive day. I improved the interface of lzma. Reader | |
237 | and lzma. Writer and fixed the error handling. | |
198 | 238 | |
199 | 239 | ### 2015-06-01 |
200 | 240 | |
245 | 285 | |
246 | 286 | However I will implement a ReaderState and WriterState type to use |
247 | 287 | static typing to ensure the right State object is combined with the |
248 | right lzbase.Reader and lzbase.Writer. | |
288 | right lzbase. Reader and lzbase. Writer. | |
249 | 289 | |
250 | 290 | As a start I have implemented ReaderState and WriterState to ensure |
251 | 291 | that the state for reading is only used by readers and WriterState only |
267 | 307 | |
268 | 308 | ### 2015-04-05 |
269 | 309 | |
270 | Implemented lzma.Reader and tested it. | |
310 | Implemented lzma. Reader and tested it. | |
271 | 311 | |
272 | 312 | ### 2015-04-04 |
273 | 313 | |
274 | Implemented baseReader by adapting code form lzma.Reader. | |
314 | Implemented baseReader by adapting code form lzma. Reader. | |
275 | 315 | |
276 | 316 | ### 2015-04-03 |
277 | 317 | |
287 | 327 | (Javaïstes?)" is the the idea that using an embedded field E, all the |
288 | 328 | methods of E will be defined on T. If E is an interface T satisfies E. |
289 | 329 | |
290 | https://talks.golang.org/2014/go4java.slide#51 | |
330 | <https://talks.golang.org/2014/go4java.slide#51> | |
291 | 331 | |
292 | 332 | I have never used this, but it seems to be a cool idea. |
293 | 333 | |
312 | 352 | |
313 | 353 | 1. Implemented simple lzmago tool |
314 | 354 | 2. Tested tool against large 4.4G file |
315 | - compression worked correctly; tested decompression with lzma | |
316 | - decompression hits a full buffer condition | |
355 | * compression worked correctly; tested decompression with lzma | |
356 | * decompression hits a full buffer condition | |
317 | 357 | 3. Fixed a bug in the compressor and wrote a test for it |
318 | 358 | 4. Executed full cycle for 4.4 GB file; performance can be improved ;-) |
319 | 359 | |
320 | 360 | ### 2015-01-11 |
321 | 361 | |
322 | - Release v0.2 because of the working LZMA encoder and decoder | |
362 | * Release v0.2 because of the working LZMA encoder and decoder |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
53 | 53 | |
54 | 54 | // readUvarint reads a uvarint from the given byte reader. |
55 | 55 | func readUvarint(r io.ByteReader) (x uint64, n int, err error) { |
56 | const maxUvarintLen = 10 | |
57 | ||
56 | 58 | var s uint |
57 | 59 | i := 0 |
58 | 60 | for { |
61 | 63 | return x, i, err |
62 | 64 | } |
63 | 65 | i++ |
66 | if i > maxUvarintLen { | |
67 | return x, i, errOverflowU64 | |
68 | } | |
64 | 69 | if b < 0x80 { |
65 | if i > 10 || i == 10 && b > 1 { | |
70 | if i == maxUvarintLen && b > 1 { | |
66 | 71 | return x, i, errOverflowU64 |
67 | 72 | } |
68 | 73 | return x | uint64(b)<<s, i, nil |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
30 | 30 | } |
31 | 31 | } |
32 | 32 | } |
33 | ||
34 | func TestUvarIntCVE_2020_16845(t *testing.T) { | |
35 | var a = []byte{0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | |
36 | 0x88, 0x89, 0x8a, 0x8b} | |
37 | ||
38 | r := bytes.NewReader(a) | |
39 | _, _, err := readUvarint(r) | |
40 | if err != errOverflowU64 { | |
41 | t.Fatalf("readUvarint overflow not detected") | |
42 | } | |
43 | } |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
27 | 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 | ` |
30 | const xzLicense = `Copyright (c) 2014-2019 Ulrich Kunitz | |
30 | const xzLicense = `Copyright (c) 2014-2021 Ulrich Kunitz | |
31 | 31 | All rights reserved. |
32 | 32 | |
33 | 33 | Redistribution and use in source and binary forms, with or without |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
27 | 27 | } |
28 | 28 | |
29 | 29 | const copyrightText = ` |
30 | Copyright 2014-2019 Ulrich Kunitz. All rights reserved. | |
30 | Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
31 | 31 | Use of this source code is governed by a BSD-style |
32 | 32 | license that can be found in the LICENSE file. |
33 | 33 | ` |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | # Release Notes v0.5.10 | |
1 | ||
2 | This release fixes issue #40. Many thanks to Github user Misuo Heijo for fuzzing | |
3 | the xz module. |
0 | # Release Notes v0.5.7 | |
1 | ||
2 | This release fixes issue #27 "Checksum None is valid" by supporting the | |
3 | check-ID None. | |
4 | ||
5 | Many thanks to [blacktop](https://github.com/blacktop) for reporting the | |
6 | bug. |
0 | # Release Notes v0.5.8 | |
1 | ||
2 | This release fixes the security issue #35. The readUvarint function | |
3 | would run infinitely given specific input. The function is now | |
4 | terminating if more than 10 bytes of input have been read. The behavior | |
5 | is tested. | |
6 | ||
7 | Many thanks to Github user 0xdecaf for reporting the issue. |
0 | # Release Notes v0.5.9 | |
1 | ||
2 | This release fixes: | |
3 | ||
4 | - all staticcheck issues in the public repositories. | |
5 | - fixes wrong const type definitions; thanks Matt LaPlante | |
6 | - fixes a typo; Michael Vetter | |
7 | - adds a SECURITY.md file |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
45 | 45 | |
46 | 46 | // Constants for the checksum methods supported by xz. |
47 | 47 | const ( |
48 | None byte = 0x0 | |
48 | 49 | CRC32 byte = 0x1 |
49 | CRC64 = 0x4 | |
50 | SHA256 = 0xa | |
50 | CRC64 byte = 0x4 | |
51 | SHA256 byte = 0xa | |
51 | 52 | ) |
52 | 53 | |
53 | 54 | // errInvalidFlags indicates that flags are invalid. |
57 | 58 | // invalid. |
58 | 59 | func verifyFlags(flags byte) error { |
59 | 60 | switch flags { |
60 | case CRC32, CRC64, SHA256: | |
61 | case None, CRC32, CRC64, SHA256: | |
61 | 62 | return nil |
62 | 63 | default: |
63 | 64 | return errInvalidFlags |
66 | 67 | |
67 | 68 | // flagstrings maps flag values to strings. |
68 | 69 | var flagstrings = map[byte]string{ |
70 | None: "None", | |
69 | 71 | CRC32: "CRC-32", |
70 | 72 | CRC64: "CRC-64", |
71 | 73 | SHA256: "SHA-256", |
84 | 86 | // hash method encoded in flags. |
85 | 87 | func newHashFunc(flags byte) (newHash func() hash.Hash, err error) { |
86 | 88 | switch flags { |
89 | case None: | |
90 | newHash = newNoneHash | |
87 | 91 | case CRC32: |
88 | 92 | newHash = newCRC32 |
89 | 93 | case CRC64: |
564 | 568 | return []filter{f}, err |
565 | 569 | } |
566 | 570 | |
567 | // writeFilters writes the filters. | |
568 | func writeFilters(w io.Writer, filters []filter) (n int, err error) { | |
569 | for _, f := range filters { | |
570 | p, err := f.MarshalBinary() | |
571 | if err != nil { | |
572 | return n, err | |
573 | } | |
574 | k, err := w.Write(p) | |
575 | n += k | |
576 | if err != nil { | |
577 | return n, err | |
578 | } | |
579 | } | |
580 | return n, nil | |
581 | } | |
582 | ||
583 | 571 | /*** Index ***/ |
584 | 572 | |
585 | 573 | // record describes a block in the xz file index. |
673 | 661 | |
674 | 662 | // readIndexBody reads the index from the reader. It assumes that the |
675 | 663 | // index indicator has already been read. |
676 | func readIndexBody(r io.Reader) (records []record, n int64, err error) { | |
664 | func readIndexBody(r io.Reader, expectedRecordLen int) (records []record, n int64, err error) { | |
677 | 665 | crc := crc32.NewIEEE() |
678 | 666 | // index indicator |
679 | 667 | crc.Write([]byte{0}) |
689 | 677 | recLen := int(u) |
690 | 678 | if recLen < 0 || uint64(recLen) != u { |
691 | 679 | return nil, n, errors.New("xz: record number overflow") |
680 | } | |
681 | if recLen != expectedRecordLen { | |
682 | return nil, n, fmt.Errorf( | |
683 | "xz: index length is %d; want %d", | |
684 | recLen, expectedRecordLen) | |
692 | 685 | } |
693 | 686 | |
694 | 687 | // list of records |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
84 | 84 | t.Fatalf("indicator %d; want %d", c, 0) |
85 | 85 | } |
86 | 86 | |
87 | g, m, err := readIndexBody(&buf) | |
87 | g, m, err := readIndexBody(&buf, len(records)) | |
88 | 88 | if err != nil { |
89 | 89 | for i, r := range g { |
90 | 90 | t.Logf("records[%d] %v", i, r) |
Binary diff not shown
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
4 | 4 | package lzma |
5 | 5 | |
6 | 6 | import ( |
7 | "bufio" | |
8 | 7 | "errors" |
9 | "fmt" | |
10 | "io" | |
11 | 8 | "unicode" |
12 | 9 | ) |
13 | 10 | |
348 | 345 | return string(a) |
349 | 346 | } |
350 | 347 | |
348 | /* | |
351 | 349 | // dumpNode writes a representation of the node v into the io.Writer. |
352 | 350 | func (t *binTree) dumpNode(w io.Writer, v uint32, indent int) { |
353 | 351 | if v == null { |
376 | 374 | t.dumpNode(bw, t.root, 0) |
377 | 375 | return bw.Flush() |
378 | 376 | } |
377 | */ | |
379 | 378 | |
380 | 379 | func (t *binTree) distance(v uint32) int { |
381 | 380 | dist := int(t.front) - int(v) |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
17 | 17 | 30, 17, 8, 14, 29, 13, 28, 27, |
18 | 18 | } |
19 | 19 | |
20 | /* | |
20 | 21 | // ntz32 computes the number of trailing zeros for an unsigned 32-bit integer. |
21 | 22 | func ntz32(x uint32) int { |
22 | 23 | if x == 0 { |
25 | 26 | x = (x & -x) * ntz32Const |
26 | 27 | return int(ntz32Table[x>>27]) |
27 | 28 | } |
29 | */ | |
28 | 30 | |
29 | 31 | // nlz32 computes the number of leading zeros for an unsigned 32-bit integer. |
30 | 32 | func nlz32(x uint32) int { |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
199 | 199 | op, err := d.readOp() |
200 | 200 | switch err { |
201 | 201 | case nil: |
202 | break | |
202 | // break | |
203 | 203 | case errEOS: |
204 | 204 | d.eos = true |
205 | 205 | if !d.rd.possiblyAtEnd() { |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
125 | 125 | |
126 | 126 | // Read reads data from the buffer contained in the decoder dictionary. |
127 | 127 | func (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) } |
128 | ||
129 | // Buffered returns the number of bytes currently buffered in the | |
130 | // decoder dictionary. | |
131 | func (d *decoderDict) buffered() int { return d.buf.Buffered() } | |
132 | ||
133 | // Peek gets data from the buffer without advancing the rear index. | |
134 | func (d *decoderDict) peek(p []byte) (n int, err error) { return d.buf.Peek(p) } |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
4 | 4 | package lzma |
5 | 5 | |
6 | 6 | import ( |
7 | "fmt" | |
8 | 7 | "testing" |
9 | 8 | ) |
10 | ||
11 | func peek(d *decoderDict) []byte { | |
12 | p := make([]byte, d.buffered()) | |
13 | k, err := d.peek(p) | |
14 | if err != nil { | |
15 | panic(fmt.Errorf("peek: "+ | |
16 | "Read returned unexpected error %s", err)) | |
17 | } | |
18 | if k != len(p) { | |
19 | panic(fmt.Errorf("peek: "+ | |
20 | "Read returned %d; wanted %d", k, len(p))) | |
21 | } | |
22 | return p | |
23 | } | |
24 | 9 | |
25 | 10 | func TestNewDecoderDict(t *testing.T) { |
26 | 11 | if _, err := newDecoderDict(0); err == nil { |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
4 | 4 | package lzma |
5 | 5 | |
6 | import "fmt" | |
7 | ||
8 | 6 | // directCodec allows the encoding and decoding of values with a fixed number |
9 | 7 | // of bits. The number of bits must be in the range [1,32]. |
10 | 8 | type directCodec byte |
11 | ||
12 | // makeDirectCodec creates a directCodec. The function panics if the number of | |
13 | // bits is not in the range [1,32]. | |
14 | func makeDirectCodec(bits int) directCodec { | |
15 | if !(1 <= bits && bits <= 32) { | |
16 | panic(fmt.Errorf("bits=%d out of range", bits)) | |
17 | } | |
18 | return directCodec(bits) | |
19 | } | |
20 | 9 | |
21 | 10 | // Bits returns the number of bits supported by this codec. |
22 | 11 | func (dc directCodec) Bits() int { |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
19 | 19 | posSlotBits = 6 |
20 | 20 | // number of align bits |
21 | 21 | alignBits = 4 |
22 | // maximum position slot | |
23 | maxPosSlot = 63 | |
24 | 22 | ) |
25 | 23 | |
26 | 24 | // distCodec provides encoding and decoding of distance values. |
42 | 40 | dc.posModel[i].deepcopy(&src.posModel[i]) |
43 | 41 | } |
44 | 42 | dc.alignCodec.deepcopy(&src.alignCodec) |
45 | } | |
46 | ||
47 | // distBits returns the number of bits required to encode dist. | |
48 | func distBits(dist uint32) int { | |
49 | if dist < startPosModel { | |
50 | return 6 | |
51 | } | |
52 | // slot s > 3, dist d | |
53 | // s = 2(bits(d)-1) + bit(d, bits(d)-2) | |
54 | // s>>1 = bits(d)-1 | |
55 | // bits(d) = 32-nlz32(d) | |
56 | // s>>1=31-nlz32(d) | |
57 | // n = 5 + (s>>1) = 36 - nlz32(d) | |
58 | return 36 - nlz32(dist) | |
59 | 43 | } |
60 | 44 | |
61 | 45 | // newDistCodec creates a new distance codec. |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
18 | 18 | } |
19 | 19 | |
20 | 20 | // encoderDict provides the dictionary of the encoder. It includes an |
21 | // addtional buffer atop of the actual dictionary. | |
21 | // additional buffer atop of the actual dictionary. | |
22 | 22 | type encoderDict struct { |
23 | 23 | buf buffer |
24 | 24 | m matcher |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
263 | 263 | // state |
264 | 264 | const ( |
265 | 265 | start chunkState = 'S' |
266 | stop = 'T' | |
266 | stop chunkState = 'T' | |
267 | 267 | ) |
268 | 268 | |
269 | 269 | // errors for the chunk state handling |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
53 | 53 | lc.mid[i] = makeTreeCodec(3) |
54 | 54 | } |
55 | 55 | lc.high = makeTreeCodec(8) |
56 | } | |
57 | ||
58 | // lBits gives the number of bits used for the encoding of the l value | |
59 | // provided to the range encoder. | |
60 | func lBits(l uint32) int { | |
61 | switch { | |
62 | case l < 8: | |
63 | return 4 | |
64 | case l < 16: | |
65 | return 5 | |
66 | default: | |
67 | return 10 | |
68 | } | |
69 | 56 | } |
70 | 57 | |
71 | 58 | // Encode encodes the length offset. The length offset l can be compute by |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
122 | 122 | minLP = 0 |
123 | 123 | maxLP = 4 |
124 | 124 | ) |
125 | ||
126 | // minState and maxState define a range for the state values stored in | |
127 | // the State values. | |
128 | const ( | |
129 | minState = 0 | |
130 | maxState = 11 | |
131 | ) |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
4 | 4 | package lzma |
5 | 5 | |
6 | 6 | import ( |
7 | "errors" | |
8 | 7 | "fmt" |
9 | 8 | "unicode" |
10 | 9 | ) |
21 | 20 | distance int64 |
22 | 21 | // length |
23 | 22 | n int |
24 | } | |
25 | ||
26 | // verify checks whether the match is valid. If that is not the case an | |
27 | // error is returned. | |
28 | func (m match) verify() error { | |
29 | if !(minDistance <= m.distance && m.distance <= maxDistance) { | |
30 | return errors.New("distance out of range") | |
31 | } | |
32 | if !(1 <= m.n && m.n <= maxMatchLen) { | |
33 | return errors.New("length out of range") | |
34 | } | |
35 | return nil | |
36 | } | |
37 | ||
38 | // l return the l-value for the match, which is the difference of length | |
39 | // n and 2. | |
40 | func (m match) l() uint32 { | |
41 | return uint32(m.n - minMatchLen) | |
42 | } | |
43 | ||
44 | // dist returns the dist value for the match, which is one less of the | |
45 | // distance stored in the match. | |
46 | func (m match) dist() uint32 { | |
47 | return uint32(m.distance - minDistance) | |
48 | 23 | } |
49 | 24 | |
50 | 25 | // Len returns the number of bytes matched. |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
130 | 130 | code uint32 |
131 | 131 | } |
132 | 132 | |
133 | // init initializes the range decoder, by reading from the byte reader. | |
134 | func (d *rangeDecoder) init() error { | |
135 | d.nrange = 0xffffffff | |
136 | d.code = 0 | |
137 | ||
138 | b, err := d.br.ReadByte() | |
139 | if err != nil { | |
140 | return err | |
141 | } | |
142 | if b != 0 { | |
143 | return errors.New("newRangeDecoder: first byte not zero") | |
144 | } | |
145 | ||
146 | for i := 0; i < 4; i++ { | |
147 | if err = d.updateCode(); err != nil { | |
148 | return err | |
149 | } | |
150 | } | |
151 | ||
152 | if d.code >= d.nrange { | |
153 | return errors.New("newRangeDecoder: d.code >= d.nrange") | |
154 | } | |
155 | ||
156 | return nil | |
157 | } | |
158 | ||
159 | 133 | // newRangeDecoder initializes a range decoder. It reads five bytes from the |
160 | 134 | // reader and therefore may return an error. |
161 | 135 | func newRangeDecoder(br io.ByteReader) (d *rangeDecoder, err error) { |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
47 | 47 | chunkReader io.Reader |
48 | 48 | |
49 | 49 | cstate chunkState |
50 | ctype chunkType | |
51 | 50 | } |
52 | 51 | |
53 | 52 | // NewReader2 creates a reader for an LZMA2 chunk sequence. |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
50 | 50 | s.lenCodec.init() |
51 | 51 | s.repLenCodec.init() |
52 | 52 | s.distCodec.init() |
53 | } | |
54 | ||
55 | // initState initializes the state. | |
56 | func initState(s *state, p Properties) { | |
57 | *s = state{Properties: p} | |
58 | s.Reset() | |
59 | 53 | } |
60 | 54 | |
61 | 55 | // newState creates a new state from the give Properties. |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | // Use of this source code is governed by a BSD-style | |
2 | // license that can be found in the LICENSE file. | |
3 | ||
4 | package xz | |
5 | ||
6 | import "hash" | |
7 | ||
8 | type noneHash struct{} | |
9 | ||
10 | func (h noneHash) Write(p []byte) (n int, err error) { return len(p), nil } | |
11 | ||
12 | func (h noneHash) Sum(b []byte) []byte { return b } | |
13 | ||
14 | func (h noneHash) Reset() {} | |
15 | ||
16 | func (h noneHash) Size() int { return 0 } | |
17 | ||
18 | func (h noneHash) BlockSize() int { return 0 } | |
19 | ||
20 | func newNoneHash() hash.Hash { | |
21 | return &noneHash{} | |
22 | } |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | // Use of this source code is governed by a BSD-style | |
2 | // license that can be found in the LICENSE file. | |
3 | ||
4 | package xz | |
5 | ||
6 | import ( | |
7 | "bytes" | |
8 | "testing" | |
9 | ) | |
10 | ||
11 | func TestNoneHash(t *testing.T) { | |
12 | h := newNoneHash() | |
13 | ||
14 | p := []byte("foo") | |
15 | q := h.Sum(p) | |
16 | ||
17 | if !bytes.Equal(q, p) { | |
18 | t.Fatalf("h.Sum: got %q; want %q", q, p) | |
19 | } | |
20 | ||
21 | } |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
23 | 23 | type ReaderConfig struct { |
24 | 24 | DictCap int |
25 | 25 | SingleStream bool |
26 | } | |
27 | ||
28 | // fill replaces all zero values with their default values. | |
29 | func (c *ReaderConfig) fill() { | |
30 | if c.DictCap == 0 { | |
31 | c.DictCap = 8 * 1024 * 1024 | |
32 | } | |
33 | 26 | } |
34 | 27 | |
35 | 28 | // Verify checks the reader parameters for Validity. Zero values will be |
164 | 157 | return r, nil |
165 | 158 | } |
166 | 159 | |
167 | // errIndex indicates an error with the xz file index. | |
168 | var errIndex = errors.New("xz: error in xz file index") | |
169 | ||
170 | 160 | // readTail reads the index body and the xz footer. |
171 | 161 | func (r *streamReader) readTail() error { |
172 | index, n, err := readIndexBody(r.xz) | |
162 | index, n, err := readIndexBody(r.xz, len(r.index)) | |
173 | 163 | if err != nil { |
174 | 164 | if err == io.EOF { |
175 | 165 | err = io.ErrUnexpectedEOF |
176 | 166 | } |
177 | 167 | return err |
178 | 168 | } |
179 | if len(index) != len(r.index) { | |
180 | return fmt.Errorf("xz: index length is %d; want %d", | |
181 | len(index), len(r.index)) | |
182 | } | |
169 | ||
183 | 170 | for i, rec := range r.index { |
184 | 171 | if rec != index[i] { |
185 | 172 | return fmt.Errorf("xz: record %d is %v; want %v", |
264 | 251 | n int64 |
265 | 252 | hash hash.Hash |
266 | 253 | r io.Reader |
267 | err error | |
268 | 254 | } |
269 | 255 | |
270 | 256 | // newBlockReader creates a new block reader. |
282 | 268 | if err != nil { |
283 | 269 | return nil, err |
284 | 270 | } |
285 | br.r = io.TeeReader(fr, br.hash) | |
271 | if br.hash.Size() != 0 { | |
272 | br.r = io.TeeReader(fr, br.hash) | |
273 | } else { | |
274 | br.r = fr | |
275 | } | |
286 | 276 | |
287 | 277 | return br, nil |
288 | 278 | } |
310 | 300 | return record{br.unpaddedSize(), br.uncompressedSize()} |
311 | 301 | } |
312 | 302 | |
313 | // errBlockSize indicates that the size of the block in the block header | |
314 | // is wrong. | |
315 | var errBlockSize = errors.New("xz: wrong uncompressed size for block") | |
316 | ||
317 | 303 | // Read reads data from the block. |
318 | 304 | func (br *blockReader) Read(p []byte) (n int, err error) { |
319 | 305 | n, err = br.r.Read(p) |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
54 | 54 | } |
55 | 55 | } |
56 | 56 | |
57 | func TestReaaderMultipleStreams(t *testing.T) { | |
57 | func TestReaderMultipleStreams(t *testing.T) { | |
58 | 58 | data, err := ioutil.ReadFile("fox.xz") |
59 | 59 | if err != nil { |
60 | 60 | t.Fatalf("ReadFile error %s", err) |
78 | 78 | t.Fatalf("io.Copy error %s", err) |
79 | 79 | } |
80 | 80 | } |
81 | ||
82 | func TestCheckNone(t *testing.T) { | |
83 | const file = "fox-check-none.xz" | |
84 | xz, err := os.Open(file) | |
85 | if err != nil { | |
86 | t.Fatalf("os.Open(%q) error %s", file, err) | |
87 | } | |
88 | r, err := NewReader(xz) | |
89 | if err != nil { | |
90 | t.Fatalf("NewReader error %s", err) | |
91 | } | |
92 | var buf bytes.Buffer | |
93 | if _, err = io.Copy(&buf, r); err != nil { | |
94 | t.Fatalf("io.Copy error %s", err) | |
95 | } | |
96 | } |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
5 | 5 | |
6 | 6 | import ( |
7 | 7 | "errors" |
8 | "fmt" | |
8 | 9 | "hash" |
9 | 10 | "io" |
10 | 11 | |
17 | 18 | DictCap int |
18 | 19 | BufSize int |
19 | 20 | BlockSize int64 |
20 | // checksum method: CRC32, CRC64 or SHA256 | |
21 | // checksum method: CRC32, CRC64 or SHA256 (default: CRC64) | |
21 | 22 | CheckSum byte |
23 | // Forces NoChecksum (default: false) | |
24 | NoCheckSum bool | |
22 | 25 | // match algorithm |
23 | 26 | Matcher lzma.MatchAlgorithm |
24 | 27 | } |
39 | 42 | } |
40 | 43 | if c.CheckSum == 0 { |
41 | 44 | c.CheckSum = CRC64 |
45 | } | |
46 | if c.NoCheckSum { | |
47 | c.CheckSum = None | |
42 | 48 | } |
43 | 49 | } |
44 | 50 | |
184 | 190 | return nil, err |
185 | 191 | } |
186 | 192 | data, err := w.h.MarshalBinary() |
193 | if err != nil { | |
194 | return nil, fmt.Errorf("w.h.MarshalBinary(): error %w", err) | |
195 | } | |
187 | 196 | if _, err = xz.Write(data); err != nil { |
188 | 197 | return nil, err |
189 | 198 | } |
283 | 292 | if err != nil { |
284 | 293 | return nil, err |
285 | 294 | } |
286 | bw.mw = io.MultiWriter(bw.w, bw.hash) | |
295 | if bw.hash.Size() != 0 { | |
296 | bw.mw = io.MultiWriter(bw.w, bw.hash) | |
297 | } else { | |
298 | bw.mw = bw.w | |
299 | } | |
287 | 300 | return bw, nil |
288 | 301 | } |
289 | 302 |
0 | // Copyright 2014-2017 Ulrich Kunitz. All rights reserved. | |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | 1 | // Use of this source code is governed by a BSD-style |
2 | 2 | // license that can be found in the LICENSE file. |
3 | 3 | |
135 | 135 | t.Fatal("decompressed data differs from original") |
136 | 136 | } |
137 | 137 | } |
138 | ||
139 | func TestWriterNoneCheck(t *testing.T) { | |
140 | const txtlen = 1023 | |
141 | var buf bytes.Buffer | |
142 | io.CopyN(&buf, randtxt.NewReader(rand.NewSource(41)), txtlen) | |
143 | txt := buf.String() | |
144 | ||
145 | buf.Reset() | |
146 | w, err := WriterConfig{NoCheckSum: true}.NewWriter(&buf) | |
147 | if err != nil { | |
148 | t.Fatalf("NewWriter error %s", err) | |
149 | } | |
150 | n, err := io.WriteString(w, txt) | |
151 | if err != nil { | |
152 | t.Fatalf("WriteString error %s", err) | |
153 | } | |
154 | if n != len(txt) { | |
155 | t.Fatalf("WriteString wrote %d bytes; want %d", n, len(txt)) | |
156 | } | |
157 | if err = w.Close(); err != nil { | |
158 | t.Fatalf("Close error %s", err) | |
159 | } | |
160 | t.Logf("buf.Len() %d", buf.Len()) | |
161 | r, err := NewReader(&buf) | |
162 | if err != nil { | |
163 | t.Fatalf("NewReader error %s", err) | |
164 | } | |
165 | var out bytes.Buffer | |
166 | k, err := io.Copy(&out, r) | |
167 | if err != nil { | |
168 | t.Fatalf("Decompressing copy error %s after %d bytes", err, n) | |
169 | } | |
170 | if k != txtlen { | |
171 | t.Fatalf("Decompression data length %d; want %d", k, txtlen) | |
172 | } | |
173 | if txt != out.String() { | |
174 | t.Fatal("decompressed data differs from original") | |
175 | } | |
176 | } |
0 | // Copyright 2014-2021 Ulrich Kunitz. All rights reserved. | |
1 | // Use of this source code is governed by a BSD-style | |
2 | // license that can be found in the LICENSE file. | |
3 | ||
4 | package xz_test | |
5 | ||
6 | import ( | |
7 | "bytes" | |
8 | "io/ioutil" | |
9 | "testing" | |
10 | ||
11 | "github.com/ulikunitz/xz" | |
12 | ) | |
13 | ||
14 | func TestPanic(t *testing.T) { | |
15 | data := []byte([]uint8{253, 55, 122, 88, 90, 0, 0, 0, 255, 18, 217, 65, 0, 189, 191, 239, 189, 191, 239, 48}) | |
16 | t.Logf("%q", string(data)) | |
17 | t.Logf("0x%02x", data) | |
18 | r, err := xz.NewReader(bytes.NewReader(data)) | |
19 | if err != nil { | |
20 | t.Logf("xz.NewReader error %s", err) | |
21 | return | |
22 | } | |
23 | _, err = ioutil.ReadAll(r) | |
24 | if err != nil { | |
25 | t.Logf("ioutil.ReadAll(r) error %s", err) | |
26 | return | |
27 | } | |
28 | } |