@patrickdk77/archive-defuse 0.0.0-stage → 0.1.1

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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +378 -2
  3. package/dist/aes7z.d.ts +16 -0
  4. package/dist/aes7z.js +131 -0
  5. package/dist/alone.d.ts +21 -0
  6. package/dist/alone.js +65 -0
  7. package/dist/bcj2.d.ts +21 -0
  8. package/dist/bcj2.js +140 -0
  9. package/dist/bzip2.d.ts +21 -0
  10. package/dist/bzip2.js +688 -0
  11. package/dist/cab.d.ts +63 -0
  12. package/dist/cab.js +493 -0
  13. package/dist/checks.d.ts +23 -0
  14. package/dist/checks.js +123 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +364 -0
  17. package/dist/codecs.d.ts +39 -0
  18. package/dist/codecs.js +124 -0
  19. package/dist/coders.d.ts +58 -0
  20. package/dist/coders.js +392 -0
  21. package/dist/crc32.d.ts +8 -0
  22. package/dist/crc32.js +59 -0
  23. package/dist/detect.d.ts +10 -0
  24. package/dist/detect.js +95 -0
  25. package/dist/encoder.d.ts +44 -0
  26. package/dist/encoder.js +114 -0
  27. package/dist/engine.d.ts +44 -0
  28. package/dist/engine.js +753 -0
  29. package/dist/errors.d.ts +64 -0
  30. package/dist/errors.js +98 -0
  31. package/dist/filters.d.ts +34 -0
  32. package/dist/filters.js +385 -0
  33. package/dist/findings.d.ts +26 -0
  34. package/dist/findings.js +176 -0
  35. package/dist/formats.d.ts +24 -0
  36. package/dist/formats.js +106 -0
  37. package/dist/index.d.ts +9 -0
  38. package/dist/index.js +53 -0
  39. package/dist/index.mjs +3 -0
  40. package/dist/inflate64.d.ts +6 -0
  41. package/dist/inflate64.js +388 -0
  42. package/dist/io.d.ts +78 -0
  43. package/dist/io.js +379 -0
  44. package/dist/lzma-formats.d.ts +75 -0
  45. package/dist/lzma-formats.js +373 -0
  46. package/dist/lzma-sniff.d.ts +20 -0
  47. package/dist/lzma-sniff.js +73 -0
  48. package/dist/lzma-writers.d.ts +35 -0
  49. package/dist/lzma-writers.js +276 -0
  50. package/dist/lzma1/LICENSE +201 -0
  51. package/dist/lzma1/NOTICE +36 -0
  52. package/dist/lzma1/crc32.d.ts +4 -0
  53. package/dist/lzma1/crc32.js +19 -0
  54. package/dist/lzma1/hash234.d.ts +22 -0
  55. package/dist/lzma1/hash234.js +75 -0
  56. package/dist/lzma1/hc4.d.ts +30 -0
  57. package/dist/lzma1/hc4.js +142 -0
  58. package/dist/lzma1/header.d.ts +32 -0
  59. package/dist/lzma1/header.js +73 -0
  60. package/dist/lzma1/lz-decoder.d.ts +41 -0
  61. package/dist/lzma1/lz-decoder.js +128 -0
  62. package/dist/lzma1/lz-encoder.d.ts +87 -0
  63. package/dist/lzma1/lz-encoder.js +166 -0
  64. package/dist/lzma1/lzma-coder.d.ts +107 -0
  65. package/dist/lzma1/lzma-coder.js +162 -0
  66. package/dist/lzma1/lzma-decoder.d.ts +36 -0
  67. package/dist/lzma1/lzma-decoder.js +484 -0
  68. package/dist/lzma1/lzma-encoder-fast.d.ts +13 -0
  69. package/dist/lzma1/lzma-encoder-fast.js +114 -0
  70. package/dist/lzma1/lzma-encoder.d.ts +105 -0
  71. package/dist/lzma1/lzma-encoder.js +497 -0
  72. package/dist/lzma1/lzma2-decoder.d.ts +85 -0
  73. package/dist/lzma1/lzma2-decoder.js +249 -0
  74. package/dist/lzma1/range-coder.d.ts +18 -0
  75. package/dist/lzma1/range-coder.js +23 -0
  76. package/dist/lzma1/range-decoder.d.ts +41 -0
  77. package/dist/lzma1/range-decoder.js +78 -0
  78. package/dist/lzma1/range-encoder.d.ts +53 -0
  79. package/dist/lzma1/range-encoder.js +269 -0
  80. package/dist/lzma1-stream.d.ts +60 -0
  81. package/dist/lzma1-stream.js +202 -0
  82. package/dist/model.d.ts +141 -0
  83. package/dist/model.js +16 -0
  84. package/dist/names.d.ts +13 -0
  85. package/dist/names.js +66 -0
  86. package/dist/pack.d.ts +79 -0
  87. package/dist/pack.js +590 -0
  88. package/dist/plugins.d.ts +13 -0
  89. package/dist/plugins.js +56 -0
  90. package/dist/rules.d.ts +25 -0
  91. package/dist/rules.js +403 -0
  92. package/dist/score.d.ts +17 -0
  93. package/dist/score.js +58 -0
  94. package/dist/seven.d.ts +75 -0
  95. package/dist/seven.js +492 -0
  96. package/dist/sevenzip.d.ts +133 -0
  97. package/dist/sevenzip.js +529 -0
  98. package/dist/single.d.ts +103 -0
  99. package/dist/single.js +453 -0
  100. package/dist/sniff.d.ts +20 -0
  101. package/dist/sniff.js +224 -0
  102. package/dist/stream-meter.d.ts +39 -0
  103. package/dist/stream-meter.js +54 -0
  104. package/dist/tar.d.ts +102 -0
  105. package/dist/tar.js +765 -0
  106. package/dist/types.d.ts +311 -0
  107. package/dist/types.js +133 -0
  108. package/dist/unpack.d.ts +67 -0
  109. package/dist/unpack.js +194 -0
  110. package/dist/xz.d.ts +25 -0
  111. package/dist/xz.js +333 -0
  112. package/dist/zip-lzma.d.ts +15 -0
  113. package/dist/zip-lzma.js +137 -0
  114. package/dist/zip-writer.d.ts +51 -0
  115. package/dist/zip-writer.js +305 -0
  116. package/dist/zip.d.ts +99 -0
  117. package/dist/zip.js +901 -0
  118. package/dist/zipcrypt.d.ts +47 -0
  119. package/dist/zipcrypt.js +233 -0
  120. package/dist/zstd.d.ts +25 -0
  121. package/dist/zstd.js +160 -0
  122. package/package.json +94 -4
