@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
|
@@ -1,41 +1,68 @@
|
|
|
1
1
|
"use strict";
|
|
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
|
+
/**
|
|
4
|
+
* Range encoder writing to its own growable buffer.
|
|
5
|
+
*
|
|
6
|
+
* Ported from XZ for Java (0BSD), `src/org/tukaani/xz/rangecoder/RangeEncoder.java`
|
|
7
|
+
* and `RangeEncoderToBuffer.java`, by Lasse Collin and Igor Pavlov.
|
|
8
|
+
*
|
|
9
|
+
* Integer adaptations (see the hazard checklist in `docs/verification.md`):
|
|
10
|
+
* - `low` needs 33 bits (32 bits plus a carry), so it is a regular number;
|
|
11
|
+
* doubles represent integers up to 2^53 exactly. The carry test uses
|
|
12
|
+
* division instead of `low >>> 32`.
|
|
13
|
+
* - `range` is an unsigned 32-bit value in a regular number: `<<` is
|
|
14
|
+
* followed by `>>> 0`, and `(range & TOP_MASK) == 0` becomes an
|
|
15
|
+
* unsigned `range < TOP_VALUE`.
|
|
16
|
+
* - Bitwise ops on values that may exceed 2^31 are kept off the signed
|
|
17
|
+
* int32 path (`low`'s 24-bit wrap multiplies by 256 instead of
|
|
18
|
+
* shifting).
|
|
19
|
+
*/
|
|
2
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
21
|
exports.RangeEncoder = void 0;
|
|
22
|
+
exports.createPriceTable = createPriceTable;
|
|
4
23
|
exports.getBitPrice = getBitPrice;
|
|
5
24
|
exports.getBitTreePrice = getBitTreePrice;
|
|
6
25
|
exports.getReverseBitTreePrice = getReverseBitTreePrice;
|
|
7
26
|
exports.getDirectBitsPrice = getDirectBitsPrice;
|
|
8
|
-
// Copied from lzma1 (Apache-2.0, Copyright Filip Seman) and changed for lzma-defuse. NOTICE in this folder lists the changes.
|
|
9
27
|
const range_coder_1 = require("./range-coder");
|
|
10
28
|
const MOVE_REDUCING_BITS = 4;
|
|
11
29
|
const BIT_PRICE_SHIFT_BITS = 4;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
30
|
+
// Bit prices in 1/16 bits: the price of a 0 bit, then the same prices
|
|
31
|
+
// reversed, which are the prices of a 1 bit, at
|
|
32
|
+
// (bit << 7) | (prob >>> MOVE_REDUCING_BITS). One lookup without the Java
|
|
33
|
+
// code's bit flip was measured faster.
|
|
34
|
+
const bitPrices = createBitPriceTable();
|
|
35
|
+
function createBitPriceTable() {
|
|
36
|
+
const prices = createPriceTable();
|
|
37
|
+
const half = prices.length;
|
|
38
|
+
const table = new Uint32Array(2 * half);
|
|
39
|
+
for (let i = 0; i < half; ++i) {
|
|
40
|
+
table[i] = prices[i];
|
|
41
|
+
table[half + i] = prices[half - 1 - i];
|
|
42
|
+
}
|
|
43
|
+
return table;
|
|
44
|
+
}
|
|
17
45
|
function createPriceTable() {
|
|
18
|
-
const
|
|
46
|
+
const table = new Uint32Array(range_coder_1.BIT_MODEL_TOTAL >>> MOVE_REDUCING_BITS);
|
|
19
47
|
for (let i = (1 << MOVE_REDUCING_BITS) / 2; i < range_coder_1.BIT_MODEL_TOTAL; i += 1 << MOVE_REDUCING_BITS) {
|
|
20
|
-
// Approximate -log2(i / BIT_MODEL_TOTAL) using repeated squaring.
|
|
21
48
|
let w = i;
|
|
22
49
|
let bitCount = 0;
|
|
23
50
|
for (let j = 0; j < BIT_PRICE_SHIFT_BITS; ++j) {
|
|
24
51
|
w *= w;
|
|
25
52
|
bitCount <<= 1;
|
|
26
|
-
while (w
|
|
53
|
+
while ((w & 0xffff0000) !== 0) {
|
|
27
54
|
w >>>= 1;
|
|
28
55
|
++bitCount;
|
|
29
56
|
}
|
|
30
57
|
}
|
|
31
|
-
|
|
58
|
+
table[i >> MOVE_REDUCING_BITS] = (range_coder_1.BIT_MODEL_TOTAL_BITS << BIT_PRICE_SHIFT_BITS) - 15 - bitCount;
|
|
32
59
|
}
|
|
33
|
-
return
|
|
60
|
+
return table;
|
|
34
61
|
}
|
|
35
62
|
function getBitPrice(prob, bit) {
|
|
36
|
-
|
|
63
|
+
// NOTE: Unlike in encodeBit(), here bit must be 0 or 1.
|
|
64
|
+
return bitPrices[(bit << 7) | (prob >>> MOVE_REDUCING_BITS)];
|
|
37
65
|
}
|
|
38
|
-
/** Price of a `bits`-bit symbol coded MSB-first with the bit tree at `offset`. */
|
|
39
66
|
function getBitTreePrice(probs, offset, bits, symbolIn) {
|
|
40
67
|
let symbol = symbolIn;
|
|
41
68
|
let price = 0;
|
|
@@ -47,42 +74,47 @@ function getBitTreePrice(probs, offset, bits, symbolIn) {
|
|
|
47
74
|
} while (symbol !== 1);
|
|
48
75
|
return price;
|
|
49
76
|
}
|
|
50
|
-
/** Price of a `bits`-bit symbol coded LSB-first with the bit tree at `offset`. */
|
|
51
77
|
function getReverseBitTreePrice(probs, offset, bits, symbolIn) {
|
|
52
78
|
let symbol = symbolIn;
|
|
53
79
|
let price = 0;
|
|
54
80
|
let index = 1;
|
|
55
|
-
|
|
81
|
+
symbol |= 1 << bits;
|
|
82
|
+
do {
|
|
56
83
|
const bit = symbol & 1;
|
|
57
84
|
symbol >>>= 1;
|
|
58
85
|
price += getBitPrice(probs[offset + index], bit);
|
|
59
86
|
index = (index << 1) | bit;
|
|
60
|
-
}
|
|
87
|
+
} while (symbol !== 1);
|
|
61
88
|
return price;
|
|
62
89
|
}
|
|
63
|
-
/** Price of bits coded with a fixed 50% probability. */
|
|
64
90
|
function getDirectBitsPrice(count) {
|
|
65
91
|
return count << BIT_PRICE_SHIFT_BITS;
|
|
66
92
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Range encoder writing to its own growable buffer.
|
|
69
|
-
*
|
|
70
|
-
* `low` needs 33 bits (32 bits plus a carry), so it is kept as a regular
|
|
71
|
-
* number instead of an int32. Doubles represent integers up to 2^53 exactly.
|
|
72
|
-
*
|
|
73
|
-
* Performance: like `RangeDecoder`, the methods that encode several bits
|
|
74
|
-
* keep `range` and `low` in local variables for the whole symbol.
|
|
75
|
-
*/
|
|
76
93
|
class RangeEncoder {
|
|
77
94
|
low = 0;
|
|
78
95
|
range = 0xffffffff;
|
|
79
96
|
cache = 0;
|
|
97
|
+
/**
|
|
98
|
+
* NOTE: int is OK for LZMA2 because a compressed chunk is not more
|
|
99
|
+
* than 64 KiB, but with LZMA1 there is no chunking so in theory
|
|
100
|
+
* cacheSize can grow very big. A JS number counts well past 2^32.
|
|
101
|
+
*/
|
|
80
102
|
cacheSize = 1;
|
|
103
|
+
// Instead of the fixed output array of RangeEncoderToBuffer, the
|
|
104
|
+
// buffer grows on demand and the written bytes are handed out with
|
|
105
|
+
// take()/finish(), because the compressed size isn't known in advance
|
|
106
|
+
// here (contract adaptation).
|
|
81
107
|
buf;
|
|
82
108
|
size = 0;
|
|
83
109
|
constructor(initialCapacity) {
|
|
84
110
|
this.buf = new Uint8Array(Math.max(64, initialCapacity));
|
|
85
111
|
}
|
|
112
|
+
reset() {
|
|
113
|
+
this.low = 0;
|
|
114
|
+
this.range = 0xffffffff;
|
|
115
|
+
this.cache = 0x00;
|
|
116
|
+
this.cacheSize = 1;
|
|
117
|
+
}
|
|
86
118
|
/** Appends bytes that are not range coded, e.g. a header. */
|
|
87
119
|
writeBytes(bytes) {
|
|
88
120
|
this.ensureCapacity(bytes.length);
|
|
@@ -97,16 +129,34 @@ class RangeEncoder {
|
|
|
97
129
|
}
|
|
98
130
|
/** Flushes all pending bytes and returns the rest of the output. */
|
|
99
131
|
finish() {
|
|
100
|
-
let low = this.low;
|
|
101
132
|
for (let i = 0; i < 5; ++i) {
|
|
102
|
-
|
|
133
|
+
this.shiftLow();
|
|
103
134
|
}
|
|
104
|
-
this.low = low;
|
|
105
135
|
return this.size === this.buf.length ? this.buf : this.buf.slice(0, this.size);
|
|
106
136
|
}
|
|
137
|
+
writeByte(b) {
|
|
138
|
+
this.ensureCapacity(1);
|
|
139
|
+
this.buf[this.size++] = b;
|
|
140
|
+
}
|
|
141
|
+
shiftLow() {
|
|
142
|
+
// (int)(low >>> 32), the pending carry: 0 or 1.
|
|
143
|
+
const lowHi = Math.floor(this.low / 0x100000000);
|
|
144
|
+
if (lowHi !== 0 || this.low < 0xff000000) {
|
|
145
|
+
let temp = this.cache;
|
|
146
|
+
do {
|
|
147
|
+
this.writeByte(temp + lowHi);
|
|
148
|
+
temp = 0xff;
|
|
149
|
+
} while (--this.cacheSize !== 0);
|
|
150
|
+
this.cache = (this.low >>> 24) & 0xff;
|
|
151
|
+
}
|
|
152
|
+
++this.cacheSize;
|
|
153
|
+
// (low & 0x00FFFFFF) << 8, kept exact above 2^31 with * 256.
|
|
154
|
+
this.low = (this.low & 0x00ffffff) * 256;
|
|
155
|
+
}
|
|
107
156
|
encodeBit(probs, index, bit) {
|
|
108
157
|
const prob = probs[index];
|
|
109
158
|
const bound = (this.range >>> range_coder_1.BIT_MODEL_TOTAL_BITS) * prob;
|
|
159
|
+
// NOTE: Any non-zero value for bit is taken as 1.
|
|
110
160
|
if (bit === 0) {
|
|
111
161
|
this.range = bound;
|
|
112
162
|
probs[index] = prob + ((range_coder_1.BIT_MODEL_TOTAL - prob) >>> range_coder_1.MOVE_BITS);
|
|
@@ -118,145 +168,43 @@ class RangeEncoder {
|
|
|
118
168
|
}
|
|
119
169
|
if (this.range < range_coder_1.TOP_VALUE) {
|
|
120
170
|
this.range = (this.range << 8) >>> 0;
|
|
121
|
-
this.
|
|
171
|
+
this.shiftLow();
|
|
122
172
|
}
|
|
123
173
|
}
|
|
124
|
-
/** Encodes a `bits`-bit symbol MSB-first with the bit tree at `offset`. */
|
|
125
174
|
encodeBitTree(probs, offset, bits, symbol) {
|
|
126
|
-
let range = this.range;
|
|
127
|
-
let low = this.low;
|
|
128
175
|
let index = 1;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
else {
|
|
138
|
-
low += bound;
|
|
139
|
-
range -= bound;
|
|
140
|
-
probs[offset + index] = prob - (prob >>> range_coder_1.MOVE_BITS);
|
|
141
|
-
}
|
|
142
|
-
if (range < range_coder_1.TOP_VALUE) {
|
|
143
|
-
range = (range << 8) >>> 0;
|
|
144
|
-
low = this.shiftLow(low);
|
|
176
|
+
let mask = 1 << bits;
|
|
177
|
+
do {
|
|
178
|
+
mask >>>= 1;
|
|
179
|
+
const bit = symbol & mask;
|
|
180
|
+
this.encodeBit(probs, offset + index, bit);
|
|
181
|
+
index <<= 1;
|
|
182
|
+
if (bit !== 0) {
|
|
183
|
+
index |= 1;
|
|
145
184
|
}
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
this.range = range;
|
|
149
|
-
this.low = low;
|
|
185
|
+
} while (mask !== 1);
|
|
150
186
|
}
|
|
151
|
-
/** Encodes a `bits`-bit symbol LSB-first with the bit tree at `offset`. */
|
|
152
187
|
encodeReverseBitTree(probs, offset, bits, symbolIn) {
|
|
153
188
|
let symbol = symbolIn;
|
|
154
|
-
let range = this.range;
|
|
155
|
-
let low = this.low;
|
|
156
189
|
let index = 1;
|
|
157
|
-
|
|
190
|
+
symbol |= 1 << bits;
|
|
191
|
+
do {
|
|
158
192
|
const bit = symbol & 1;
|
|
159
193
|
symbol >>>= 1;
|
|
160
|
-
|
|
161
|
-
const bound = (range >>> range_coder_1.BIT_MODEL_TOTAL_BITS) * prob;
|
|
162
|
-
if (bit === 0) {
|
|
163
|
-
range = bound;
|
|
164
|
-
probs[offset + index] = prob + ((range_coder_1.BIT_MODEL_TOTAL - prob) >>> range_coder_1.MOVE_BITS);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
low += bound;
|
|
168
|
-
range -= bound;
|
|
169
|
-
probs[offset + index] = prob - (prob >>> range_coder_1.MOVE_BITS);
|
|
170
|
-
}
|
|
171
|
-
if (range < range_coder_1.TOP_VALUE) {
|
|
172
|
-
range = (range << 8) >>> 0;
|
|
173
|
-
low = this.shiftLow(low);
|
|
174
|
-
}
|
|
194
|
+
this.encodeBit(probs, offset + index, bit);
|
|
175
195
|
index = (index << 1) | bit;
|
|
176
|
-
}
|
|
177
|
-
this.range = range;
|
|
178
|
-
this.low = low;
|
|
179
|
-
}
|
|
180
|
-
/** Encodes a literal byte with the 0x100-leaf bit tree at `offset`. */
|
|
181
|
-
encodeLiteral(probs, offset, symbol) {
|
|
182
|
-
this.encodeBitTree(probs, offset, 8, symbol);
|
|
196
|
+
} while (symbol !== 1);
|
|
183
197
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Encodes a literal after a match. The bits of `matchByte` (the byte at
|
|
186
|
-
* rep0) select separate probabilities until the first bit that differs.
|
|
187
|
-
*/
|
|
188
|
-
encodeMatchedLiteral(probs, offset, symbolIn, matchByteIn) {
|
|
189
|
-
let symbol = symbolIn;
|
|
190
|
-
let matchByte = matchByteIn;
|
|
191
|
-
let range = this.range;
|
|
192
|
-
let low = this.low;
|
|
193
|
-
let matchOffset = 0x100;
|
|
194
|
-
symbol |= 0x100;
|
|
195
|
-
do {
|
|
196
|
-
matchByte <<= 1;
|
|
197
|
-
const matchBit = matchByte & matchOffset;
|
|
198
|
-
const index = offset + matchOffset + matchBit + (symbol >>> 8);
|
|
199
|
-
const bit = (symbol >>> 7) & 1;
|
|
200
|
-
const prob = probs[index];
|
|
201
|
-
const bound = (range >>> range_coder_1.BIT_MODEL_TOTAL_BITS) * prob;
|
|
202
|
-
if (bit === 0) {
|
|
203
|
-
range = bound;
|
|
204
|
-
probs[index] = prob + ((range_coder_1.BIT_MODEL_TOTAL - prob) >>> range_coder_1.MOVE_BITS);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
low += bound;
|
|
208
|
-
range -= bound;
|
|
209
|
-
probs[index] = prob - (prob >>> range_coder_1.MOVE_BITS);
|
|
210
|
-
}
|
|
211
|
-
if (range < range_coder_1.TOP_VALUE) {
|
|
212
|
-
range = (range << 8) >>> 0;
|
|
213
|
-
low = this.shiftLow(low);
|
|
214
|
-
}
|
|
215
|
-
symbol <<= 1;
|
|
216
|
-
matchOffset &= ~(matchByte ^ symbol);
|
|
217
|
-
} while (symbol < 0x10000);
|
|
218
|
-
this.range = range;
|
|
219
|
-
this.low = low;
|
|
220
|
-
}
|
|
221
|
-
/** Encodes the `count` low bits of `value` with a fixed 50% probability. */
|
|
222
198
|
encodeDirectBits(value, countIn) {
|
|
223
199
|
let count = countIn;
|
|
224
|
-
let range = this.range;
|
|
225
|
-
let low = this.low;
|
|
226
200
|
do {
|
|
227
|
-
range >>>= 1;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
range = (range << 8) >>> 0;
|
|
233
|
-
low = this.shiftLow(low);
|
|
201
|
+
this.range >>>= 1;
|
|
202
|
+
this.low += this.range & (0 - ((value >>> --count) & 1));
|
|
203
|
+
if (this.range < range_coder_1.TOP_VALUE) {
|
|
204
|
+
this.range = (this.range << 8) >>> 0;
|
|
205
|
+
this.shiftLow();
|
|
234
206
|
}
|
|
235
207
|
} while (count !== 0);
|
|
236
|
-
this.range = range;
|
|
237
|
-
this.low = low;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Moves the top byte of `low` to the output and returns the new `low`.
|
|
241
|
-
* A run of 0xFF bytes is held back (`cache` + `cacheSize`) until it is
|
|
242
|
-
* known whether a carry will propagate into it.
|
|
243
|
-
*/
|
|
244
|
-
shiftLow(low) {
|
|
245
|
-
if (low < 0xff000000 || low >= 0x100000000) {
|
|
246
|
-
const carry = low >= 0x100000000 ? 1 : 0;
|
|
247
|
-
this.ensureCapacity(this.cacheSize);
|
|
248
|
-
const buf = this.buf;
|
|
249
|
-
let size = this.size;
|
|
250
|
-
buf[size++] = (this.cache + carry) & 0xff;
|
|
251
|
-
for (let i = 1; i < this.cacheSize; ++i) {
|
|
252
|
-
buf[size++] = (0xff + carry) & 0xff;
|
|
253
|
-
}
|
|
254
|
-
this.size = size;
|
|
255
|
-
this.cacheSize = 0;
|
|
256
|
-
this.cache = (low >>> 24) & 0xff;
|
|
257
|
-
}
|
|
258
|
-
++this.cacheSize;
|
|
259
|
-
return (low & 0x00ffffff) * 256;
|
|
260
208
|
}
|
|
261
209
|
ensureCapacity(extra) {
|
|
262
210
|
if (this.size + extra > this.buf.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patrickdk77/archive-defuse",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Sanitize zip, tar, gzip, bzip2, zstd, Brotli, cab, 7z, xz and lzma archives. Detects path traversal, links out of the tree, device files, duplicate names, overlapping entries, hidden and prepended data, encrypted entries and compression bombs, hands every entry to file plugins, scores the risk, and writes a defused archive in the same format with no runtime dependencies.",
|
|
5
5
|
"license": "MIT AND Apache-2.0",
|
|
6
6
|
"author": "patrickdk77",
|