git ssb

3+

cel / ssb-npm-registry



Tree: d2f2697f296dd39aed6a8b63c6d04a736a7db5b3

Files: d2f2697f296dd39aed6a8b63c6d04a736a7db5b3 / node_modules / tar-stream / headers.js

7375 bytesRaw
1var alloc = Buffer.alloc
2
3var ZEROS = '0000000000000000000'
4var SEVENS = '7777777777777777777'
5var ZERO_OFFSET = '0'.charCodeAt(0)
6var USTAR = 'ustar\x0000'
7var MASK = parseInt('7777', 8)
8
9var clamp = function (index, len, defaultValue) {
10 if (typeof index !== 'number') return defaultValue
11 index = ~~index // Coerce to integer.
12 if (index >= len) return len
13 if (index >= 0) return index
14 index += len
15 if (index >= 0) return index
16 return 0
17}
18
19var toType = function (flag) {
20 switch (flag) {
21 case 0:
22 return 'file'
23 case 1:
24 return 'link'
25 case 2:
26 return 'symlink'
27 case 3:
28 return 'character-device'
29 case 4:
30 return 'block-device'
31 case 5:
32 return 'directory'
33 case 6:
34 return 'fifo'
35 case 7:
36 return 'contiguous-file'
37 case 72:
38 return 'pax-header'
39 case 55:
40 return 'pax-global-header'
41 case 27:
42 return 'gnu-long-link-path'
43 case 28:
44 case 30:
45 return 'gnu-long-path'
46 }
47
48 return null
49}
50
51var toTypeflag = function (flag) {
52 switch (flag) {
53 case 'file':
54 return 0
55 case 'link':
56 return 1
57 case 'symlink':
58 return 2
59 case 'character-device':
60 return 3
61 case 'block-device':
62 return 4
63 case 'directory':
64 return 5
65 case 'fifo':
66 return 6
67 case 'contiguous-file':
68 return 7
69 case 'pax-header':
70 return 72
71 }
72
73 return 0
74}
75
76var indexOf = function (block, num, offset, end) {
77 for (; offset < end; offset++) {
78 if (block[offset] === num) return offset
79 }
80 return end
81}
82
83var cksum = function (block) {
84 var sum = 8 * 32
85 for (var i = 0; i < 148; i++) sum += block[i]
86 for (var j = 156; j < 512; j++) sum += block[j]
87 return sum
88}
89
90var encodeOct = function (val, n) {
91 val = val.toString(8)
92 if (val.length > n) return SEVENS.slice(0, n) + ' '
93 else return ZEROS.slice(0, n - val.length) + val + ' '
94}
95
96/* Copied from the node-tar repo and modified to meet
97 * tar-stream coding standard.
98 *
99 * Source: https://github.com/npm/node-tar/blob/51b6627a1f357d2eb433e7378e5f05e83b7aa6cd/lib/header.js#L349
100 */
101function parse256 (buf) {
102 // first byte MUST be either 80 or FF
103 // 80 for positive, FF for 2's comp
104 var positive
105 if (buf[0] === 0x80) positive = true
106 else if (buf[0] === 0xFF) positive = false
107 else return null
108
109 // build up a base-256 tuple from the least sig to the highest
110 var zero = false
111 var tuple = []
112 for (var i = buf.length - 1; i > 0; i--) {
113 var byte = buf[i]
114 if (positive) tuple.push(byte)
115 else if (zero && byte === 0) tuple.push(0)
116 else if (zero) {
117 zero = false
118 tuple.push(0x100 - byte)
119 } else tuple.push(0xFF - byte)
120 }
121
122 var sum = 0
123 var l = tuple.length
124 for (i = 0; i < l; i++) {
125 sum += tuple[i] * Math.pow(256, i)
126 }
127
128 return positive ? sum : -1 * sum
129}
130
131var decodeOct = function (val, offset, length) {
132 val = val.slice(offset, offset + length)
133 offset = 0
134
135 // If prefixed with 0x80 then parse as a base-256 integer
136 if (val[offset] & 0x80) {
137 return parse256(val)
138 } else {
139 // Older versions of tar can prefix with spaces
140 while (offset < val.length && val[offset] === 32) offset++
141 var end = clamp(indexOf(val, 32, offset, val.length), val.length, val.length)
142 while (offset < end && val[offset] === 0) offset++
143 if (end === offset) return 0
144 return parseInt(val.slice(offset, end).toString(), 8)
145 }
146}
147
148var decodeStr = function (val, offset, length, encoding) {
149 return val.slice(offset, indexOf(val, 0, offset, offset + length)).toString(encoding)
150}
151
152var addLength = function (str) {
153 var len = Buffer.byteLength(str)
154 var digits = Math.floor(Math.log(len) / Math.log(10)) + 1
155 if (len + digits >= Math.pow(10, digits)) digits++
156
157 return (len + digits) + str
158}
159
160exports.decodeLongPath = function (buf, encoding) {
161 return decodeStr(buf, 0, buf.length, encoding)
162}
163
164exports.encodePax = function (opts) { // TODO: encode more stuff in pax
165 var result = ''
166 if (opts.name) result += addLength(' path=' + opts.name + '\n')
167 if (opts.linkname) result += addLength(' linkpath=' + opts.linkname + '\n')
168 var pax = opts.pax
169 if (pax) {
170 for (var key in pax) {
171 result += addLength(' ' + key + '=' + pax[key] + '\n')
172 }
173 }
174 return Buffer.from(result)
175}
176
177exports.decodePax = function (buf) {
178 var result = {}
179
180 while (buf.length) {
181 var i = 0
182 while (i < buf.length && buf[i] !== 32) i++
183 var len = parseInt(buf.slice(0, i).toString(), 10)
184 if (!len) return result
185
186 var b = buf.slice(i + 1, len - 1).toString()
187 var keyIndex = b.indexOf('=')
188 if (keyIndex === -1) return result
189 result[b.slice(0, keyIndex)] = b.slice(keyIndex + 1)
190
191 buf = buf.slice(len)
192 }
193
194 return result
195}
196
197exports.encode = function (opts) {
198 var buf = alloc(512)
199 var name = opts.name
200 var prefix = ''
201
202 if (opts.typeflag === 5 && name[name.length - 1] !== '/') name += '/'
203 if (Buffer.byteLength(name) !== name.length) return null // utf-8
204
205 while (Buffer.byteLength(name) > 100) {
206 var i = name.indexOf('/')
207 if (i === -1) return null
208 prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i)
209 name = name.slice(i + 1)
210 }
211
212 if (Buffer.byteLength(name) > 100 || Buffer.byteLength(prefix) > 155) return null
213 if (opts.linkname && Buffer.byteLength(opts.linkname) > 100) return null
214
215 buf.write(name)
216 buf.write(encodeOct(opts.mode & MASK, 6), 100)
217 buf.write(encodeOct(opts.uid, 6), 108)
218 buf.write(encodeOct(opts.gid, 6), 116)
219 buf.write(encodeOct(opts.size, 11), 124)
220 buf.write(encodeOct((opts.mtime.getTime() / 1000) | 0, 11), 136)
221
222 buf[156] = ZERO_OFFSET + toTypeflag(opts.type)
223
224 if (opts.linkname) buf.write(opts.linkname, 157)
225
226 buf.write(USTAR, 257)
227 if (opts.uname) buf.write(opts.uname, 265)
228 if (opts.gname) buf.write(opts.gname, 297)
229 buf.write(encodeOct(opts.devmajor || 0, 6), 329)
230 buf.write(encodeOct(opts.devminor || 0, 6), 337)
231
232 if (prefix) buf.write(prefix, 345)
233
234 buf.write(encodeOct(cksum(buf), 6), 148)
235
236 return buf
237}
238
239exports.decode = function (buf, filenameEncoding) {
240 var typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET
241
242 var name = decodeStr(buf, 0, 100, filenameEncoding)
243 var mode = decodeOct(buf, 100, 8)
244 var uid = decodeOct(buf, 108, 8)
245 var gid = decodeOct(buf, 116, 8)
246 var size = decodeOct(buf, 124, 12)
247 var mtime = decodeOct(buf, 136, 12)
248 var type = toType(typeflag)
249 var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100, filenameEncoding)
250 var uname = decodeStr(buf, 265, 32)
251 var gname = decodeStr(buf, 297, 32)
252 var devmajor = decodeOct(buf, 329, 8)
253 var devminor = decodeOct(buf, 337, 8)
254
255 if (buf[345]) name = decodeStr(buf, 345, 155, filenameEncoding) + '/' + name
256
257 // to support old tar versions that use trailing / to indicate dirs
258 if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5
259
260 var c = cksum(buf)
261
262 // checksum is still initial value if header was null.
263 if (c === 8 * 32) return null
264
265 // valid checksum
266 if (c !== decodeOct(buf, 148, 8)) throw new Error('Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?')
267
268 return {
269 name: name,
270 mode: mode,
271 uid: uid,
272 gid: gid,
273 size: size,
274 mtime: new Date(1000 * mtime),
275 type: type,
276 linkname: linkname,
277 uname: uname,
278 gname: gname,
279 devmajor: devmajor,
280 devminor: devminor
281 }
282}
283

Built with git-ssb-web