@@ -0,0 +1,311 @@
1
+ /** High-level kind of a finding. */
2
+ export declare enum ArchiveCategory {
3
+ Corrupted = "CORRUPTED",
4
+ Structure = "STRUCTURE",
5
+ Name = "NAME",
6
+ Link = "LINK",
7
+ Special = "SPECIAL",
8
+ Permissions = "PERMISSIONS",
9
+ Encrypted = "ENCRYPTED",
10
+ Compression = "COMPRESSION",
11
+ Entry = "ENTRY",
12
+ Metadata = "METADATA",
13
+ Limit = "LIMIT",
14
+ Processing = "PROCESSING"
15
+ }
16
+ /** Exact variant of a finding. */
17
+ export declare enum ArchiveDetail {
18
+ Unparseable = "UNPARSEABLE",
19
+ Truncated = "TRUNCATED",
20
+ DataError = "DATA_ERROR",
21
+ EntryData = "ENTRY_DATA",
22
+ CheckFailed = "CHECK_FAILED",
23
+ LeadingBytes = "LEADING_BYTES",
24
+ TrailingBytes = "TRAILING_BYTES",
25
+ HiddenData = "HIDDEN_DATA",
26
+ Polyglot = "POLYGLOT",
27
+ SeveralEndRecords = "SEVERAL_END_RECORDS",
28
+ HeaderMismatch = "HEADER_MISMATCH",
29
+ OffsetShift = "OFFSET_SHIFT",
30
+ Overlap = "OVERLAP",
31
+ ExtraField = "EXTRA_FIELD",
32
+ NonFileData = "NON_FILE_DATA",
33
+ MultipleStreams = "MULTIPLE_STREAMS",
34
+ MalformedHeader = "MALFORMED_HEADER",
35
+ MultiVolume = "MULTI_VOLUME",
36
+ StreamPadding = "STREAM_PADDING",
37
+ BadPadding = "BAD_PADDING",
38
+ IndexMismatch = "INDEX_MISMATCH",
39
+ SizeMismatch = "SIZE_MISMATCH",
40
+ NoCheck = "NO_CHECK",
41
+ UnknownCheck = "UNKNOWN_CHECK",
42
+ UnknownProperty = "UNKNOWN_PROPERTY",
43
+ EmptyStartHeader = "EMPTY_START_HEADER",
44
+ Traversal = "TRAVERSAL",
45
+ Absolute = "ABSOLUTE",
46
+ DriveLetter = "DRIVE_LETTER",
47
+ Backslash = "BACKSLASH",
48
+ EmptySegment = "EMPTY_SEGMENT",
49
+ ControlCharacter = "CONTROL_CHARACTER",
50
+ WindowsReserved = "WINDOWS_RESERVED",
51
+ Encoding = "ENCODING",
52
+ UnicodePath = "UNICODE_PATH",
53
+ Empty = "EMPTY",
54
+ TooLong = "TOO_LONG",
55
+ Duplicate = "DUPLICATE",
56
+ CaseCollision = "CASE_COLLISION",
57
+ NormalizationCollision = "NORMALIZATION_COLLISION",
58
+ FileDirectoryClash = "FILE_DIRECTORY_CLASH",
59
+ ShortNameCollision = "SHORT_NAME_COLLISION",
60
+ Symlink = "SYMLINK",
61
+ Hardlink = "HARDLINK",
62
+ Outside = "OUTSIDE",
63
+ Dangling = "DANGLING",
64
+ ThroughLink = "THROUGH_LINK",
65
+ Device = "DEVICE",
66
+ Fifo = "FIFO",
67
+ Socket = "SOCKET",
68
+ UnknownType = "UNKNOWN_TYPE",
69
+ AntiItem = "ANTI_ITEM",
70
+ Setuid = "SETUID",
71
+ Setgid = "SETGID",
72
+ Sticky = "STICKY",
73
+ Capability = "CAPABILITY",
74
+ ZipCrypto = "ZIPCRYPTO",
75
+ Aes128 = "AES_128",
76
+ Aes192 = "AES_192",
77
+ Aes256 = "AES_256",
78
+ Decrypted = "DECRYPTED",
79
+ EmptyPassword = "EMPTY_PASSWORD",
80
+ PasswordRequired = "PASSWORD_REQUIRED",
81
+ Unsupported = "UNSUPPORTED",
82
+ Header = "HEADER",
83
+ UnsupportedMethod = "UNSUPPORTED_METHOD",
84
+ UnsupportedFeature = "UNSUPPORTED_FEATURE",
85
+ UnusualMethod = "UNUSUAL_METHOD",
86
+ Unavailable = "UNAVAILABLE",
87
+ NoPlugin = "NO_PLUGIN",
88
+ TypeMismatch = "TYPE_MISMATCH",
89
+ PluginPassed = "PLUGIN_PASSED",
90
+ PluginScrubbed = "PLUGIN_SCRUBBED",
91
+ PluginFailed = "PLUGIN_FAILED",
92
+ PluginRemoved = "PLUGIN_REMOVED",
93
+ Comment = "COMMENT",
94
+ Stripped = "STRIPPED",
95
+ FileSize = "FILE_SIZE",
96
+ EntryCount = "ENTRY_COUNT",
97
+ DecompressedSize = "DECOMPRESSED_SIZE",
98
+ TotalDecompressedSize = "TOTAL_DECOMPRESSED_SIZE",
99
+ Ratio = "RATIO",
100
+ DictionarySize = "DICTIONARY_SIZE",
101
+ NestingDepth = "NESTING_DEPTH",
102
+ Time = "TIME",
103
+ MemoryFallback = "MEMORY_FALLBACK",
104
+ VerificationFailed = "VERIFICATION_FAILED",
105
+ ContentRemoved = "CONTENT_REMOVED"
106
+ }
107
+ export type ArchiveFindingAction = 'reject' | 'strip' | 'info';
108
+ /**
109
+ * A finding as any package of the defuse family reports it. Category and detail are plain strings, since the string
110
+ * enums of two packages never match each other.
111
+ */
112
+ export interface DefuseFinding {
113
+ category: string;
114
+ detail: string;
115
+ /** Plain sentence, safe to show the uploader. */
116
+ description: string;
117
+ /** Default action after any caller override. */
118
+ action: 'reject' | 'strip' | 'info';
119
+ /** Where in the file, such as the name of an entry. */
120
+ location?: string;
121
+ /** Extra values: the entry name, sizes, counts, the plugin name. */
122
+ data?: Record<string, string | number>;
123
+ /**
124
+ * Set when the finding comes from inside a contained file, such as a PDF inside the archive: the file's name, with
125
+ * " > " between nesting levels. `location` then starts with where that file sits.
126
+ */
127
+ attachment?: string;
128
+ /** How much the finding adds to a score, set by the package that made it. */
129
+ weight?: number;
130
+ }
131
+ /** A finding archive-defuse makes itself. */
132
+ export interface ArchiveFinding extends DefuseFinding {
133
+ category: ArchiveCategory;
134
+ detail: ArchiveDetail;
135
+ }
136
+ export declare enum ArchiveRisk {
137
+ None = "NONE",
138
+ Low = "LOW",
139
+ Medium = "MEDIUM",
140
+ High = "HIGH",
141
+ Critical = "CRITICAL",
142
+ /** The file could not be inspected: unparseable, an entry no password opens, or a limit stopped the run. */
143
+ Unknown = "UNKNOWN"
144
+ }
145
+ /** The formats archive-defuse reads and writes. */
146
+ export type ArchiveFormat = 'zip' | 'tar' | 'gzip' | 'bzip2' | 'zstd' | 'brotli' | 'cab' | '7z' | 'xz' | 'lzma';
147
+ export interface ArchiveInspection {
148
+ status: 'clean' | 'strippable' | 'rejected';
149
+ /** 0 to 100, null when risk is UNKNOWN. */
150
+ score: number | null;
151
+ risk: ArchiveRisk;
152
+ findings: DefuseFinding[];
153
+ /** The format the content was read as. Absent when it matched none. */
154
+ format?: ArchiveFormat;
155
+ /** Entries in the archive, or 1 for a compressed file. Absent when the archive could not be opened. */
156
+ entries?: number;
157
+ }
158
+ export interface ArchiveDisarmResult {
159
+ status: 'clean' | 'defused' | 'rejected';
160
+ /** The uploaded file and its score. */
161
+ before: ArchiveInspection;
162
+ /** The output and its remaining score. Absent when rejected. */
163
+ after?: ArchiveInspection;
164
+ /** Findings whose content was removed. */
165
+ removed: DefuseFinding[];
166
+ }
167
+ /** Random-access input. A buffer, a local file and an S3 ranged GetObject all fit. */
168
+ export interface ByteSource {
169
+ size(): Promise<number>;
170
+ read(offset: number, length: number): Promise<Uint8Array>;
171
+ close?(): Promise<void>;
172
+ }
173
+ /** Append-only output. Never seeks. */
174
+ export interface ByteSink {
175
+ write(chunk: Uint8Array): Promise<void>;
176
+ close(): Promise<void>;
177
+ /** Called instead of close() when copying to the sink fails, so a partial output is not taken for a whole one. */
178
+ abort?(error: unknown): Promise<void>;
179
+ }
180
+ export interface ArchiveLimits {
181
+ /** Bytes in the upload. Not enforced unless set. */
182
+ fileSize?: number;
183
+ /** Entries in the archive. Default 10,000. */
184
+ entries?: number;
185
+ /** Decompressed size of any one entry, declared or actual, in bytes. Default 512 MiB. */
186
+ decompressedBytes?: number;
187
+ /** Decompressed sizes of the entries read in one run added together, declared or actual, in bytes. Default 2 GiB. */
188
+ totalDecompressedBytes?: number;
189
+ /**
190
+ * Decompressed bytes per compressed byte of one entry, checked once the entry passes 1 MiB decompressed. Default
191
+ * 1,000.
192
+ */
193
+ compressionRatio?: number;
194
+ /**
195
+ * The deepest an archive may sit in the upload. The upload is at depth 0 and a file inside it at 1, and files of
196
+ * every format in between count. Default 10, since an archive can hold itself.
197
+ */
198
+ nestingDepth?: number;
199
+ /**
200
+ * The dictionary memory LZMA decoding may need, in bytes: one LZMA or LZMA2 stream's dictionary, or those of all the
201
+ * coders of one 7z folder together with their probability tables. A dictionary larger than the declared decoded size
202
+ * counts at that size. Default 256 MiB.
203
+ */
204
+ dictionaryBytes?: number;
205
+ /** Milliseconds for the whole run. Not enforced unless set. */
206
+ timeMs?: number;
207
+ }
208
+ /**
209
+ * A file's format as a package of the family finds it, among the formats that package reads. The family's router asks
210
+ * each package and routes the file by the answers.
211
+ */
212
+ export interface FormatDetection {
213
+ /** The format's MIME type, such as application/zip. */
214
+ mimeType: string;
215
+ /** The format's usual extension, lowercase and without the dot. */
216
+ extension: string;
217
+ /** Where the format starts in the file: 0, or the offset of its data when other data comes first. */
218
+ offset: number;
219
+ /** Set when the match rests on more than the content, and says what it rests on. */
220
+ heuristic?: string;
221
+ }
222
+ /** What a detect function may know of a file besides its content. */
223
+ export interface DetectOptions {
224
+ /** The file's name, as the upload or the container that holds it gives it. */
225
+ name?: string;
226
+ /** The MIME type the upload or the container declares. */
227
+ declaredType?: string;
228
+ /** The Date.now() value detection must finish by, as `PluginContext.deadline`. */
229
+ deadline?: number;
230
+ /** Folder for temporary files. Defaults to `os.tmpdir()`. */
231
+ tempDir?: string;
232
+ /** Bytes held in memory before a temporary file takes over. */
233
+ memoryThreshold?: number;
234
+ }
235
+ /** What a contained file plugin learns of the run, with nothing format-specific, so any package of the family can make one. */
236
+ export interface PluginContext {
237
+ /** The depth of the file itself: 0 for the upload, 1 for a file inside it, and so on, whatever the formats. */
238
+ depth: number;
239
+ /** When a time limit is set, the Date.now() value the whole run must finish by. Nested runs share it. */
240
+ deadline?: number;
241
+ }
242
+ export interface ContainedFile {
243
+ name?: string;
244
+ /** The MIME type the container declares for the file. Archives declare none. */
245
+ declaredType?: string;
246
+ /** From the first bytes. */
247
+ sniffedType?: string;
248
+ /** Decoded size. */
249
+ size: number;
250
+ location: string;
251
+ /** The depth of the file itself: 0 for the upload, 1 for a file inside it, and so on, whatever the formats. */
252
+ depth: number;
253
+ /** Decoded and decrypted bytes. */
254
+ source: ByteSource;
255
+ }
256
+ /** What a file plugin did, plus anything it found inside the file. */
257
+ export interface ContainedFileResult {
258
+ result: 'scrubbed' | 'passed' | 'removed';
259
+ /** Findings inside the file as it arrived. They go into the report of the file that contains it. */
260
+ findings?: DefuseFinding[];
261
+ /** Findings inside the bytes the plugin kept. They go into the report of the output. */
262
+ outputFindings?: DefuseFinding[];
263
+ }
264
+ export interface ContainedFilePlugin {
265
+ kind: 'file';
266
+ name: string;
267
+ accepts(file: ContainedFile): boolean | Promise<boolean>;
268
+ /** Writes the bytes to keep. Returning 'removed' drops the file after all. */
269
+ process(file: ContainedFile, sink: ByteSink, context: PluginContext): Promise<'scrubbed' | 'passed' | 'removed' | ContainedFileResult>;
270
+ }
271
+ export interface ArchiveActionOverride {
272
+ category: ArchiveCategory;
273
+ detail?: ArchiveDetail;
274
+ action: ArchiveFindingAction;
275
+ }
276
+ export interface ArchiveScoreWeight {
277
+ category: ArchiveCategory;
278
+ detail?: ArchiveDetail;
279
+ weight: number;
280
+ }
281
+ /** Lower bound of each band. */
282
+ export interface ArchiveScoreBands {
283
+ low: number;
284
+ medium: number;
285
+ high: number;
286
+ critical: number;
287
+ }
288
+ export interface ArchiveOptions {
289
+ /**
290
+ * Passwords for encrypted entries. Each is tried in order on each encrypted entry, and the empty password after
291
+ * them.
292
+ */
293
+ password?: string | string[];
294
+ /** Limits left out take the defaults listed on ArchiveLimits. */
295
+ limits?: ArchiveLimits;
296
+ /** Default false. The rewrite drops comments, owner names and ids, timestamps and extended attributes. */
297
+ stripMetadata?: boolean;
298
+ actionOverrides?: ArchiveActionOverride[];
299
+ scoreWeights?: ArchiveScoreWeight[];
300
+ scoreBands?: ArchiveScoreBands;
301
+ /** Every file entry goes to these in order. The first that accepts it decides. */
302
+ filePlugins?: ContainedFilePlugin[];
303
+ /** Directory for temporary files. Defaults to os.tmpdir(). */
304
+ tempDir?: string;
305
+ /**
306
+ * Default 8 MiB. disarmArchiveSource keeps its copy of the upload in memory up to this size and in a temporary file
307
+ * above it. Each entry handed to the plugins above it goes through a temporary file, and the copies plugins keep
308
+ * share this much memory.
309
+ */
310
+ memoryThreshold?: number;
311
+ }
package/dist/types.js ADDED
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ArchiveRisk = exports.ArchiveDetail = exports.ArchiveCategory = void 0;
4
+ /** High-level kind of a finding. */
5
+ var ArchiveCategory;
6
+ (function (ArchiveCategory) {
7
+ ArchiveCategory["Corrupted"] = "CORRUPTED";
8
+ ArchiveCategory["Structure"] = "STRUCTURE";
9
+ ArchiveCategory["Name"] = "NAME";
10
+ ArchiveCategory["Link"] = "LINK";
11
+ ArchiveCategory["Special"] = "SPECIAL";
12
+ ArchiveCategory["Permissions"] = "PERMISSIONS";
13
+ ArchiveCategory["Encrypted"] = "ENCRYPTED";
14
+ ArchiveCategory["Compression"] = "COMPRESSION";
15
+ ArchiveCategory["Entry"] = "ENTRY";
16
+ ArchiveCategory["Metadata"] = "METADATA";
17
+ ArchiveCategory["Limit"] = "LIMIT";
18
+ ArchiveCategory["Processing"] = "PROCESSING";
19
+ })(ArchiveCategory || (exports.ArchiveCategory = ArchiveCategory = {}));
20
+ /** Exact variant of a finding. */
21
+ var ArchiveDetail;
22
+ (function (ArchiveDetail) {
23
+ // CORRUPTED
24
+ ArchiveDetail["Unparseable"] = "UNPARSEABLE";
25
+ ArchiveDetail["Truncated"] = "TRUNCATED";
26
+ ArchiveDetail["DataError"] = "DATA_ERROR";
27
+ ArchiveDetail["EntryData"] = "ENTRY_DATA";
28
+ ArchiveDetail["CheckFailed"] = "CHECK_FAILED";
29
+ // STRUCTURE
30
+ ArchiveDetail["LeadingBytes"] = "LEADING_BYTES";
31
+ ArchiveDetail["TrailingBytes"] = "TRAILING_BYTES";
32
+ ArchiveDetail["HiddenData"] = "HIDDEN_DATA";
33
+ ArchiveDetail["Polyglot"] = "POLYGLOT";
34
+ ArchiveDetail["SeveralEndRecords"] = "SEVERAL_END_RECORDS";
35
+ ArchiveDetail["HeaderMismatch"] = "HEADER_MISMATCH";
36
+ ArchiveDetail["OffsetShift"] = "OFFSET_SHIFT";
37
+ ArchiveDetail["Overlap"] = "OVERLAP";
38
+ ArchiveDetail["ExtraField"] = "EXTRA_FIELD";
39
+ ArchiveDetail["NonFileData"] = "NON_FILE_DATA";
40
+ ArchiveDetail["MultipleStreams"] = "MULTIPLE_STREAMS";
41
+ ArchiveDetail["MalformedHeader"] = "MALFORMED_HEADER";
42
+ ArchiveDetail["MultiVolume"] = "MULTI_VOLUME";
43
+ ArchiveDetail["StreamPadding"] = "STREAM_PADDING";
44
+ ArchiveDetail["BadPadding"] = "BAD_PADDING";
45
+ ArchiveDetail["IndexMismatch"] = "INDEX_MISMATCH";
46
+ ArchiveDetail["SizeMismatch"] = "SIZE_MISMATCH";
47
+ ArchiveDetail["NoCheck"] = "NO_CHECK";
48
+ ArchiveDetail["UnknownCheck"] = "UNKNOWN_CHECK";
49
+ ArchiveDetail["UnknownProperty"] = "UNKNOWN_PROPERTY";
50
+ ArchiveDetail["EmptyStartHeader"] = "EMPTY_START_HEADER";
51
+ // NAME
52
+ ArchiveDetail["Traversal"] = "TRAVERSAL";
53
+ ArchiveDetail["Absolute"] = "ABSOLUTE";
54
+ ArchiveDetail["DriveLetter"] = "DRIVE_LETTER";
55
+ ArchiveDetail["Backslash"] = "BACKSLASH";
56
+ ArchiveDetail["EmptySegment"] = "EMPTY_SEGMENT";
57
+ ArchiveDetail["ControlCharacter"] = "CONTROL_CHARACTER";
58
+ ArchiveDetail["WindowsReserved"] = "WINDOWS_RESERVED";
59
+ ArchiveDetail["Encoding"] = "ENCODING";
60
+ ArchiveDetail["UnicodePath"] = "UNICODE_PATH";
61
+ ArchiveDetail["Empty"] = "EMPTY";
62
+ ArchiveDetail["TooLong"] = "TOO_LONG";
63
+ ArchiveDetail["Duplicate"] = "DUPLICATE";
64
+ ArchiveDetail["CaseCollision"] = "CASE_COLLISION";
65
+ ArchiveDetail["NormalizationCollision"] = "NORMALIZATION_COLLISION";
66
+ ArchiveDetail["FileDirectoryClash"] = "FILE_DIRECTORY_CLASH";
67
+ ArchiveDetail["ShortNameCollision"] = "SHORT_NAME_COLLISION";
68
+ // LINK
69
+ ArchiveDetail["Symlink"] = "SYMLINK";
70
+ ArchiveDetail["Hardlink"] = "HARDLINK";
71
+ ArchiveDetail["Outside"] = "OUTSIDE";
72
+ ArchiveDetail["Dangling"] = "DANGLING";
73
+ ArchiveDetail["ThroughLink"] = "THROUGH_LINK";
74
+ // SPECIAL
75
+ ArchiveDetail["Device"] = "DEVICE";
76
+ ArchiveDetail["Fifo"] = "FIFO";
77
+ ArchiveDetail["Socket"] = "SOCKET";
78
+ ArchiveDetail["UnknownType"] = "UNKNOWN_TYPE";
79
+ ArchiveDetail["AntiItem"] = "ANTI_ITEM";
80
+ // PERMISSIONS
81
+ ArchiveDetail["Setuid"] = "SETUID";
82
+ ArchiveDetail["Setgid"] = "SETGID";
83
+ ArchiveDetail["Sticky"] = "STICKY";
84
+ ArchiveDetail["Capability"] = "CAPABILITY";
85
+ // ENCRYPTED
86
+ ArchiveDetail["ZipCrypto"] = "ZIPCRYPTO";
87
+ ArchiveDetail["Aes128"] = "AES_128";
88
+ ArchiveDetail["Aes192"] = "AES_192";
89
+ ArchiveDetail["Aes256"] = "AES_256";
90
+ ArchiveDetail["Decrypted"] = "DECRYPTED";
91
+ ArchiveDetail["EmptyPassword"] = "EMPTY_PASSWORD";
92
+ ArchiveDetail["PasswordRequired"] = "PASSWORD_REQUIRED";
93
+ ArchiveDetail["Unsupported"] = "UNSUPPORTED";
94
+ ArchiveDetail["Header"] = "HEADER";
95
+ // COMPRESSION
96
+ ArchiveDetail["UnsupportedMethod"] = "UNSUPPORTED_METHOD";
97
+ ArchiveDetail["UnsupportedFeature"] = "UNSUPPORTED_FEATURE";
98
+ ArchiveDetail["UnusualMethod"] = "UNUSUAL_METHOD";
99
+ ArchiveDetail["Unavailable"] = "UNAVAILABLE";
100
+ // ENTRY
101
+ ArchiveDetail["NoPlugin"] = "NO_PLUGIN";
102
+ ArchiveDetail["TypeMismatch"] = "TYPE_MISMATCH";
103
+ ArchiveDetail["PluginPassed"] = "PLUGIN_PASSED";
104
+ ArchiveDetail["PluginScrubbed"] = "PLUGIN_SCRUBBED";
105
+ ArchiveDetail["PluginFailed"] = "PLUGIN_FAILED";
106
+ ArchiveDetail["PluginRemoved"] = "PLUGIN_REMOVED";
107
+ // METADATA
108
+ ArchiveDetail["Comment"] = "COMMENT";
109
+ ArchiveDetail["Stripped"] = "STRIPPED";
110
+ // LIMIT
111
+ ArchiveDetail["FileSize"] = "FILE_SIZE";
112
+ ArchiveDetail["EntryCount"] = "ENTRY_COUNT";
113
+ ArchiveDetail["DecompressedSize"] = "DECOMPRESSED_SIZE";
114
+ ArchiveDetail["TotalDecompressedSize"] = "TOTAL_DECOMPRESSED_SIZE";
115
+ ArchiveDetail["Ratio"] = "RATIO";
116
+ ArchiveDetail["DictionarySize"] = "DICTIONARY_SIZE";
117
+ ArchiveDetail["NestingDepth"] = "NESTING_DEPTH";
118
+ ArchiveDetail["Time"] = "TIME";
119
+ // PROCESSING
120
+ ArchiveDetail["MemoryFallback"] = "MEMORY_FALLBACK";
121
+ ArchiveDetail["VerificationFailed"] = "VERIFICATION_FAILED";
122
+ ArchiveDetail["ContentRemoved"] = "CONTENT_REMOVED";
123
+ })(ArchiveDetail || (exports.ArchiveDetail = ArchiveDetail = {}));
124
+ var ArchiveRisk;
125
+ (function (ArchiveRisk) {
126
+ ArchiveRisk["None"] = "NONE";
127
+ ArchiveRisk["Low"] = "LOW";
128
+ ArchiveRisk["Medium"] = "MEDIUM";
129
+ ArchiveRisk["High"] = "HIGH";
130
+ ArchiveRisk["Critical"] = "CRITICAL";
131
+ /** The file could not be inspected: unparseable, an entry no password opens, or a limit stopped the run. */
132
+ ArchiveRisk["Unknown"] = "UNKNOWN";
133
+ })(ArchiveRisk || (exports.ArchiveRisk = ArchiveRisk = {}));
@@ -0,0 +1,67 @@
1
+ import type { EntryKind } from './model';
2
+ import type { ArchiveFormat, ArchiveLimits, ByteSource } from './types';
3
+ /** One entry of an archive, as `openArchive` lists it. */
4
+ export interface ArchiveReaderEntry {
5
+ /** Position in the archive's own order. */
6
+ index: number;
7
+ /**
8
+ * The name as the archive gives it, decoded, with no rule applied: it can climb out with "..", be absolute or repeat
9
+ * another entry's name. Folders end in "/". The one entry of a compressed file has the name the file stores, or "".
10
+ */
11
+ name: string;
12
+ kind: EntryKind;
13
+ /** Decoded size the headers declare, or undefined for a compressed file, whose size is known only once read. */
14
+ size?: number;
15
+ /** Permission bits, when the format records them. */
16
+ mode?: number;
17
+ /** A link's target, when the entry is a link. */
18
+ linkTarget?: string;
19
+ /** True when the entry is encrypted. */
20
+ encrypted: boolean;
21
+ }
22
+ export interface OpenArchiveOptions {
23
+ /** Folder for temporary files, which an XZ entry of a ZIP archive needs. Defaults to `os.tmpdir()`. */
24
+ tempDir?: string;
25
+ /** Bytes an XZ entry of a ZIP archive holds in memory before a temporary file takes over. Default 8 MiB. */
26
+ memoryThreshold?: number;
27
+ /** One password or a list, tried in order on each encrypted entry, then the empty password. */
28
+ password?: string | string[];
29
+ /** The limits of `inspectArchive`, with its defaults: every read counts toward them, and the total is shared. */
30
+ limits?: ArchiveLimits;
31
+ }
32
+ /** An archive opened for reading. */
33
+ export interface ArchiveReader {
34
+ format: ArchiveFormat;
35
+ entries: ArchiveReaderEntry[];
36
+ /** The first entry with this exact name, or undefined. */
37
+ find(name: string): ArchiveReaderEntry | undefined;
38
+ /** An entry's content, decrypted and decoded, checked against its size and CRC as it goes. */
39
+ stream(entry: ArchiveReaderEntry | string): AsyncIterable<Uint8Array>;
40
+ /** An entry's whole content. */
41
+ bytes(entry: ArchiveReaderEntry | string): Promise<Buffer>;
42
+ /** An entry's whole content as text, UTF-8 unless `encoding` says otherwise. */
43
+ text(entry: ArchiveReaderEntry | string, encoding?: BufferEncoding): Promise<string>;
44
+ /** Closes the source. */
45
+ close(): Promise<void>;
46
+ }
47
+ /**
48
+ * Thrown when an archive cannot be read: not a format this package reads, a limit, a missing password, or data that
49
+ * does not decode. `category` and `detail` name the finding `inspectArchive` would report.
50
+ */
51
+ export declare class ArchiveReadError extends Error {
52
+ readonly category: string;
53
+ readonly detail: string;
54
+ readonly data?: Record<string, string | number> | undefined;
55
+ constructor(message: string, category: string, detail: string, data?: Record<string, string | number> | undefined);
56
+ }
57
+ /**
58
+ * Opens an archive or a compressed file for reading. The format comes from the content, as for `inspectArchive`. The
59
+ * entries are listed at once; content is read only when asked for. The source is closed by `close()`, or at once when
60
+ * opening fails.
61
+ */
62
+ export declare function openArchive(input: Uint8Array | ByteSource, options?: OpenArchiveOptions): Promise<ArchiveReader>;
63
+ /**
64
+ * Decodes a compressed file, such as gzip, bzip2, zstd, Brotli, xz or .lzma, to its content. An archive of several
65
+ * entries throws; `openArchive` reads those.
66
+ */
67
+ export declare function decompress(input: Uint8Array | ByteSource, options?: OpenArchiveOptions): Promise<Buffer>;