@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,176 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { LinuxRepoError, limitExceeded, truncated } from '../shared/errors.js';
|
|
3
|
+
import { concatBytes, READ_CHUNK_BYTES, readExact, readUpTo } from './bytes.js';
|
|
4
|
+
const FLAG_HCRC = 0x02;
|
|
5
|
+
const FLAG_EXTRA = 0x04;
|
|
6
|
+
const FLAG_NAME = 0x08;
|
|
7
|
+
const FLAG_COMMENT = 0x10;
|
|
8
|
+
/**
|
|
9
|
+
* Reads exactly one gzip member (RFC 1952) from `inputArg` and leaves the
|
|
10
|
+
* reader positioned at the first byte after it, so concatenated members (an
|
|
11
|
+
* apk v2 package) can be read one at a time with their exact boundaries.
|
|
12
|
+
*
|
|
13
|
+
* The header is parsed here; the deflate data is inflated with
|
|
14
|
+
* `zlib.createInflateRaw()`, whose `bytesWritten` counts only the bytes the
|
|
15
|
+
* deflate stream consumed, and the bytes past the stream's end are pushed back
|
|
16
|
+
* with `unread`. The trailer's CRC-32 and ISIZE are checked. Returns `null`
|
|
17
|
+
* when the input ends exactly where a member would start.
|
|
18
|
+
*/
|
|
19
|
+
export async function readGzipMember(inputArg, optionsArg) {
|
|
20
|
+
const sha1 = plugins.crypto.createHash('sha1');
|
|
21
|
+
let memberBytes = 0;
|
|
22
|
+
const account = (bytesArg) => {
|
|
23
|
+
memberBytes += bytesArg.length;
|
|
24
|
+
if (memberBytes > optionsArg.maxMemberBytes) {
|
|
25
|
+
throw limitExceeded(optionsArg.memberLimit, optionsArg.maxMemberBytes, 'gzip member');
|
|
26
|
+
}
|
|
27
|
+
sha1.update(bytesArg);
|
|
28
|
+
};
|
|
29
|
+
// header
|
|
30
|
+
const fixed = await readUpTo(inputArg, 10);
|
|
31
|
+
if (fixed.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (fixed[0] !== 0x1f || (fixed.length > 1 && fixed[1] !== 0x8b) || (fixed.length > 2 && fixed[2] !== 0x08)) {
|
|
35
|
+
throw new LinuxRepoError('malformed-archive', 'input is not a gzip member', { field: 'gzip header' });
|
|
36
|
+
}
|
|
37
|
+
if (fixed.length < 10) {
|
|
38
|
+
throw truncated('gzip header');
|
|
39
|
+
}
|
|
40
|
+
account(fixed);
|
|
41
|
+
let headerCrc = plugins.zlib.crc32(fixed);
|
|
42
|
+
const flags = fixed[3];
|
|
43
|
+
if ((flags & FLAG_EXTRA) !== 0) {
|
|
44
|
+
const lengthBytes = await readExact(inputArg, 2, 'gzip header');
|
|
45
|
+
account(lengthBytes);
|
|
46
|
+
headerCrc = plugins.zlib.crc32(lengthBytes, headerCrc);
|
|
47
|
+
const extra = await readExact(inputArg, lengthBytes[0] | (lengthBytes[1] << 8), 'gzip header');
|
|
48
|
+
account(extra);
|
|
49
|
+
headerCrc = plugins.zlib.crc32(extra, headerCrc);
|
|
50
|
+
}
|
|
51
|
+
for (const flag of [FLAG_NAME, FLAG_COMMENT]) {
|
|
52
|
+
if ((flags & flag) !== 0) {
|
|
53
|
+
const text = await readZeroTerminated(inputArg, optionsArg.maxHeaderBytes);
|
|
54
|
+
account(text);
|
|
55
|
+
headerCrc = plugins.zlib.crc32(text, headerCrc);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if ((flags & FLAG_HCRC) !== 0) {
|
|
59
|
+
const stored = await readExact(inputArg, 2, 'gzip header');
|
|
60
|
+
account(stored);
|
|
61
|
+
if ((stored[0] | (stored[1] << 8)) !== (headerCrc & 0xffff)) {
|
|
62
|
+
throw new LinuxRepoError('malformed-archive', 'gzip header CRC mismatch', { field: 'gzip header' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// deflate data
|
|
66
|
+
const output = await inflateRawMember(inputArg, optionsArg, account);
|
|
67
|
+
// trailer
|
|
68
|
+
const trailer = await readExact(inputArg, 8, 'gzip trailer');
|
|
69
|
+
account(trailer);
|
|
70
|
+
const view = new DataView(trailer.buffer, trailer.byteOffset, trailer.byteLength);
|
|
71
|
+
if (view.getUint32(0, true) !== output.crc || view.getUint32(4, true) !== output.bytes.length % 0x1_0000_0000) {
|
|
72
|
+
throw new LinuxRepoError('malformed-archive', 'gzip trailer does not match the data', { field: 'gzip trailer' });
|
|
73
|
+
}
|
|
74
|
+
return { output: output.bytes, memberBytes, memberSha1: sha1.digest('hex') };
|
|
75
|
+
}
|
|
76
|
+
async function inflateRawMember(inputArg, optionsArg, accountArg) {
|
|
77
|
+
const inflate = plugins.zlib.createInflateRaw();
|
|
78
|
+
const chunks = [];
|
|
79
|
+
let outputBytes = 0;
|
|
80
|
+
let crc = 0;
|
|
81
|
+
let failure = null;
|
|
82
|
+
let streamError = null;
|
|
83
|
+
inflate.on('data', (chunk) => {
|
|
84
|
+
if (failure !== null) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
outputBytes += chunk.length;
|
|
88
|
+
if (outputBytes > optionsArg.maxOutputBytes) {
|
|
89
|
+
failure = limitExceeded(optionsArg.outputLimit, optionsArg.maxOutputBytes, 'decompressed gzip member');
|
|
90
|
+
inflate.destroy();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
crc = plugins.zlib.crc32(chunk, crc);
|
|
94
|
+
chunks.push(chunk);
|
|
95
|
+
});
|
|
96
|
+
inflate.on('error', (error) => {
|
|
97
|
+
streamError ??= error;
|
|
98
|
+
});
|
|
99
|
+
try {
|
|
100
|
+
for (;;) {
|
|
101
|
+
const chunk = await inputArg.read(READ_CHUNK_BYTES);
|
|
102
|
+
if (chunk === null) {
|
|
103
|
+
throw truncated('gzip member');
|
|
104
|
+
}
|
|
105
|
+
const before = inflate.bytesWritten;
|
|
106
|
+
try {
|
|
107
|
+
await writeChunk(inflate, chunk);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw failure ?? mapInflateError(streamError ?? error);
|
|
111
|
+
}
|
|
112
|
+
if (failure !== null) {
|
|
113
|
+
throw failure;
|
|
114
|
+
}
|
|
115
|
+
const consumed = inflate.bytesWritten - before;
|
|
116
|
+
accountArg(chunk.subarray(0, consumed));
|
|
117
|
+
if (consumed < chunk.length) {
|
|
118
|
+
inputArg.unread(chunk.subarray(consumed));
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!inflate.readableEnded) {
|
|
123
|
+
await new Promise((resolve) => inflate.once('end', resolve));
|
|
124
|
+
}
|
|
125
|
+
if (failure !== null) {
|
|
126
|
+
throw failure;
|
|
127
|
+
}
|
|
128
|
+
return { bytes: concatBytes(chunks, outputBytes), crc };
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
inflate.destroy();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** Writes one chunk and waits until the stream processed it, failing if the stream closes first. */
|
|
135
|
+
function writeChunk(streamArg, chunkArg) {
|
|
136
|
+
return new Promise((resolve, reject) => {
|
|
137
|
+
const onClose = () => reject(new Error('inflate stream closed'));
|
|
138
|
+
streamArg.once('close', onClose);
|
|
139
|
+
streamArg.write(chunkArg, (error) => {
|
|
140
|
+
streamArg.off('close', onClose);
|
|
141
|
+
if (error) {
|
|
142
|
+
reject(error);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
resolve();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function mapInflateError(errorArg) {
|
|
151
|
+
return new LinuxRepoError('malformed-archive', 'gzip member has corrupt deflate data', { field: 'gzip member' }, {
|
|
152
|
+
cause: errorArg,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async function readZeroTerminated(inputArg, maxBytesArg) {
|
|
156
|
+
const parts = [];
|
|
157
|
+
let total = 0;
|
|
158
|
+
for (;;) {
|
|
159
|
+
const chunk = await inputArg.read(READ_CHUNK_BYTES);
|
|
160
|
+
if (chunk === null) {
|
|
161
|
+
throw truncated('gzip header');
|
|
162
|
+
}
|
|
163
|
+
const nul = chunk.indexOf(0);
|
|
164
|
+
const take = nul < 0 ? chunk : chunk.subarray(0, nul + 1);
|
|
165
|
+
total += take.length;
|
|
166
|
+
if (total > maxBytesArg) {
|
|
167
|
+
throw limitExceeded('maxHeaderBytes', maxBytesArg, 'gzip header string');
|
|
168
|
+
}
|
|
169
|
+
parts.push(take);
|
|
170
|
+
if (nul >= 0) {
|
|
171
|
+
inputArg.unread(chunk.subarray(nul + 1));
|
|
172
|
+
return concatBytes(parts, total);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3ppcG1lbWJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3JlYWRlcnMvZ3ppcG1lbWJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUvRSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQW9CLE1BQU0sWUFBWSxDQUFDO0FBRWxHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQUN2QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUM7QUFDeEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQztBQXNCMUI7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUNsQyxRQUFxQixFQUNyQixVQUE4QjtJQUU5QixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQyxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDcEIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxRQUFvQixFQUFFLEVBQUU7UUFDdkMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxXQUFXLEdBQUcsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzVDLE1BQU0sYUFBYSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLGNBQWMsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUN4RixDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUM7SUFFRixTQUFTO0lBQ1QsTUFBTSxLQUFLLEdBQUcsTUFBTSxRQUFRLENBQUMs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
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ILinuxPackageLimits } from '../shared/limits.js';
|
|
2
|
+
import { LimitedReader, type IByteReader } from './bytes.js';
|
|
3
|
+
export interface ITarEntry {
|
|
4
|
+
/**
|
|
5
|
+
* The final name: PAX `path`, else GNU long name, else USTAR prefix + name;
|
|
6
|
+
* a recognised PAX GNU sparse header's `GNU.sparse.name` wins. Bytes are
|
|
7
|
+
* decoded as Gitea's JSON stores a Go string (`decodeGoUtf8`). The name is
|
|
8
|
+
* reported as it stands: no normalisation of `./`, `..` or absolute paths.
|
|
9
|
+
*/
|
|
10
|
+
name: string;
|
|
11
|
+
/** The link target; empty for `'g'`, as Go returns it. */
|
|
12
|
+
linkName: string;
|
|
13
|
+
/**
|
|
14
|
+
* The header's mode field as Go `archive/tar` parses it (octal or base-256;
|
|
15
|
+
* a field Go cannot parse fails the archive, as in Go); 0 for `'g'`, as Go
|
|
16
|
+
* returns it.
|
|
17
|
+
*/
|
|
18
|
+
mode: bigint;
|
|
19
|
+
/**
|
|
20
|
+
* The type flag. Go's legacy `\0` becomes `'0'`, or `'5'` when the name ends
|
|
21
|
+
* with `/`. `'g'` is a PAX global header, returned as an entry as Go does.
|
|
22
|
+
*/
|
|
23
|
+
typeflag: string;
|
|
24
|
+
/**
|
|
25
|
+
* Data bytes readable through `body` (0 for header-only types and `'g'`);
|
|
26
|
+
* for a sparse entry, the real size Go reports, any non-negative int64.
|
|
27
|
+
* Stored data above `Number.MAX_SAFE_INTEGER` bytes is refused.
|
|
28
|
+
*/
|
|
29
|
+
size: bigint;
|
|
30
|
+
/**
|
|
31
|
+
* An old GNU (`'S'`) or PAX GNU 0.0, 0.1 or 1.0 sparse entry whose map Go
|
|
32
|
+
* accepts. The codec does not expand holes: reading its data (through
|
|
33
|
+
* `body` or `readTarEntryData`) is refused with `unsupported-package-format`,
|
|
34
|
+
* a known difference from Gitea; skipping it works.
|
|
35
|
+
*/
|
|
36
|
+
sparse: boolean;
|
|
37
|
+
body: LimitedReader;
|
|
38
|
+
}
|
|
39
|
+
export interface ITarReaderOptions {
|
|
40
|
+
/** Entries returned per archive. */
|
|
41
|
+
maxEntries: number;
|
|
42
|
+
/**
|
|
43
|
+
* One header chain: header blocks, PAX records, GNU long names and old GNU
|
|
44
|
+
* sparse extension blocks. A PAX GNU 1.0 map, which heads the entry's data,
|
|
45
|
+
* is bounded by Go's 1 MiB cap only.
|
|
46
|
+
*/
|
|
47
|
+
maxHeaderBytes: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A bounded ustar reader following Go `archive/tar` (Gitea's reader):
|
|
51
|
+
* USTAR, PAX (`x`, `g`), GNU long names (`L`, `K`), STAR prefixes, Go's
|
|
52
|
+
* pre-1.8 GNU prefix fallback, base-256 numbers and signed or unsigned
|
|
53
|
+
* checksums. A header Go refuses for an unparseable numeric field is refused. The archive ends at two zero
|
|
54
|
+
* blocks, at a clean end of input on a header boundary (apk segments have no
|
|
55
|
+
* end marker), or when the input ends inside the padding after an entry.
|
|
56
|
+
* Sparse maps (old GNU, PAX GNU 0.0, 0.1 and 1.0) are read and validated as
|
|
57
|
+
* Go does; the holes are not expanded, so a sparse entry's data can only be
|
|
58
|
+
* skipped.
|
|
59
|
+
*/
|
|
60
|
+
export declare class TarReader {
|
|
61
|
+
private readonly input;
|
|
62
|
+
private readonly options;
|
|
63
|
+
private done;
|
|
64
|
+
private current;
|
|
65
|
+
private pad;
|
|
66
|
+
private entries;
|
|
67
|
+
constructor(input: IByteReader, options: ITarReaderOptions);
|
|
68
|
+
next(): Promise<ITarEntry | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Go `readOldGNUSparseMap` (reader.go:478-525) and the map check of
|
|
71
|
+
* `handleSparseFile`; returns the real size. The map fills the header's
|
|
72
|
+
* sparse array and extension blocks; Go gives up once its arrays reach
|
|
73
|
+
* 1 MiB (`errSparseTooLong`), whatever `maxHeaderBytes` allows.
|
|
74
|
+
*/
|
|
75
|
+
private readOldGnuSparseMap;
|
|
76
|
+
private countEntry;
|
|
77
|
+
/** Reads the pending padding; false when the input ended inside it (a clean end, as in Go). */
|
|
78
|
+
private consumePadding;
|
|
79
|
+
private finish;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reads a whole entry's data into memory, refusing entries larger than
|
|
83
|
+
* `maxBytesArg` before reading them, and sparse entries at all.
|
|
84
|
+
*/
|
|
85
|
+
export declare function readTarEntryData(entryArg: ITarEntry, maxBytesArg: number, limitArg: keyof ILinuxPackageLimits): Promise<Uint8Array>;
|