@push.rocks/smartlinuxrepo 0.0.0-stage → 0.1.0
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/.smartconfig.json +64 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/alpine/apkindex.d.ts +39 -0
- package/dist_ts/alpine/apkindex.js +211 -0
- package/dist_ts/alpine/pkginfo.d.ts +45 -0
- package/dist_ts/alpine/pkginfo.js +159 -0
- package/dist_ts/alpine/reader.d.ts +20 -0
- package/dist_ts/alpine/reader.js +89 -0
- package/dist_ts/arch/builder.d.ts +41 -0
- package/dist_ts/arch/builder.js +234 -0
- package/dist_ts/arch/reader.d.ts +16 -0
- package/dist_ts/arch/reader.js +271 -0
- package/dist_ts/arch/signer.d.ts +21 -0
- package/dist_ts/arch/signer.js +66 -0
- package/dist_ts/arch/vercmp.d.ts +12 -0
- package/dist_ts/arch/vercmp.js +170 -0
- package/dist_ts/debian/control.d.ts +22 -0
- package/dist_ts/debian/control.js +137 -0
- package/dist_ts/debian/gostring.d.ts +26 -0
- package/dist_ts/debian/gostring.js +145 -0
- package/dist_ts/debian/indexbuilder.d.ts +47 -0
- package/dist_ts/debian/indexbuilder.js +299 -0
- package/dist_ts/debian/mailaddress.d.ts +12 -0
- package/dist_ts/debian/mailaddress.js +736 -0
- package/dist_ts/debian/reader.d.ts +30 -0
- package/dist_ts/debian/reader.js +110 -0
- package/dist_ts/index.d.ts +23 -0
- package/dist_ts/index.js +18 -0
- package/dist_ts/plugins.d.ts +8 -0
- package/dist_ts/plugins.js +11 -0
- package/dist_ts/readers/ar.d.ts +31 -0
- package/dist_ts/readers/ar.js +87 -0
- package/dist_ts/readers/bytes.d.ts +58 -0
- package/dist_ts/readers/bytes.js +147 -0
- package/dist_ts/readers/bytesource.d.ts +40 -0
- package/dist_ts/readers/bytesource.js +154 -0
- package/dist_ts/readers/decompress.d.ts +43 -0
- package/dist_ts/readers/decompress.js +269 -0
- package/dist_ts/readers/gzipmember.d.ts +32 -0
- package/dist_ts/readers/gzipmember.js +176 -0
- package/dist_ts/readers/tar.d.ts +85 -0
- package/dist_ts/readers/tar.js +731 -0
- package/dist_ts/readers/text.d.ts +16 -0
- package/dist_ts/readers/text.js +96 -0
- package/dist_ts/rpm/builder.d.ts +28 -0
- package/dist_ts/rpm/builder.js +208 -0
- package/dist_ts/rpm/header.d.ts +138 -0
- package/dist_ts/rpm/header.js +546 -0
- package/dist_ts/rpm/reader.d.ts +20 -0
- package/dist_ts/rpm/reader.js +306 -0
- package/dist_ts/rpm/repoconfig.d.ts +15 -0
- package/dist_ts/rpm/repoconfig.js +38 -0
- package/dist_ts/rpm/repodata.d.ts +44 -0
- package/dist_ts/rpm/repodata.js +148 -0
- package/dist_ts/rpm/sign.d.ts +30 -0
- package/dist_ts/rpm/sign.js +183 -0
- package/dist_ts/rpm/updates.d.ts +38 -0
- package/dist_ts/rpm/updates.js +265 -0
- package/dist_ts/rpm/xml.d.ts +18 -0
- package/dist_ts/rpm/xml.js +90 -0
- package/dist_ts/shared/architecture.d.ts +8 -0
- package/dist_ts/shared/architecture.js +17 -0
- package/dist_ts/shared/errors.d.ts +38 -0
- package/dist_ts/shared/errors.js +22 -0
- package/dist_ts/shared/gopath.d.ts +13 -0
- package/dist_ts/shared/gopath.js +53 -0
- package/dist_ts/shared/gostrings.d.ts +14 -0
- package/dist_ts/shared/gostrings.js +29 -0
- package/dist_ts/shared/limits.d.ts +47 -0
- package/dist_ts/shared/limits.js +57 -0
- package/dist_ts/shared/types.d.ts +213 -0
- package/dist_ts/shared/types.js +13 -0
- package/dist_ts/shared/url.d.ts +18 -0
- package/dist_ts/shared/url.js +371 -0
- package/dist_ts/shared/validation.d.ts +21 -0
- package/dist_ts/shared/validation.js +58 -0
- package/dist_ts/signing/keys.d.ts +36 -0
- package/dist_ts/signing/keys.js +89 -0
- package/dist_ts/signing/openpgpframing.d.ts +33 -0
- package/dist_ts/signing/openpgpframing.js +93 -0
- package/dist_ts/signing/signers.d.ts +63 -0
- package/dist_ts/signing/signers.js +248 -0
- package/dist_ts/writers/gotar.d.ts +43 -0
- package/dist_ts/writers/gotar.js +218 -0
- package/license.md +19 -0
- package/package.json +56 -3
- package/readme.md +176 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/alpine/apkindex.ts +241 -0
- package/ts/alpine/pkginfo.ts +183 -0
- package/ts/alpine/reader.ts +96 -0
- package/ts/arch/builder.ts +283 -0
- package/ts/arch/reader.ts +307 -0
- package/ts/arch/signer.ts +70 -0
- package/ts/arch/vercmp.ts +188 -0
- package/ts/debian/control.ts +150 -0
- package/ts/debian/gostring.ts +150 -0
- package/ts/debian/indexbuilder.ts +355 -0
- package/ts/debian/mailaddress.ts +754 -0
- package/ts/debian/reader.ts +126 -0
- package/ts/index.ts +46 -0
- package/ts/plugins.ts +13 -0
- package/ts/readers/ar.ts +102 -0
- package/ts/readers/bytes.ts +182 -0
- package/ts/readers/bytesource.ts +164 -0
- package/ts/readers/decompress.ts +332 -0
- package/ts/readers/gzipmember.ts +209 -0
- package/ts/readers/tar.ts +835 -0
- package/ts/readers/text.ts +91 -0
- package/ts/rpm/builder.ts +253 -0
- package/ts/rpm/header.ts +628 -0
- package/ts/rpm/reader.ts +317 -0
- package/ts/rpm/repoconfig.ts +45 -0
- package/ts/rpm/repodata.ts +219 -0
- package/ts/rpm/sign.ts +200 -0
- package/ts/rpm/updates.ts +314 -0
- package/ts/rpm/xml.ts +101 -0
- package/ts/shared/architecture.ts +16 -0
- package/ts/shared/errors.ts +78 -0
- package/ts/shared/gopath.ts +54 -0
- package/ts/shared/gostrings.ts +31 -0
- package/ts/shared/limits.ts +93 -0
- package/ts/shared/types.ts +251 -0
- package/ts/shared/url.ts +387 -0
- package/ts/shared/validation.ts +71 -0
- package/ts/signing/keys.ts +110 -0
- package/ts/signing/openpgpframing.ts +115 -0
- package/ts/signing/signers.ts +315 -0
- package/ts/writers/gotar.ts +256 -0
- package/README.md +0 -3
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
import { LinuxRepoError, limitExceeded, truncated } from '../shared/errors.js';
|
|
2
|
+
import { concatBytes, LimitedReader, readExact, readUpTo } from './bytes.js';
|
|
3
|
+
import { decodeGoUtf8, decodeLatin1 } from './text.js';
|
|
4
|
+
const BLOCK = 512;
|
|
5
|
+
/** Type flags whose header size never has data (Go `isHeaderOnlyType`). */
|
|
6
|
+
const HEADER_ONLY_TYPES = new Set(['1', '2', '3', '4', '5', '6']);
|
|
7
|
+
const MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);
|
|
8
|
+
const INT64_MIN = -(1n << 63n);
|
|
9
|
+
const INT64_MAX = (1n << 63n) - 1n;
|
|
10
|
+
/**
|
|
11
|
+
* Go `maxSpecialFileSize` (format.go:147-149): the most Go reads of one PAX
|
|
12
|
+
* header, GNU long name or long link, old GNU sparse map or PAX GNU 1.0
|
|
13
|
+
* sparse map, whatever `maxHeaderBytes` allows.
|
|
14
|
+
*/
|
|
15
|
+
const MAX_SPECIAL_FILE_SIZE = 1 << 20;
|
|
16
|
+
/**
|
|
17
|
+
* A bounded ustar reader following Go `archive/tar` (Gitea's reader):
|
|
18
|
+
* USTAR, PAX (`x`, `g`), GNU long names (`L`, `K`), STAR prefixes, Go's
|
|
19
|
+
* pre-1.8 GNU prefix fallback, base-256 numbers and signed or unsigned
|
|
20
|
+
* checksums. A header Go refuses for an unparseable numeric field is refused. The archive ends at two zero
|
|
21
|
+
* blocks, at a clean end of input on a header boundary (apk segments have no
|
|
22
|
+
* end marker), or when the input ends inside the padding after an entry.
|
|
23
|
+
* Sparse maps (old GNU, PAX GNU 0.0, 0.1 and 1.0) are read and validated as
|
|
24
|
+
* Go does; the holes are not expanded, so a sparse entry's data can only be
|
|
25
|
+
* skipped.
|
|
26
|
+
*/
|
|
27
|
+
export class TarReader {
|
|
28
|
+
input;
|
|
29
|
+
options;
|
|
30
|
+
done = false;
|
|
31
|
+
current = null;
|
|
32
|
+
pad = 0;
|
|
33
|
+
entries = 0;
|
|
34
|
+
constructor(input, options) {
|
|
35
|
+
this.input = input;
|
|
36
|
+
this.options = options;
|
|
37
|
+
}
|
|
38
|
+
async next() {
|
|
39
|
+
if (this.done) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (this.current !== null) {
|
|
43
|
+
await this.current.skipRest();
|
|
44
|
+
this.current = null;
|
|
45
|
+
}
|
|
46
|
+
if (!(await this.consumePadding())) {
|
|
47
|
+
return this.finish();
|
|
48
|
+
}
|
|
49
|
+
let chainBytes = 0;
|
|
50
|
+
let paxRecords = null;
|
|
51
|
+
let gnuLongName = null;
|
|
52
|
+
let gnuLongLink = null;
|
|
53
|
+
const addChain = (bytesArg) => {
|
|
54
|
+
chainBytes += bytesArg;
|
|
55
|
+
if (chainBytes > this.options.maxHeaderBytes) {
|
|
56
|
+
throw limitExceeded('maxHeaderBytes', this.options.maxHeaderBytes, 'tar header chain');
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
for (;;) {
|
|
60
|
+
const block = await readUpTo(this.input, BLOCK);
|
|
61
|
+
if (block.length === 0) {
|
|
62
|
+
return this.finish();
|
|
63
|
+
}
|
|
64
|
+
if (block.length < BLOCK) {
|
|
65
|
+
throw truncated('tar header');
|
|
66
|
+
}
|
|
67
|
+
if (isZeroBlock(block)) {
|
|
68
|
+
const second = await readUpTo(this.input, BLOCK);
|
|
69
|
+
if (second.length === 0) {
|
|
70
|
+
return this.finish();
|
|
71
|
+
}
|
|
72
|
+
if (second.length < BLOCK) {
|
|
73
|
+
throw truncated('tar end-of-archive marker');
|
|
74
|
+
}
|
|
75
|
+
if (isZeroBlock(second)) {
|
|
76
|
+
return this.finish();
|
|
77
|
+
}
|
|
78
|
+
throw malformed('a zero block is followed by a non-zero block');
|
|
79
|
+
}
|
|
80
|
+
addChain(BLOCK);
|
|
81
|
+
const header = parseHeaderBlock(block);
|
|
82
|
+
if (header.typeflag === 'x' || header.typeflag === 'g') {
|
|
83
|
+
const size = specialFileSize(header, 'PAX header');
|
|
84
|
+
addChain(size);
|
|
85
|
+
const data = await readExact(this.input, size, 'tar PAX header');
|
|
86
|
+
this.pad = padding(size);
|
|
87
|
+
const records = parsePax(data);
|
|
88
|
+
if (header.typeflag === 'g') {
|
|
89
|
+
this.countEntry();
|
|
90
|
+
this.current = new LimitedReader(this.input, 0, 'tar entry data');
|
|
91
|
+
// Go returns a global header's name, type flag and records only, and
|
|
92
|
+
// ignores mergePAX's error for it (reader.go:107-116); after a failing
|
|
93
|
+
// record Go's name depends on map order, the codec takes `path`
|
|
94
|
+
const name = records.get('path') || header.name;
|
|
95
|
+
return { name, linkName: '', mode: 0n, typeflag: 'g', size: 0n, sparse: false, body: this.current };
|
|
96
|
+
}
|
|
97
|
+
paxRecords = records;
|
|
98
|
+
if (!(await this.consumePadding())) {
|
|
99
|
+
return this.finish();
|
|
100
|
+
}
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (header.typeflag === 'L' || header.typeflag === 'K') {
|
|
104
|
+
const size = specialFileSize(header, 'GNU long name or link');
|
|
105
|
+
addChain(size);
|
|
106
|
+
const data = await readExact(this.input, size, 'tar GNU long name');
|
|
107
|
+
this.pad = padding(size);
|
|
108
|
+
const value = decodeGoUtf8(cutAtNul(data));
|
|
109
|
+
if (header.typeflag === 'L') {
|
|
110
|
+
gnuLongName = value;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
gnuLongLink = value;
|
|
114
|
+
}
|
|
115
|
+
if (!(await this.consumePadding())) {
|
|
116
|
+
return this.finish();
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// a real entry: Go mergePAX (reader.go:261-305), then the GNU long names
|
|
121
|
+
let name = header.name;
|
|
122
|
+
let linkName = header.linkName;
|
|
123
|
+
let size = header.size;
|
|
124
|
+
if (paxRecords !== null) {
|
|
125
|
+
checkPaxNumbers(paxRecords);
|
|
126
|
+
const path = paxRecords.get('path');
|
|
127
|
+
if (path) {
|
|
128
|
+
name = path;
|
|
129
|
+
}
|
|
130
|
+
const linkPath = paxRecords.get('linkpath');
|
|
131
|
+
if (linkPath) {
|
|
132
|
+
linkName = linkPath;
|
|
133
|
+
}
|
|
134
|
+
const paxSize = paxRecords.get('size');
|
|
135
|
+
if (paxSize) {
|
|
136
|
+
size = parsePaxInt(paxSize, 'size');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (gnuLongName !== null && gnuLongName !== '') {
|
|
140
|
+
name = gnuLongName;
|
|
141
|
+
}
|
|
142
|
+
if (gnuLongLink !== null && gnuLongLink !== '') {
|
|
143
|
+
linkName = gnuLongLink;
|
|
144
|
+
}
|
|
145
|
+
let typeflag = header.typeflag;
|
|
146
|
+
if (typeflag === '\0') {
|
|
147
|
+
typeflag = name.endsWith('/') ? '5' : '0';
|
|
148
|
+
}
|
|
149
|
+
const dataSize = HEADER_ONLY_TYPES.has(typeflag) ? 0n : size;
|
|
150
|
+
if (dataSize < 0n) {
|
|
151
|
+
throw malformed('negative entry size');
|
|
152
|
+
}
|
|
153
|
+
if (dataSize > MAX_SAFE) {
|
|
154
|
+
throw malformed('entry size is out of range');
|
|
155
|
+
}
|
|
156
|
+
const length = Number(dataSize);
|
|
157
|
+
let body = new LimitedReader(this.input, length, 'tar entry data');
|
|
158
|
+
// Go handleSparseFile (reader.go:195-214): the reported size becomes the real size
|
|
159
|
+
let reportedSize = dataSize;
|
|
160
|
+
let sparse = false;
|
|
161
|
+
if (typeflag === 'S') {
|
|
162
|
+
reportedSize = await this.readOldGnuSparseMap(block, header.format, addChain);
|
|
163
|
+
sparse = true;
|
|
164
|
+
}
|
|
165
|
+
else if (paxRecords !== null) {
|
|
166
|
+
const version = gnuSparseVersion(paxRecords);
|
|
167
|
+
if (version !== null) {
|
|
168
|
+
// Go readGNUSparsePAXHeaders (reader.go:220-259)
|
|
169
|
+
const sparseName = paxRecords.get('GNU.sparse.name') ?? '';
|
|
170
|
+
if (sparseName !== '') {
|
|
171
|
+
name = sparseName;
|
|
172
|
+
}
|
|
173
|
+
const realSizeText = paxRecords.get('GNU.sparse.size') || paxRecords.get('GNU.sparse.realsize') || '';
|
|
174
|
+
const realSize = realSizeText === '' ? size : parsePaxInt(realSizeText, 'GNU sparse size');
|
|
175
|
+
const check = new SparseMapCheck(realSize);
|
|
176
|
+
if (version === '1.0') {
|
|
177
|
+
await checkGnuSparseMap1x0(body, check);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
checkGnuSparseMap0x1(paxRecords, check);
|
|
181
|
+
}
|
|
182
|
+
if (HEADER_ONLY_TYPES.has(typeflag) || !check.valid) {
|
|
183
|
+
throw malformed('invalid sparse map');
|
|
184
|
+
}
|
|
185
|
+
reportedSize = realSize;
|
|
186
|
+
sparse = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
this.countEntry();
|
|
190
|
+
if (sparse) {
|
|
191
|
+
body = new SparseEntryBody(this.input, body.unreadBytes, name);
|
|
192
|
+
}
|
|
193
|
+
this.current = body;
|
|
194
|
+
this.pad = padding(length);
|
|
195
|
+
return { name, linkName, mode: header.mode, typeflag, size: reportedSize, sparse, body };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Go `readOldGNUSparseMap` (reader.go:478-525) and the map check of
|
|
200
|
+
* `handleSparseFile`; returns the real size. The map fills the header's
|
|
201
|
+
* sparse array and extension blocks; Go gives up once its arrays reach
|
|
202
|
+
* 1 MiB (`errSparseTooLong`), whatever `maxHeaderBytes` allows.
|
|
203
|
+
*/
|
|
204
|
+
async readOldGnuSparseMap(blockArg, formatArg, addChainArg) {
|
|
205
|
+
if (formatArg !== 'gnu') {
|
|
206
|
+
throw malformed('old GNU sparse entry outside the GNU format');
|
|
207
|
+
}
|
|
208
|
+
const realSize = parseNumeric(blockArg.subarray(483, 495), 'GNU sparse real size');
|
|
209
|
+
const check = new SparseMapCheck(realSize);
|
|
210
|
+
let array = blockArg.subarray(386, 483); // format.go:276
|
|
211
|
+
let totalSize = array.length;
|
|
212
|
+
while (totalSize < MAX_SPECIAL_FILE_SIZE) {
|
|
213
|
+
if (!checkOldGnuSparseArray(array, check)) {
|
|
214
|
+
if (!check.valid) {
|
|
215
|
+
throw malformed('invalid sparse map');
|
|
216
|
+
}
|
|
217
|
+
return realSize;
|
|
218
|
+
}
|
|
219
|
+
addChainArg(BLOCK);
|
|
220
|
+
array = await readExact(this.input, BLOCK, 'tar sparse header'); // a whole block (format.go:173)
|
|
221
|
+
totalSize += array.length;
|
|
222
|
+
}
|
|
223
|
+
throw malformed('the old GNU sparse map is longer than 1 MiB');
|
|
224
|
+
}
|
|
225
|
+
countEntry() {
|
|
226
|
+
this.entries += 1;
|
|
227
|
+
if (this.entries > this.options.maxEntries) {
|
|
228
|
+
throw limitExceeded('maxEntries', this.options.maxEntries, 'tar entry count');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** Reads the pending padding; false when the input ended inside it (a clean end, as in Go). */
|
|
232
|
+
async consumePadding() {
|
|
233
|
+
if (this.pad === 0) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
const expected = this.pad;
|
|
237
|
+
this.pad = 0;
|
|
238
|
+
const bytes = await readUpTo(this.input, expected);
|
|
239
|
+
return bytes.length === expected;
|
|
240
|
+
}
|
|
241
|
+
finish() {
|
|
242
|
+
this.done = true;
|
|
243
|
+
this.current = null;
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The stored fragments of a sparse entry. The codec does not expand holes,
|
|
249
|
+
* so reading is refused; `skipRest`, and so `TarReader.next`, skips them.
|
|
250
|
+
*/
|
|
251
|
+
class SparseEntryBody extends LimitedReader {
|
|
252
|
+
entryName;
|
|
253
|
+
constructor(innerArg, lengthArg, entryName) {
|
|
254
|
+
super(innerArg, lengthArg, 'tar entry data');
|
|
255
|
+
this.entryName = entryName;
|
|
256
|
+
}
|
|
257
|
+
async read() {
|
|
258
|
+
throw sparseDataRefused(this.entryName);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Reads a whole entry's data into memory, refusing entries larger than
|
|
263
|
+
* `maxBytesArg` before reading them, and sparse entries at all.
|
|
264
|
+
*/
|
|
265
|
+
export async function readTarEntryData(entryArg, maxBytesArg, limitArg) {
|
|
266
|
+
if (entryArg.sparse) {
|
|
267
|
+
throw sparseDataRefused(entryArg.name);
|
|
268
|
+
}
|
|
269
|
+
if (entryArg.size > BigInt(maxBytesArg)) {
|
|
270
|
+
throw limitExceeded(limitArg, maxBytesArg, `tar entry ${entryArg.name}`);
|
|
271
|
+
}
|
|
272
|
+
return readExact(entryArg.body, Number(entryArg.size), 'tar entry data');
|
|
273
|
+
}
|
|
274
|
+
/** Go `block.getFormat`'s magic detection (format.go:187-200); the checksum is checked first. */
|
|
275
|
+
function headerFormat(blockArg) {
|
|
276
|
+
const magic = decodeLatin1(blockArg.subarray(257, 263));
|
|
277
|
+
const version = decodeLatin1(blockArg.subarray(263, 265));
|
|
278
|
+
const trailer = decodeLatin1(blockArg.subarray(508, 512));
|
|
279
|
+
if (magic === 'ustar\0' && trailer === 'tar\0') {
|
|
280
|
+
return 'star';
|
|
281
|
+
}
|
|
282
|
+
if (magic === 'ustar\0') {
|
|
283
|
+
return 'ustar'; // USTAR or PAX
|
|
284
|
+
}
|
|
285
|
+
if (magic === 'ustar ' && version === ' \0') {
|
|
286
|
+
return 'gnu';
|
|
287
|
+
}
|
|
288
|
+
return 'v7';
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Go `Reader.readHeader` (reader.go:356-468): every numeric field Go parses
|
|
292
|
+
* with its fatal parser fails the archive here too, although only size and
|
|
293
|
+
* mode are kept.
|
|
294
|
+
*/
|
|
295
|
+
function parseHeaderBlock(blockArg) {
|
|
296
|
+
verifyChecksum(blockArg);
|
|
297
|
+
const format = headerFormat(blockArg);
|
|
298
|
+
// reader.go:385-389, all formats
|
|
299
|
+
const size = parseNumeric(blockArg.subarray(124, 136), 'size');
|
|
300
|
+
const mode = parseNumeric(blockArg.subarray(100, 108), 'mode');
|
|
301
|
+
parseNumeric(blockArg.subarray(108, 116), 'uid');
|
|
302
|
+
parseNumeric(blockArg.subarray(116, 124), 'gid');
|
|
303
|
+
parseNumeric(blockArg.subarray(136, 148), 'mtime');
|
|
304
|
+
let prefix = new Uint8Array(0);
|
|
305
|
+
if (format !== 'v7') {
|
|
306
|
+
// reader.go:392-397: above V7 only, so a V7 header may hold anything there
|
|
307
|
+
parseNumeric(blockArg.subarray(329, 337), 'devmajor');
|
|
308
|
+
parseNumeric(blockArg.subarray(337, 345), 'devminor');
|
|
309
|
+
if (format === 'ustar') {
|
|
310
|
+
prefix = cutAtNul(blockArg.subarray(345, 500)); // reader.go:401-404
|
|
311
|
+
}
|
|
312
|
+
else if (format === 'star') {
|
|
313
|
+
// reader.go:417-421
|
|
314
|
+
prefix = cutAtNul(blockArg.subarray(345, 476));
|
|
315
|
+
parseNumeric(blockArg.subarray(476, 488), 'STAR atime');
|
|
316
|
+
parseNumeric(blockArg.subarray(488, 500), 'STAR ctime');
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
prefix = gnuLegacyPrefix(blockArg);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
let name = decodeGoUtf8(cutAtNul(blockArg.subarray(0, 100)));
|
|
323
|
+
if (prefix.length > 0) {
|
|
324
|
+
name = `${decodeGoUtf8(prefix)}/${name}`; // reader.go:463-465
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
name,
|
|
328
|
+
linkName: decodeGoUtf8(cutAtNul(blockArg.subarray(157, 257))),
|
|
329
|
+
mode,
|
|
330
|
+
typeflag: String.fromCharCode(blockArg[156]),
|
|
331
|
+
size,
|
|
332
|
+
format,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* The old GNU format has no prefix field, but Go before 1.8 wrote one over
|
|
337
|
+
* atime and ctime. Go parses each of the two only when its first byte is not
|
|
338
|
+
* NUL, with a parser whose failure is not fatal; when either fails it takes
|
|
339
|
+
* bytes [345, 500) up to the first NUL as the prefix if they are ASCII
|
|
340
|
+
* (reader.go:422-461, `isASCII` strconv.go:21-28).
|
|
341
|
+
*/
|
|
342
|
+
function gnuLegacyPrefix(blockArg) {
|
|
343
|
+
const parses = (fieldArg) => fieldArg[0] === 0 || goNumeric(fieldArg) !== null;
|
|
344
|
+
if (parses(blockArg.subarray(345, 357)) && parses(blockArg.subarray(357, 369))) {
|
|
345
|
+
return new Uint8Array(0);
|
|
346
|
+
}
|
|
347
|
+
const prefix = cutAtNul(blockArg.subarray(345, 500));
|
|
348
|
+
return prefix.every((byteArg) => byteArg < 0x80) ? prefix : new Uint8Array(0);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Reads one old GNU sparse array (Go `sparseArray`, format.go:304-313):
|
|
352
|
+
* 24-byte entries, each a 12-byte offset and length, then the isExtended
|
|
353
|
+
* byte. As in Go `readOldGNUSparseMap` (reader.go:496-511), the entries up to
|
|
354
|
+
* the first whose offset starts with NUL must parse and go into the map
|
|
355
|
+
* check. Returns isExtended.
|
|
356
|
+
*/
|
|
357
|
+
function checkOldGnuSparseArray(arrayArg, checkArg) {
|
|
358
|
+
const entries = Math.floor(arrayArg.length / 24);
|
|
359
|
+
for (let i = 0; i < entries; i++) {
|
|
360
|
+
const entry = arrayArg.subarray(i * 24, i * 24 + 24);
|
|
361
|
+
if (entry[0] === 0) {
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
const offset = parseNumeric(entry.subarray(0, 12), 'GNU sparse offset');
|
|
365
|
+
const length = parseNumeric(entry.subarray(12, 24), 'GNU sparse length');
|
|
366
|
+
checkArg.add(offset, length);
|
|
367
|
+
}
|
|
368
|
+
return arrayArg[entries * 24] !== 0;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Go `validateSparseEntries` (common.go:255-278), fed one map entry at a
|
|
372
|
+
* time: no negative offset or length, no int64 overflow, no fragment past the
|
|
373
|
+
* real size, fragments in order without overlap; a negative real size fails
|
|
374
|
+
* even an empty map. Go checks the map once it has parsed all of it
|
|
375
|
+
* (reader.go:206-209), so callers read `valid` after the last entry. Go's
|
|
376
|
+
* `maxSparseFileEntries` (reader.go:643-648) is not ported: the 1 MiB caps
|
|
377
|
+
* keep every map below it.
|
|
378
|
+
*/
|
|
379
|
+
class SparseMapCheck {
|
|
380
|
+
size;
|
|
381
|
+
previousEnd = 0n;
|
|
382
|
+
ok;
|
|
383
|
+
constructor(size) {
|
|
384
|
+
this.size = size;
|
|
385
|
+
this.ok = size >= 0n;
|
|
386
|
+
}
|
|
387
|
+
get valid() {
|
|
388
|
+
return this.ok;
|
|
389
|
+
}
|
|
390
|
+
add(offsetArg, lengthArg) {
|
|
391
|
+
if (!this.ok) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const end = offsetArg + lengthArg;
|
|
395
|
+
if (offsetArg < 0n || lengthArg < 0n || end > INT64_MAX || end > this.size || this.previousEnd > offsetArg) {
|
|
396
|
+
this.ok = false;
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
this.previousEnd = end;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Go `readGNUSparsePAXHeaders`' version detection (reader.go:221-235): 0.0
|
|
404
|
+
* and 0.1 keep their map in PAX records, 1.0 at the start of the data; null
|
|
405
|
+
* when the records describe no PAX GNU sparse file.
|
|
406
|
+
*/
|
|
407
|
+
function gnuSparseVersion(recordsArg) {
|
|
408
|
+
const major = recordsArg.get('GNU.sparse.major') ?? '';
|
|
409
|
+
const minor = recordsArg.get('GNU.sparse.minor') ?? '';
|
|
410
|
+
if (major === '0' && (minor === '0' || minor === '1')) {
|
|
411
|
+
return '0.x';
|
|
412
|
+
}
|
|
413
|
+
if (major === '1' && minor === '0') {
|
|
414
|
+
return '1.0';
|
|
415
|
+
}
|
|
416
|
+
if (major !== '' || minor !== '') {
|
|
417
|
+
return null; // an unknown version
|
|
418
|
+
}
|
|
419
|
+
return (recordsArg.get('GNU.sparse.map') ?? '') !== '' ? '0.x' : null;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Go `readGNUSparseMap0x1` (reader.go:607-641): `GNU.sparse.numblocks`
|
|
423
|
+
* entries in `GNU.sparse.map` as comma-separated offset and length pairs
|
|
424
|
+
* (0.0 records arrive here already joined by `parsePax`).
|
|
425
|
+
*/
|
|
426
|
+
function checkGnuSparseMap0x1(recordsArg, checkArg) {
|
|
427
|
+
const count = sparseEntryCount(recordsArg.get('GNU.sparse.numblocks') ?? '');
|
|
428
|
+
const map = recordsArg.get('GNU.sparse.map') ?? '';
|
|
429
|
+
const fields = map === '' ? [] : map.split(',');
|
|
430
|
+
if (BigInt(fields.length) !== 2n * count) {
|
|
431
|
+
throw malformed('the sparse map does not hold GNU.sparse.numblocks entries');
|
|
432
|
+
}
|
|
433
|
+
for (let i = 0; i < fields.length; i += 2) {
|
|
434
|
+
const offset = goParseInt(fields[i]);
|
|
435
|
+
const length = goParseInt(fields[i + 1]);
|
|
436
|
+
if (offset === null || length === null) {
|
|
437
|
+
throw malformed('a sparse map entry is not a decimal integer');
|
|
438
|
+
}
|
|
439
|
+
checkArg.add(offset, length);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Go `readGNUSparseMap1x0` (reader.go:537-603): the map heads the entry's
|
|
444
|
+
* data as newline-terminated decimals, the entry count and then offset and
|
|
445
|
+
* length pairs. Go reads whole blocks until it holds the newlines it needs,
|
|
446
|
+
* at most 1 MiB of them (`errSparseTooLong`); the data after the last of
|
|
447
|
+
* those blocks is the stored fragments.
|
|
448
|
+
*/
|
|
449
|
+
async function checkGnuSparseMap1x0(dataArg, checkArg) {
|
|
450
|
+
let buffer = new Uint8Array(0);
|
|
451
|
+
let cursor = 0;
|
|
452
|
+
let newlines = 0;
|
|
453
|
+
let totalSize = 0;
|
|
454
|
+
const feedTokens = async (countArg) => {
|
|
455
|
+
const chunks = [buffer.subarray(cursor)];
|
|
456
|
+
while (BigInt(newlines) < countArg) {
|
|
457
|
+
totalSize += BLOCK;
|
|
458
|
+
if (totalSize > MAX_SPECIAL_FILE_SIZE) {
|
|
459
|
+
throw malformed('the PAX GNU sparse map is longer than 1 MiB');
|
|
460
|
+
}
|
|
461
|
+
const block = await readUpTo(dataArg, BLOCK);
|
|
462
|
+
if (block.length < BLOCK) {
|
|
463
|
+
throw malformed('the PAX GNU sparse map runs past the entry data');
|
|
464
|
+
}
|
|
465
|
+
chunks.push(block);
|
|
466
|
+
for (const byte of block) {
|
|
467
|
+
if (byte === 0x0a) {
|
|
468
|
+
newlines++;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
buffer = concatBytes(chunks);
|
|
473
|
+
cursor = 0;
|
|
474
|
+
};
|
|
475
|
+
const nextToken = () => {
|
|
476
|
+
newlines--;
|
|
477
|
+
const end = buffer.indexOf(0x0a, cursor);
|
|
478
|
+
const token = decodeLatin1(buffer.subarray(cursor, end));
|
|
479
|
+
cursor = end + 1;
|
|
480
|
+
return token;
|
|
481
|
+
};
|
|
482
|
+
await feedTokens(1n);
|
|
483
|
+
const count = sparseEntryCount(nextToken());
|
|
484
|
+
await feedTokens(2n * count);
|
|
485
|
+
for (let i = 0n; i < count; i++) {
|
|
486
|
+
const offset = goParseInt(nextToken());
|
|
487
|
+
const length = goParseInt(nextToken());
|
|
488
|
+
if (offset === null || length === null) {
|
|
489
|
+
throw malformed('a sparse map entry is not a decimal integer');
|
|
490
|
+
}
|
|
491
|
+
checkArg.add(offset, length);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/** A sparse map's entry count as Go checks it (reader.go:579-582, :611-614). */
|
|
495
|
+
function sparseEntryCount(textArg) {
|
|
496
|
+
const count = goParseInt(textArg);
|
|
497
|
+
if (count === null || count < 0n || 2n * count > INT64_MAX) {
|
|
498
|
+
throw malformed('invalid sparse map entry count');
|
|
499
|
+
}
|
|
500
|
+
return count;
|
|
501
|
+
}
|
|
502
|
+
function verifyChecksum(blockArg) {
|
|
503
|
+
const stored = goOctal(blockArg.subarray(148, 156));
|
|
504
|
+
if (stored === null) {
|
|
505
|
+
throw malformed('checksum field is not octal');
|
|
506
|
+
}
|
|
507
|
+
let unsigned = 0;
|
|
508
|
+
let signed = 0;
|
|
509
|
+
for (let i = 0; i < BLOCK; i++) {
|
|
510
|
+
const byte = i >= 148 && i < 156 ? 0x20 : blockArg[i];
|
|
511
|
+
unsigned += byte;
|
|
512
|
+
signed += byte >= 0x80 ? byte - 0x100 : byte;
|
|
513
|
+
}
|
|
514
|
+
if (stored !== BigInt(unsigned) && stored !== BigInt(signed)) {
|
|
515
|
+
throw malformed('header checksum mismatch');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
/** Go `parser.parseNumeric` (strconv.go:96-135), failing the archive where Go sets its error. */
|
|
519
|
+
function parseNumeric(fieldArg, whatArg) {
|
|
520
|
+
const value = goNumeric(fieldArg);
|
|
521
|
+
if (value === null) {
|
|
522
|
+
throw malformed(`${whatArg} field is not a valid tar number`);
|
|
523
|
+
}
|
|
524
|
+
return value;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Go `parser.parseNumeric` (strconv.go:96-135): base-256 when the high bit is
|
|
528
|
+
* set, else octal; null where Go sets the parser's error.
|
|
529
|
+
*/
|
|
530
|
+
function goNumeric(fieldArg) {
|
|
531
|
+
if (fieldArg.length > 0 && (fieldArg[0] & 0x80) !== 0) {
|
|
532
|
+
const inverse = (fieldArg[0] & 0x40) !== 0 ? 0xff : 0x00;
|
|
533
|
+
let value = 0n;
|
|
534
|
+
for (let i = 0; i < fieldArg.length; i++) {
|
|
535
|
+
let byte = fieldArg[i] ^ inverse;
|
|
536
|
+
if (i === 0) {
|
|
537
|
+
byte &= 0x7f;
|
|
538
|
+
}
|
|
539
|
+
if (value >> 56n > 0n) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
value = (value << 8n) | BigInt(byte);
|
|
543
|
+
}
|
|
544
|
+
if (value >> 63n > 0n) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
return inverse === 0xff ? -value - 1n : value;
|
|
548
|
+
}
|
|
549
|
+
return goOctal(fieldArg);
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Go `parser.parseOctal` (strconv.go:158-174): trims spaces and NULs, cuts at
|
|
553
|
+
* a NUL, parses base 8 into 64 bits; null where Go sets the parser's error.
|
|
554
|
+
*/
|
|
555
|
+
function goOctal(fieldArg) {
|
|
556
|
+
let start = 0;
|
|
557
|
+
let end = fieldArg.length;
|
|
558
|
+
while (start < end && (fieldArg[start] === 0x20 || fieldArg[start] === 0x00)) {
|
|
559
|
+
start++;
|
|
560
|
+
}
|
|
561
|
+
while (end > start && (fieldArg[end - 1] === 0x20 || fieldArg[end - 1] === 0x00)) {
|
|
562
|
+
end--;
|
|
563
|
+
}
|
|
564
|
+
const text = decodeLatin1(cutAtNul(fieldArg.subarray(start, end)));
|
|
565
|
+
if (text.length === 0) {
|
|
566
|
+
return 0n;
|
|
567
|
+
}
|
|
568
|
+
if (!/^[0-7]+$/.test(text)) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
const value = BigInt(`0o${text}`);
|
|
572
|
+
return value >> 64n > 0n ? null : value;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Go `strconv.ParseInt(s, 10, 64)`: an optional sign, decimal digits, int64
|
|
576
|
+
* range; null where Go fails.
|
|
577
|
+
*/
|
|
578
|
+
function goParseInt(textArg) {
|
|
579
|
+
if (!/^[+-]?[0-9]+$/.test(textArg)) {
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
const digits = textArg.replace(/^[+-]/, '').replace(/^0+/, '');
|
|
583
|
+
if (digits.length > 19) {
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
const value = BigInt(textArg);
|
|
587
|
+
return value < INT64_MIN || value > INT64_MAX ? null : value;
|
|
588
|
+
}
|
|
589
|
+
/** A PAX integer record Go parses with `strconv.ParseInt`, failing the header where Go does. */
|
|
590
|
+
function parsePaxInt(textArg, keyArg) {
|
|
591
|
+
const value = goParseInt(textArg);
|
|
592
|
+
if (value === null) {
|
|
593
|
+
throw malformedPax(`${keyArg} is not a decimal integer`);
|
|
594
|
+
}
|
|
595
|
+
return value;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Go `mergePAX` (reader.go:261-305) for the records the codec does not keep:
|
|
599
|
+
* a uid, gid, atime, mtime or ctime Go cannot parse fails the header; an
|
|
600
|
+
* empty value keeps the USTAR field, as in Go.
|
|
601
|
+
*/
|
|
602
|
+
function checkPaxNumbers(recordsArg) {
|
|
603
|
+
for (const key of ['uid', 'gid']) {
|
|
604
|
+
const value = recordsArg.get(key) ?? '';
|
|
605
|
+
if (value !== '') {
|
|
606
|
+
parsePaxInt(value, key);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
for (const key of ['atime', 'mtime', 'ctime']) {
|
|
610
|
+
const value = recordsArg.get(key) ?? '';
|
|
611
|
+
if (value !== '' && !isGoPaxTime(value)) {
|
|
612
|
+
throw malformedPax(`${key} is not a PAX time`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Go `parsePAXTime` (strconv.go:197-231): seconds as `strconv.ParseInt`,
|
|
618
|
+
* then optionally a dot and any number of digits.
|
|
619
|
+
*/
|
|
620
|
+
function isGoPaxTime(textArg) {
|
|
621
|
+
const dot = textArg.indexOf('.');
|
|
622
|
+
const seconds = dot < 0 ? textArg : textArg.slice(0, dot);
|
|
623
|
+
const fraction = dot < 0 ? '' : textArg.slice(dot + 1);
|
|
624
|
+
return goParseInt(seconds) !== null && /^[0-9]*$/.test(fraction);
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Go `parsePAX` / `parsePAXRecord` (reader.go:307-346, strconv.go:251-287):
|
|
628
|
+
* `"<length> <key>=<value>\n"` records; a later `x` header replaces the
|
|
629
|
+
* earlier records. NUL is refused in `path`, `linkpath`, `uname` and `gname`
|
|
630
|
+
* values and in every key. GNU sparse 0.0 offset and size records must
|
|
631
|
+
* alternate, offset first, without commas; Go joins them into
|
|
632
|
+
* `GNU.sparse.map`, replacing a `GNU.sparse.map` record.
|
|
633
|
+
*/
|
|
634
|
+
function parsePax(dataArg) {
|
|
635
|
+
const records = new Map();
|
|
636
|
+
const sparseMap = [];
|
|
637
|
+
let offset = 0;
|
|
638
|
+
while (offset < dataArg.length) {
|
|
639
|
+
const rest = dataArg.subarray(offset);
|
|
640
|
+
const space = rest.indexOf(0x20);
|
|
641
|
+
if (space < 0) {
|
|
642
|
+
throw malformedPax('a record has no length');
|
|
643
|
+
}
|
|
644
|
+
const lengthText = decodeLatin1(rest.subarray(0, space));
|
|
645
|
+
if (!/^[+-]?[0-9]+$/.test(lengthText)) {
|
|
646
|
+
throw malformedPax('a record length is not a decimal integer');
|
|
647
|
+
}
|
|
648
|
+
const length = BigInt(lengthText);
|
|
649
|
+
if (length < 5n || length > BigInt(rest.length)) {
|
|
650
|
+
throw malformedPax('a record length is out of range');
|
|
651
|
+
}
|
|
652
|
+
const recordLength = Number(length);
|
|
653
|
+
if (recordLength <= space + 1) {
|
|
654
|
+
throw malformedPax('a record is shorter than its length field');
|
|
655
|
+
}
|
|
656
|
+
if (rest[recordLength - 1] !== 0x0a) {
|
|
657
|
+
throw malformedPax('a record does not end with a newline');
|
|
658
|
+
}
|
|
659
|
+
const record = rest.subarray(space + 1, recordLength - 1);
|
|
660
|
+
const equals = record.indexOf(0x3d);
|
|
661
|
+
if (equals < 0) {
|
|
662
|
+
throw malformedPax('a record has no "="');
|
|
663
|
+
}
|
|
664
|
+
const keyBytes = record.subarray(0, equals);
|
|
665
|
+
const valueBytes = record.subarray(equals + 1);
|
|
666
|
+
if (keyBytes.length === 0 || keyBytes.includes(0)) {
|
|
667
|
+
throw malformedPax('a record key is empty or contains NUL');
|
|
668
|
+
}
|
|
669
|
+
const key = decodeGoUtf8(keyBytes);
|
|
670
|
+
if (['path', 'linkpath', 'uname', 'gname'].includes(key) && valueBytes.includes(0)) {
|
|
671
|
+
throw malformedPax(`the ${key} value contains NUL`);
|
|
672
|
+
}
|
|
673
|
+
const value = decodeGoUtf8(valueBytes);
|
|
674
|
+
if (key === 'GNU.sparse.offset' || key === 'GNU.sparse.numbytes') {
|
|
675
|
+
const expected = sparseMap.length % 2 === 0 ? 'GNU.sparse.offset' : 'GNU.sparse.numbytes';
|
|
676
|
+
if (key !== expected || value.includes(',')) {
|
|
677
|
+
throw malformedPax('GNU sparse 0.0 records are out of order or hold a comma');
|
|
678
|
+
}
|
|
679
|
+
sparseMap.push(value);
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
records.set(key, value);
|
|
683
|
+
}
|
|
684
|
+
offset += recordLength;
|
|
685
|
+
}
|
|
686
|
+
if (sparseMap.length > 0) {
|
|
687
|
+
records.set('GNU.sparse.map', sparseMap.join(','));
|
|
688
|
+
}
|
|
689
|
+
return records;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* The data size of a PAX header or GNU long name or link. Go reads at most
|
|
693
|
+
* 1 MiB of it (`readSpecialFile`, reader.go:868-876, `ErrFieldTooLong`); the
|
|
694
|
+
* codec refuses a larger one from its declared size, before reading.
|
|
695
|
+
*/
|
|
696
|
+
function specialFileSize(headerArg, whatArg) {
|
|
697
|
+
if (headerArg.size < 0n) {
|
|
698
|
+
throw malformed('negative entry size');
|
|
699
|
+
}
|
|
700
|
+
if (headerArg.size > BigInt(MAX_SPECIAL_FILE_SIZE)) {
|
|
701
|
+
throw malformed(`${whatArg} is longer than 1 MiB`);
|
|
702
|
+
}
|
|
703
|
+
return Number(headerArg.size);
|
|
704
|
+
}
|
|
705
|
+
function padding(sizeArg) {
|
|
706
|
+
return (BLOCK - (sizeArg % BLOCK)) % BLOCK;
|
|
707
|
+
}
|
|
708
|
+
function isZeroBlock(blockArg) {
|
|
709
|
+
for (let i = 0; i < blockArg.length; i++) {
|
|
710
|
+
if (blockArg[i] !== 0) {
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
function cutAtNul(bytesArg) {
|
|
717
|
+
const nul = bytesArg.indexOf(0);
|
|
718
|
+
return nul < 0 ? bytesArg : bytesArg.subarray(0, nul);
|
|
719
|
+
}
|
|
720
|
+
function malformed(messageArg) {
|
|
721
|
+
return new LinuxRepoError('malformed-archive', `tar: ${messageArg}`, { field: 'tar header' });
|
|
722
|
+
}
|
|
723
|
+
/** Reading a sparse entry's data: Go expands its holes, the codec does not (a known difference from Gitea). */
|
|
724
|
+
function sparseDataRefused(nameArg) {
|
|
725
|
+
const message = `tar: the data of sparse entry ${nameArg} is not read (holes are not expanded)`;
|
|
726
|
+
return new LinuxRepoError('unsupported-package-format', message, { field: 'tar entry data' });
|
|
727
|
+
}
|
|
728
|
+
function malformedPax(messageArg) {
|
|
729
|
+
return new LinuxRepoError('malformed-archive', `tar PAX header: ${messageArg}`, { field: 'tar PAX header' });
|
|
730
|
+
}
|
|
731
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcmVhZGVycy90YXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFL0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBb0IsTUFBTSxZQUFZLENBQUM7QUFDL0YsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFdkQsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQ2xCLDJFQUEyRTtBQUMzRSxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUNqRCxNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNuQzs7OztHQUlHO0FBQ0gsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO0FBOER0Qzs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7SUFPRCxLQUFLO0lBQ0wsT0FBTztJQVBsQixJQUFJLEdBQUcsS0FBSyxDQUFDO0lBQ2IsT0FBTyxHQUF5QixJQUFJLENBQUM7SUFDckMsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUNSLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFFcEIsWUFDbUIsS0FBa0IsRUFDbEIsT0FBMEI7cUJBRDFCLEtBQUs7dUJBQ0wsT0FBTztJQUN2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
|