codekingpro/portable-devtools
114k
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.ReadEntry = void 0;
4const minipass_1 = require("minipass");
5const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
6class ReadEntry extends minipass_1.Minipass {
7 extended;
8 globalExtended;
9 header;
10 startBlockSize;
11 blockRemain;
12 remain;
13 type;
14 meta = false;
15 ignore = false;
16 path;
17 mode;
18 uid;
19 gid;
20 uname;
21 gname;
22 size = 0;
23 mtime;
24 atime;
25 ctime;
26 linkpath;
27 dev;
28 ino;
29 nlink;
30 invalid = false;
31 absolute;
32 unsupported = false;
33 constructor(header, ex, gex) {
34 super({});
35 // read entries always start life paused. this is to avoid the
36 // situation where Minipass's auto-ending empty streams results
37 // in an entry ending before we're ready for it.
38 this.pause();
39 this.extended = ex;
40 this.globalExtended = gex;
41 this.header = header;
42 /* c8 ignore start */
43 this.remain = header.size ?? 0;
44 /* c8 ignore stop */
45 this.startBlockSize = 512 * Math.ceil(this.remain / 512);
46 this.blockRemain = this.startBlockSize;
47 this.type = header.type;
48 switch (this.type) {
49 case 'File':
50 case 'OldFile':
51 case 'Link':
52 case 'SymbolicLink':
53 case 'CharacterDevice':
54 case 'BlockDevice':
55 case 'Directory':
56 case 'FIFO':
57 case 'ContiguousFile':
58 case 'GNUDumpDir':
59 break;
60 case 'NextFileHasLongLinkpath':
61 case 'NextFileHasLongPath':
62 case 'OldGnuLongPath':
63 case 'GlobalExtendedHeader':
64 case 'ExtendedHeader':
65 case 'OldExtendedHeader':
66 this.meta = true;
67 break;
68 // NOTE: gnutar and bsdtar treat unrecognized types as 'File'
69 // it may be worth doing the same, but with a warning.
70 default:
71 this.ignore = true;
72 }
73 /* c8 ignore start */
74 if (!header.path) {
75 throw new Error('no path provided for tar.ReadEntry');
76 }
77 /* c8 ignore stop */
78 this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(header.path);
79 this.mode = header.mode;
80 if (this.mode) {
81 this.mode = this.mode & 0o7777;
82 }
83 this.uid = header.uid;
84 this.gid = header.gid;
85 this.uname = header.uname;
86 this.gname = header.gname;
87 this.size = this.remain;
88 this.mtime = header.mtime;
89 this.atime = header.atime;
90 this.ctime = header.ctime;
91 /* c8 ignore start */
92 this.linkpath =
93 header.linkpath ?
94 (0, normalize_windows_path_js_1.normalizeWindowsPath)(header.linkpath)
95 : undefined;
96 /* c8 ignore stop */
97 this.uname = header.uname;
98 this.gname = header.gname;
99 if (ex) {
100 this.#slurp(ex);
101 }
102 if (gex) {
103 this.#slurp(gex, true);
104 }
105 }
106 write(data) {
107 const writeLen = data.length;
108 if (writeLen > this.blockRemain) {
109 throw new Error('writing more to entry than is appropriate');
110 }
111 const r = this.remain;
112 const br = this.blockRemain;
113 this.remain = Math.max(0, r - writeLen);
114 this.blockRemain = Math.max(0, br - writeLen);
115 if (this.ignore) {
116 return true;
117 }
118 if (r >= writeLen) {
119 return super.write(data);
120 }
121 // r < writeLen
122 return super.write(data.subarray(0, r));
123 }
124 #slurp(ex, gex = false) {
125 if (ex.path)
126 ex.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(ex.path);
127 if (ex.linkpath)
128 ex.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(ex.linkpath);
129 Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => {
130 // we slurp in everything except for the path attribute in
131 // a global extended header, because that's weird. Also, any
132 // null/undefined values are ignored.
133 return !(v === null ||
134 v === undefined ||
135 (k === 'path' && gex));
136 })));
137 }
138}
139exports.ReadEntry = ReadEntry;
140//# sourceMappingURL=read-entry.js.map