Tons of Solutions Engineering work done today for the rest of the CS team! Headway, Howard Hanna, Engels, Brighton, etc. Also completed Datasnippers auth flow and worked on Anthology's script. Cloned Anthology's courses (900..) and will clone Full Story on Monday.
This commit is contained in:
321
Scripts/node_modules/tar-stream/headers.js
generated
vendored
Normal file
321
Scripts/node_modules/tar-stream/headers.js
generated
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
const b4a = require('b4a')
|
||||
|
||||
const ZEROS = '0000000000000000000'
|
||||
const SEVENS = '7777777777777777777'
|
||||
const ZERO_OFFSET = '0'.charCodeAt(0)
|
||||
const USTAR_MAGIC = b4a.from([0x75, 0x73, 0x74, 0x61, 0x72, 0x00]) // ustar\x00
|
||||
const USTAR_VER = b4a.from([ZERO_OFFSET, ZERO_OFFSET])
|
||||
const GNU_MAGIC = b4a.from([0x75, 0x73, 0x74, 0x61, 0x72, 0x20]) // ustar\x20
|
||||
const GNU_VER = b4a.from([0x20, 0x00])
|
||||
const MASK = 0o7777
|
||||
const MAGIC_OFFSET = 257
|
||||
const VERSION_OFFSET = 263
|
||||
|
||||
exports.decodeLongPath = function decodeLongPath (buf, encoding) {
|
||||
return decodeStr(buf, 0, buf.length, encoding)
|
||||
}
|
||||
|
||||
exports.encodePax = function encodePax (opts) { // TODO: encode more stuff in pax
|
||||
let result = ''
|
||||
if (opts.name) result += addLength(' path=' + opts.name + '\n')
|
||||
if (opts.linkname) result += addLength(' linkpath=' + opts.linkname + '\n')
|
||||
const pax = opts.pax
|
||||
if (pax) {
|
||||
for (const key in pax) {
|
||||
result += addLength(' ' + key + '=' + pax[key] + '\n')
|
||||
}
|
||||
}
|
||||
return b4a.from(result)
|
||||
}
|
||||
|
||||
exports.decodePax = function decodePax (buf) {
|
||||
const result = {}
|
||||
|
||||
while (buf.length) {
|
||||
let i = 0
|
||||
while (i < buf.length && buf[i] !== 32) i++
|
||||
const len = parseInt(buf.subarray(0, i).toString(), 10)
|
||||
if (!len) return result
|
||||
|
||||
const b = b4a.toString(buf.subarray(i + 1, len - 1))
|
||||
const keyIndex = b.indexOf('=')
|
||||
if (keyIndex === -1) return result
|
||||
result[b.slice(0, keyIndex)] = b.slice(keyIndex + 1)
|
||||
|
||||
buf = buf.subarray(len)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
exports.encode = function encode (opts) {
|
||||
const buf = b4a.alloc(512)
|
||||
let name = opts.name
|
||||
let prefix = ''
|
||||
|
||||
if (opts.typeflag === 5 && name[name.length - 1] !== '/') name += '/'
|
||||
if (b4a.byteLength(name) !== name.length) return null // utf-8
|
||||
|
||||
while (b4a.byteLength(name) > 100) {
|
||||
const i = name.indexOf('/')
|
||||
if (i === -1) return null
|
||||
prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i)
|
||||
name = name.slice(i + 1)
|
||||
}
|
||||
|
||||
if (b4a.byteLength(name) > 100 || b4a.byteLength(prefix) > 155) return null
|
||||
if (opts.linkname && b4a.byteLength(opts.linkname) > 100) return null
|
||||
|
||||
b4a.write(buf, name)
|
||||
b4a.write(buf, encodeOct(opts.mode & MASK, 6), 100)
|
||||
b4a.write(buf, encodeOct(opts.uid, 6), 108)
|
||||
b4a.write(buf, encodeOct(opts.gid, 6), 116)
|
||||
encodeSize(opts.size, buf, 124)
|
||||
b4a.write(buf, encodeOct((opts.mtime.getTime() / 1000) | 0, 11), 136)
|
||||
|
||||
buf[156] = ZERO_OFFSET + toTypeflag(opts.type)
|
||||
|
||||
if (opts.linkname) b4a.write(buf, opts.linkname, 157)
|
||||
|
||||
b4a.copy(USTAR_MAGIC, buf, MAGIC_OFFSET)
|
||||
b4a.copy(USTAR_VER, buf, VERSION_OFFSET)
|
||||
if (opts.uname) b4a.write(buf, opts.uname, 265)
|
||||
if (opts.gname) b4a.write(buf, opts.gname, 297)
|
||||
b4a.write(buf, encodeOct(opts.devmajor || 0, 6), 329)
|
||||
b4a.write(buf, encodeOct(opts.devminor || 0, 6), 337)
|
||||
|
||||
if (prefix) b4a.write(buf, prefix, 345)
|
||||
|
||||
b4a.write(buf, encodeOct(cksum(buf), 6), 148)
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
exports.decode = function decode (buf, filenameEncoding, allowUnknownFormat) {
|
||||
let typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET
|
||||
|
||||
let name = decodeStr(buf, 0, 100, filenameEncoding)
|
||||
const mode = decodeOct(buf, 100, 8)
|
||||
const uid = decodeOct(buf, 108, 8)
|
||||
const gid = decodeOct(buf, 116, 8)
|
||||
const size = decodeOct(buf, 124, 12)
|
||||
const mtime = decodeOct(buf, 136, 12)
|
||||
const type = toType(typeflag)
|
||||
const linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100, filenameEncoding)
|
||||
const uname = decodeStr(buf, 265, 32)
|
||||
const gname = decodeStr(buf, 297, 32)
|
||||
const devmajor = decodeOct(buf, 329, 8)
|
||||
const devminor = decodeOct(buf, 337, 8)
|
||||
|
||||
const c = cksum(buf)
|
||||
|
||||
// checksum is still initial value if header was null.
|
||||
if (c === 8 * 32) return null
|
||||
|
||||
// valid checksum
|
||||
if (c !== decodeOct(buf, 148, 8)) throw new Error('Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?')
|
||||
|
||||
if (isUSTAR(buf)) {
|
||||
// ustar (posix) format.
|
||||
// prepend prefix, if present.
|
||||
if (buf[345]) name = decodeStr(buf, 345, 155, filenameEncoding) + '/' + name
|
||||
} else if (isGNU(buf)) {
|
||||
// 'gnu'/'oldgnu' format. Similar to ustar, but has support for incremental and
|
||||
// multi-volume tarballs.
|
||||
} else {
|
||||
if (!allowUnknownFormat) {
|
||||
throw new Error('Invalid tar header: unknown format.')
|
||||
}
|
||||
}
|
||||
|
||||
// to support old tar versions that use trailing / to indicate dirs
|
||||
if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5
|
||||
|
||||
return {
|
||||
name,
|
||||
mode,
|
||||
uid,
|
||||
gid,
|
||||
size,
|
||||
mtime: new Date(1000 * mtime),
|
||||
type,
|
||||
linkname,
|
||||
uname,
|
||||
gname,
|
||||
devmajor,
|
||||
devminor,
|
||||
pax: null
|
||||
}
|
||||
}
|
||||
|
||||
function isUSTAR (buf) {
|
||||
return b4a.equals(USTAR_MAGIC, buf.subarray(MAGIC_OFFSET, MAGIC_OFFSET + 6))
|
||||
}
|
||||
|
||||
function isGNU (buf) {
|
||||
return b4a.equals(GNU_MAGIC, buf.subarray(MAGIC_OFFSET, MAGIC_OFFSET + 6)) &&
|
||||
b4a.equals(GNU_VER, buf.subarray(VERSION_OFFSET, VERSION_OFFSET + 2))
|
||||
}
|
||||
|
||||
function clamp (index, len, defaultValue) {
|
||||
if (typeof index !== 'number') return defaultValue
|
||||
index = ~~index // Coerce to integer.
|
||||
if (index >= len) return len
|
||||
if (index >= 0) return index
|
||||
index += len
|
||||
if (index >= 0) return index
|
||||
return 0
|
||||
}
|
||||
|
||||
function toType (flag) {
|
||||
switch (flag) {
|
||||
case 0:
|
||||
return 'file'
|
||||
case 1:
|
||||
return 'link'
|
||||
case 2:
|
||||
return 'symlink'
|
||||
case 3:
|
||||
return 'character-device'
|
||||
case 4:
|
||||
return 'block-device'
|
||||
case 5:
|
||||
return 'directory'
|
||||
case 6:
|
||||
return 'fifo'
|
||||
case 7:
|
||||
return 'contiguous-file'
|
||||
case 72:
|
||||
return 'pax-header'
|
||||
case 55:
|
||||
return 'pax-global-header'
|
||||
case 27:
|
||||
return 'gnu-long-link-path'
|
||||
case 28:
|
||||
case 30:
|
||||
return 'gnu-long-path'
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function toTypeflag (flag) {
|
||||
switch (flag) {
|
||||
case 'file':
|
||||
return 0
|
||||
case 'link':
|
||||
return 1
|
||||
case 'symlink':
|
||||
return 2
|
||||
case 'character-device':
|
||||
return 3
|
||||
case 'block-device':
|
||||
return 4
|
||||
case 'directory':
|
||||
return 5
|
||||
case 'fifo':
|
||||
return 6
|
||||
case 'contiguous-file':
|
||||
return 7
|
||||
case 'pax-header':
|
||||
return 72
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function indexOf (block, num, offset, end) {
|
||||
for (; offset < end; offset++) {
|
||||
if (block[offset] === num) return offset
|
||||
}
|
||||
return end
|
||||
}
|
||||
|
||||
function cksum (block) {
|
||||
let sum = 8 * 32
|
||||
for (let i = 0; i < 148; i++) sum += block[i]
|
||||
for (let j = 156; j < 512; j++) sum += block[j]
|
||||
return sum
|
||||
}
|
||||
|
||||
function encodeOct (val, n) {
|
||||
val = val.toString(8)
|
||||
if (val.length > n) return SEVENS.slice(0, n) + ' '
|
||||
return ZEROS.slice(0, n - val.length) + val + ' '
|
||||
}
|
||||
|
||||
function encodeSizeBin (num, buf, off) {
|
||||
buf[off] = 0x80
|
||||
for (let i = 11; i > 0; i--) {
|
||||
buf[off + i] = num & 0xff
|
||||
num = Math.floor(num / 0x100)
|
||||
}
|
||||
}
|
||||
|
||||
function encodeSize (num, buf, off) {
|
||||
if (num.toString(8).length > 11) {
|
||||
encodeSizeBin(num, buf, off)
|
||||
} else {
|
||||
b4a.write(buf, encodeOct(num, 11), off)
|
||||
}
|
||||
}
|
||||
|
||||
/* Copied from the node-tar repo and modified to meet
|
||||
* tar-stream coding standard.
|
||||
*
|
||||
* Source: https://github.com/npm/node-tar/blob/51b6627a1f357d2eb433e7378e5f05e83b7aa6cd/lib/header.js#L349
|
||||
*/
|
||||
function parse256 (buf) {
|
||||
// first byte MUST be either 80 or FF
|
||||
// 80 for positive, FF for 2's comp
|
||||
let positive
|
||||
if (buf[0] === 0x80) positive = true
|
||||
else if (buf[0] === 0xFF) positive = false
|
||||
else return null
|
||||
|
||||
// build up a base-256 tuple from the least sig to the highest
|
||||
const tuple = []
|
||||
let i
|
||||
for (i = buf.length - 1; i > 0; i--) {
|
||||
const byte = buf[i]
|
||||
if (positive) tuple.push(byte)
|
||||
else tuple.push(0xFF - byte)
|
||||
}
|
||||
|
||||
let sum = 0
|
||||
const l = tuple.length
|
||||
for (i = 0; i < l; i++) {
|
||||
sum += tuple[i] * Math.pow(256, i)
|
||||
}
|
||||
|
||||
return positive ? sum : -1 * sum
|
||||
}
|
||||
|
||||
function decodeOct (val, offset, length) {
|
||||
val = val.subarray(offset, offset + length)
|
||||
offset = 0
|
||||
|
||||
// If prefixed with 0x80 then parse as a base-256 integer
|
||||
if (val[offset] & 0x80) {
|
||||
return parse256(val)
|
||||
} else {
|
||||
// Older versions of tar can prefix with spaces
|
||||
while (offset < val.length && val[offset] === 32) offset++
|
||||
const end = clamp(indexOf(val, 32, offset, val.length), val.length, val.length)
|
||||
while (offset < end && val[offset] === 0) offset++
|
||||
if (end === offset) return 0
|
||||
return parseInt(val.subarray(offset, end).toString(), 8)
|
||||
}
|
||||
}
|
||||
|
||||
function decodeStr (val, offset, length, encoding) {
|
||||
return b4a.toString(val.subarray(offset, indexOf(val, 0, offset, offset + length)), encoding)
|
||||
}
|
||||
|
||||
function addLength (str) {
|
||||
const len = b4a.byteLength(str)
|
||||
let digits = Math.floor(Math.log(len) / Math.log(10)) + 1
|
||||
if (len + digits >= Math.pow(10, digits)) digits++
|
||||
|
||||
return (len + digits) + str
|
||||
}
|
||||
Reference in New Issue
Block a user