@patrickdk77/archive-defuse 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/lzma1/NOTICE +32 -18
- package/dist/lzma1/crc32.d.ts +2 -1
- package/dist/lzma1/crc32.js +3 -2
- package/dist/lzma1/hash234.d.ts +3 -1
- package/dist/lzma1/hash234.js +9 -4
- package/dist/lzma1/hc4.d.ts +3 -2
- package/dist/lzma1/hc4.js +6 -4
- package/dist/lzma1/header.js +1 -1
- package/dist/lzma1/lz-decoder.d.ts +14 -14
- package/dist/lzma1/lz-decoder.js +15 -33
- package/dist/lzma1/lz-encoder.d.ts +3 -2
- package/dist/lzma1/lz-encoder.js +6 -4
- package/dist/lzma1/lzma-coder.d.ts +51 -27
- package/dist/lzma1/lzma-coder.js +114 -48
- package/dist/lzma1/lzma-decoder.d.ts +41 -19
- package/dist/lzma1/lzma-decoder.js +159 -437
- package/dist/lzma1/lzma-encoder-fast.d.ts +2 -1
- package/dist/lzma1/lzma-encoder-fast.js +3 -2
- package/dist/lzma1/lzma-encoder.d.ts +68 -40
- package/dist/lzma1/lzma-encoder.js +289 -232
- package/dist/lzma1/lzma2-decoder.d.ts +17 -2
- package/dist/lzma1/lzma2-decoder.js +71 -15
- package/dist/lzma1/range-coder.d.ts +4 -0
- package/dist/lzma1/range-coder.js +5 -1
- package/dist/lzma1/range-decoder.d.ts +22 -22
- package/dist/lzma1/range-decoder.js +74 -32
- package/dist/lzma1/range-encoder.d.ts +26 -28
- package/dist/lzma1/range-encoder.js +98 -150
- package/package.json +1 -1
package/dist/lzma1/lzma-coder.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Copied from lzma1 (Apache-2.0, Copyright Filip Seman) and changed for
|
|
2
|
+
// Copied from lzma1 0.6.1 (Apache-2.0, Copyright Filip Seman) and changed for archive-defuse. NOTICE in this folder lists the changes.
|
|
3
3
|
/**
|
|
4
4
|
* Probability models and state machine shared by the LZMA encoder and decoder.
|
|
5
5
|
*
|
|
6
|
-
* Ported from XZ for Java (0BSD)
|
|
6
|
+
* Ported from XZ for Java (0BSD), `src/org/tukaani/xz/lzma/LZMACoder.java`
|
|
7
|
+
* and `State.java`, by Lasse Collin and Igor Pavlov.
|
|
8
|
+
*
|
|
9
|
+
* The nested coder classes of the Java code (`LiteralCoder.LiteralSubcoder`,
|
|
10
|
+
* `LengthCoder`) are top-level classes here, because TypeScript has no inner
|
|
11
|
+
* classes; subclasses in the encoder and decoder files pass their outer
|
|
12
|
+
* coder explicitly where Java captures it implicitly.
|
|
7
13
|
*/
|
|
8
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.LzmaCoder = exports.LITERAL = exports.REP_LEN = exports.MATCH_LEN = exports.DIST_ALIGN = exports.DIST_SPECIAL = exports.
|
|
10
|
-
exports.
|
|
15
|
+
exports.LengthCoder = exports.LiteralSubcoder = exports.LiteralCoder = exports.LzmaCoder = exports.LITERAL = exports.REP_LEN = exports.MATCH_LEN = exports.DIST_ALIGN = exports.DIST_SPECIAL = exports.DIST_SLOT_OFFSET = exports.IS_REP0_LONG = exports.IS_REP2 = exports.IS_REP1 = exports.IS_REP0 = exports.IS_REP = exports.IS_MATCH = exports.STATES = exports.State = exports.REPS = exports.ALIGN_MASK = exports.ALIGN_SIZE = exports.ALIGN_BITS = exports.FULL_DISTANCES = exports.DIST_MODEL_END = exports.DIST_MODEL_START = exports.DIST_SLOT_BITS = exports.DIST_SLOTS = exports.DIST_STATES = exports.LEN_SIZE = exports.LEN_HIGH = exports.LEN_MID = exports.LEN_LOW = exports.LEN_CHOICE2 = exports.LEN_CHOICE = exports.MATCH_LEN_MAX = exports.HIGH_SYMBOLS = exports.MID_SYMBOLS = exports.LOW_SYMBOLS = exports.MATCH_LEN_MIN = exports.POS_STATES_MAX = void 0;
|
|
16
|
+
exports.getDistState = getDistState;
|
|
17
|
+
exports.probsSize = probsSize;
|
|
11
18
|
exports.stateAfterLiteral = stateAfterLiteral;
|
|
12
19
|
exports.stateAfterMatch = stateAfterMatch;
|
|
13
20
|
exports.stateAfterLongRep = stateAfterLongRep;
|
|
14
21
|
exports.stateAfterShortRep = stateAfterShortRep;
|
|
15
|
-
exports.
|
|
22
|
+
exports.isLiteralState = isLiteralState;
|
|
16
23
|
exports.distSpecialOffset = distSpecialOffset;
|
|
17
|
-
exports.probsSize = probsSize;
|
|
18
24
|
const range_coder_1 = require("./range-coder");
|
|
19
25
|
exports.POS_STATES_MAX = 1 << 4;
|
|
20
26
|
exports.MATCH_LEN_MIN = 2;
|
|
@@ -34,8 +40,9 @@ exports.LEN_MID = exports.LEN_LOW + exports.POS_STATES_MAX * exports.LOW_SYMBOLS
|
|
|
34
40
|
exports.LEN_HIGH = exports.LEN_MID + exports.POS_STATES_MAX * exports.MID_SYMBOLS;
|
|
35
41
|
exports.LEN_SIZE = exports.LEN_HIGH + exports.HIGH_SYMBOLS;
|
|
36
42
|
exports.DIST_STATES = 4;
|
|
43
|
+
exports.DIST_SLOTS = 1 << 6;
|
|
44
|
+
/** Bits of a distance slot: the depth of the slot bit trees. */
|
|
37
45
|
exports.DIST_SLOT_BITS = 6;
|
|
38
|
-
exports.DIST_SLOT_COUNT = 1 << exports.DIST_SLOT_BITS;
|
|
39
46
|
exports.DIST_MODEL_START = 4;
|
|
40
47
|
exports.DIST_MODEL_END = 14;
|
|
41
48
|
exports.FULL_DISTANCES = 1 << (exports.DIST_MODEL_END / 2);
|
|
@@ -44,13 +51,54 @@ exports.ALIGN_SIZE = 1 << exports.ALIGN_BITS;
|
|
|
44
51
|
exports.ALIGN_MASK = exports.ALIGN_SIZE - 1;
|
|
45
52
|
/** Number of recent match distances ("reps") that can be reused cheaply. */
|
|
46
53
|
exports.REPS = 4;
|
|
54
|
+
/** Distances are coded with different probabilities for lengths 2, 3, 4 and 5+. */
|
|
55
|
+
function getDistState(len) {
|
|
56
|
+
return len < exports.DIST_STATES + exports.MATCH_LEN_MIN ? len - exports.MATCH_LEN_MIN : exports.DIST_STATES - 1;
|
|
57
|
+
}
|
|
58
|
+
/** Number of probabilities of a coder with `lc` and `lp` literal bits. */
|
|
59
|
+
function probsSize(lc, lp) {
|
|
60
|
+
return exports.LITERAL + (0x300 << (lc + lp));
|
|
61
|
+
}
|
|
47
62
|
/**
|
|
48
63
|
* The coder state remembers the kinds of the most recent symbols
|
|
49
64
|
* (literal, match, long rep, short rep). It selects which probabilities
|
|
50
65
|
* are used for the next symbol.
|
|
51
66
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
class State {
|
|
68
|
+
static STATES = 12;
|
|
69
|
+
state = 0;
|
|
70
|
+
constructor(other) {
|
|
71
|
+
if (other !== undefined) {
|
|
72
|
+
this.state = other.state;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
reset() {
|
|
76
|
+
this.state = LIT_LIT;
|
|
77
|
+
}
|
|
78
|
+
get() {
|
|
79
|
+
return this.state;
|
|
80
|
+
}
|
|
81
|
+
set(other) {
|
|
82
|
+
this.state = other.state;
|
|
83
|
+
}
|
|
84
|
+
updateLiteral() {
|
|
85
|
+
this.state = stateAfterLiteral(this.state);
|
|
86
|
+
}
|
|
87
|
+
updateMatch() {
|
|
88
|
+
this.state = stateAfterMatch(this.state);
|
|
89
|
+
}
|
|
90
|
+
updateLongRep() {
|
|
91
|
+
this.state = stateAfterLongRep(this.state);
|
|
92
|
+
}
|
|
93
|
+
updateShortRep() {
|
|
94
|
+
this.state = stateAfterShortRep(this.state);
|
|
95
|
+
}
|
|
96
|
+
isLiteral() {
|
|
97
|
+
return isLiteralState(this.state);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.State = State;
|
|
101
|
+
exports.STATES = State.STATES;
|
|
54
102
|
const LIT_STATES = 7;
|
|
55
103
|
const LIT_LIT = 0;
|
|
56
104
|
const SHORTREP_LIT_LIT = 3;
|
|
@@ -59,16 +107,21 @@ const LIT_LONGREP = 8;
|
|
|
59
107
|
const LIT_SHORTREP = 9;
|
|
60
108
|
const NONLIT_MATCH = 10;
|
|
61
109
|
const NONLIT_REP = 11;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
110
|
+
/*
|
|
111
|
+
* The transitions of `State` on a plain state value, so that the optimum
|
|
112
|
+
* search can keep its per-position states as numbers. `State`'s methods
|
|
113
|
+
* call these, so the state machine is written once.
|
|
114
|
+
*/
|
|
66
115
|
function stateAfterLiteral(state) {
|
|
67
|
-
if (state <= SHORTREP_LIT_LIT)
|
|
116
|
+
if (state <= SHORTREP_LIT_LIT) {
|
|
68
117
|
return LIT_LIT;
|
|
69
|
-
|
|
118
|
+
}
|
|
119
|
+
else if (state <= LIT_SHORTREP) {
|
|
70
120
|
return state - 3;
|
|
71
|
-
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
return state - 6;
|
|
124
|
+
}
|
|
72
125
|
}
|
|
73
126
|
function stateAfterMatch(state) {
|
|
74
127
|
return state < LIT_STATES ? LIT_MATCH : NONLIT_MATCH;
|
|
@@ -79,14 +132,14 @@ function stateAfterLongRep(state) {
|
|
|
79
132
|
function stateAfterShortRep(state) {
|
|
80
133
|
return state < LIT_STATES ? LIT_SHORTREP : NONLIT_REP;
|
|
81
134
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return len < exports.DIST_STATES + exports.MATCH_LEN_MIN ? len - exports.MATCH_LEN_MIN : exports.DIST_STATES - 1;
|
|
135
|
+
function isLiteralState(state) {
|
|
136
|
+
return state < LIT_STATES;
|
|
85
137
|
}
|
|
86
138
|
/**
|
|
87
139
|
* Layout of the probability array. All probabilities of a coder live in one
|
|
88
|
-
* `Uint16Array`, like in the LZMA SDK and liblzma
|
|
89
|
-
* and the hot loops index a
|
|
140
|
+
* `Uint16Array`, like in the LZMA SDK and liblzma, instead of the
|
|
141
|
+
* Java code's per-model arrays: one allocation, and the hot loops index a
|
|
142
|
+
* single array.
|
|
90
143
|
*
|
|
91
144
|
* Bit trees of `2^n` leaves occupy `2^n` entries starting at their offset;
|
|
92
145
|
* index 0 of a tree is unused.
|
|
@@ -98,9 +151,9 @@ exports.IS_REP1 = exports.IS_REP0 + exports.STATES; // [state]
|
|
|
98
151
|
exports.IS_REP2 = exports.IS_REP1 + exports.STATES; // [state]
|
|
99
152
|
exports.IS_REP0_LONG = exports.IS_REP2 + exports.STATES; // [state][posState]
|
|
100
153
|
/** Bit trees of 6 bits per distance state. */
|
|
101
|
-
exports.
|
|
154
|
+
exports.DIST_SLOT_OFFSET = exports.IS_REP0_LONG + exports.STATES * exports.POS_STATES_MAX;
|
|
102
155
|
/** Reverse bit trees for the low bits of distances in slots 4-13. */
|
|
103
|
-
exports.DIST_SPECIAL = exports.
|
|
156
|
+
exports.DIST_SPECIAL = exports.DIST_SLOT_OFFSET + exports.DIST_STATES * exports.DIST_SLOTS;
|
|
104
157
|
/** Reverse bit tree for the lowest 4 bits of distances in slots 14+. */
|
|
105
158
|
exports.DIST_ALIGN = exports.DIST_SPECIAL + exports.FULL_DISTANCES - exports.DIST_MODEL_END;
|
|
106
159
|
exports.MATCH_LEN = exports.DIST_ALIGN + exports.ALIGN_SIZE;
|
|
@@ -116,19 +169,10 @@ exports.LITERAL = exports.REP_LEN + exports.LEN_SIZE;
|
|
|
116
169
|
function distSpecialOffset(distSlot, base) {
|
|
117
170
|
return exports.DIST_SPECIAL + base - distSlot - 1;
|
|
118
171
|
}
|
|
119
|
-
/** Number of probabilities of a coder with `lc` and `lp` literal bits. */
|
|
120
|
-
function probsSize(lc, lp) {
|
|
121
|
-
return exports.LITERAL + (0x300 << (lc + lp));
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Probability models and coder state shared by the encoder and decoder.
|
|
125
|
-
*/
|
|
126
172
|
class LzmaCoder {
|
|
127
173
|
posMask;
|
|
128
|
-
lc;
|
|
129
|
-
literalPosMask;
|
|
130
174
|
reps = new Int32Array(exports.REPS);
|
|
131
|
-
state =
|
|
175
|
+
state = new State();
|
|
132
176
|
probs;
|
|
133
177
|
/**
|
|
134
178
|
* @param probs Probability array to reuse, of `probsSize(lc, lp)` entries.
|
|
@@ -136,27 +180,49 @@ class LzmaCoder {
|
|
|
136
180
|
*/
|
|
137
181
|
constructor(lc, lp, pb, probs) {
|
|
138
182
|
this.posMask = (1 << pb) - 1;
|
|
139
|
-
this.lc = lc;
|
|
140
|
-
this.literalPosMask = (1 << lp) - 1;
|
|
141
183
|
this.probs = probs ?? new Uint16Array(probsSize(lc, lp));
|
|
142
184
|
}
|
|
143
185
|
reset() {
|
|
144
|
-
this.reps
|
|
145
|
-
this.
|
|
186
|
+
this.reps[0] = 0;
|
|
187
|
+
this.reps[1] = 0;
|
|
188
|
+
this.reps[2] = 0;
|
|
189
|
+
this.reps[3] = 0;
|
|
190
|
+
this.state.reset();
|
|
146
191
|
(0, range_coder_1.initProbs)(this.probs);
|
|
147
192
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
193
|
+
}
|
|
194
|
+
exports.LzmaCoder = LzmaCoder;
|
|
195
|
+
class LiteralCoder {
|
|
196
|
+
lc;
|
|
197
|
+
literalPosMask;
|
|
198
|
+
constructor(lc, lp) {
|
|
199
|
+
this.lc = lc;
|
|
200
|
+
this.literalPosMask = (1 << lp) - 1;
|
|
201
|
+
}
|
|
202
|
+
getSubcoderIndex(prevByte, pos) {
|
|
157
203
|
const low = prevByte >> (8 - this.lc);
|
|
158
204
|
const high = (pos & this.literalPosMask) << this.lc;
|
|
159
|
-
return
|
|
205
|
+
return low + high;
|
|
160
206
|
}
|
|
161
207
|
}
|
|
162
|
-
exports.
|
|
208
|
+
exports.LiteralCoder = LiteralCoder;
|
|
209
|
+
class LiteralSubcoder {
|
|
210
|
+
probs;
|
|
211
|
+
/** Offset of this subcoder's 0x300 probabilities in `probs`. */
|
|
212
|
+
literalOffset;
|
|
213
|
+
constructor(probs, literalOffset) {
|
|
214
|
+
this.probs = probs;
|
|
215
|
+
this.literalOffset = literalOffset;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.LiteralSubcoder = LiteralSubcoder;
|
|
219
|
+
class LengthCoder {
|
|
220
|
+
probs;
|
|
221
|
+
/** Offset of this length coder in `probs`. */
|
|
222
|
+
coder;
|
|
223
|
+
constructor(probs, coder) {
|
|
224
|
+
this.probs = probs;
|
|
225
|
+
this.coder = coder;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.LengthCoder = LengthCoder;
|
|
@@ -1,36 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LZMA decoder: turns range-coded symbols back into literals and matches.
|
|
3
3
|
*
|
|
4
|
-
* Ported from XZ for Java (0BSD)
|
|
5
|
-
*
|
|
4
|
+
* Ported from XZ for Java (0BSD), `src/org/tukaani/xz/lzma/LZMADecoder.java`,
|
|
5
|
+
* by Lasse Collin and Igor Pavlov.
|
|
6
|
+
*
|
|
7
|
+
* Contract adaptations, pinned by the recorded malformed-stream
|
|
8
|
+
* expectations in `fixtures/malformed.json` and
|
|
9
|
+
* `fixtures/raw-malformed.json`:
|
|
10
|
+
* - `decode(outLimit, inLimit)` drives the loop by the number of bytes
|
|
11
|
+
* produced (`outPos`) and the input position, instead of the Java code's
|
|
12
|
+
* `LZDecoder` window limit, because the input arrives in chunks and the
|
|
13
|
+
* output goes to a sink. `outPos` also provides the position bits
|
|
14
|
+
* (`posState` and the literal subcoder index). The Java code reads them
|
|
15
|
+
* from `LZDecoder.getPos()`, its position in a circular dictionary
|
|
16
|
+
* buffer that `LZMAInputStream.getDictSize` and
|
|
17
|
+
* `LZMA2InputStream.getDictSize` round up to a multiple of 16 for exactly
|
|
18
|
+
* this purpose, so that position equals `outPos` modulo 16. LZMA2 sets
|
|
19
|
+
* `outPos` to the bytes since the last dictionary reset, where
|
|
20
|
+
* `LZDecoder.reset` puts the Java position back to 0. The position masks
|
|
21
|
+
* keep at most the low 4 bits (`pb`, `lp` <= 4), so the two agree for
|
|
22
|
+
* every dictionary size.
|
|
23
|
+
* - The end marker returns `true` instead of surfacing as the error the
|
|
24
|
+
* Java code's `lz.repeat` raises for it; a match that would cross the
|
|
25
|
+
* output limit, the declared size or the end of an LZMA2 chunk, is an
|
|
26
|
+
* error.
|
|
6
27
|
*/
|
|
7
28
|
import type { LzDecoder } from './lz-decoder';
|
|
8
29
|
import { LzmaCoder } from './lzma-coder';
|
|
9
30
|
import type { RangeDecoder } from './range-decoder';
|
|
10
31
|
export declare class LzmaDecoder extends LzmaCoder {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
32
|
+
readonly lz: LzDecoder;
|
|
33
|
+
readonly rc: RangeDecoder;
|
|
34
|
+
private readonly literalDecoder;
|
|
35
|
+
private readonly matchLenDecoder;
|
|
36
|
+
private readonly repLenDecoder;
|
|
37
|
+
/** Bytes decoded so far; for LZMA2, since the last dictionary reset. */
|
|
14
38
|
outPos: number;
|
|
39
|
+
/**
|
|
40
|
+
* @param probs Probability array of an earlier decoder to reuse, of
|
|
41
|
+
* `probsSize(lc, lp)` entries; a new one is allocated without it.
|
|
42
|
+
*/
|
|
15
43
|
constructor(lz: LzDecoder, rc: RangeDecoder, lc: number, lp: number, pb: number, probs?: Uint16Array);
|
|
16
44
|
/**
|
|
17
|
-
*
|
|
45
|
+
* Returns true if LZMA end marker was detected. It is encoded as
|
|
46
|
+
* the maximum match distance which with int32 values becomes -1.
|
|
47
|
+
*/
|
|
48
|
+
private endMarkerDetected;
|
|
49
|
+
/**
|
|
50
|
+
* Decodes symbols until `outPos` reaches `outLimit` or the input
|
|
18
51
|
* position passes `inLimit`.
|
|
19
52
|
*
|
|
20
|
-
* Performance: this is the hot loop of decompression. The range decoder
|
|
21
|
-
* state, the coder state and the reps live in local variables, and the
|
|
22
|
-
* bit decoding step (`decodeBit` in `range-coder_test.ts`) is repeated inline:
|
|
23
|
-
*
|
|
24
|
-
* prob = probs[i];
|
|
25
|
-
* bound = (range >>> 11) * prob;
|
|
26
|
-
* if (code < bound) { range = bound; probs[i] = prob + ((2048 - prob) >>> 5); bit 0 }
|
|
27
|
-
* else { range -= bound; code -= bound; probs[i] = prob - (prob >>> 5); bit 1 }
|
|
28
|
-
* if (range < 2^24) { shift in the next input byte }
|
|
29
|
-
*
|
|
30
|
-
* With the state in object fields, engines store and reload it around
|
|
31
|
-
* every probability update, which costs 10-15% on V8.
|
|
32
|
-
*
|
|
33
53
|
* @returns `true` if the end marker was decoded
|
|
34
54
|
*/
|
|
35
55
|
decode(outLimit: number, inLimit: number): boolean;
|
|
56
|
+
private decodeMatch;
|
|
57
|
+
private decodeRepMatch;
|
|
36
58
|
}
|