feat(headers.js): allow unknown formats (#131)
Co-authored-by: Kevin Lindsay <klindsay@surge.solutions>
This commit is contained in:
parent
03edcabc53
commit
b1531cb695
5 changed files with 81 additions and 3 deletions
|
@ -120,7 +120,7 @@ var Extract = function (opts) {
|
||||||
var offset = self._offset
|
var offset = self._offset
|
||||||
var header
|
var header
|
||||||
try {
|
try {
|
||||||
header = self._header = headers.decode(b.slice(0, 512), opts.filenameEncoding)
|
header = self._header = headers.decode(b.slice(0, 512), opts.filenameEncoding, opts.allowUnknownFormat)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
self.emit('error', err)
|
self.emit('error', err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ exports.encode = function (opts) {
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.decode = function (buf, filenameEncoding) {
|
exports.decode = function (buf, filenameEncoding, allowUnknownFormat) {
|
||||||
var typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET
|
var typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET
|
||||||
|
|
||||||
var name = decodeStr(buf, 0, 100, filenameEncoding)
|
var name = decodeStr(buf, 0, 100, filenameEncoding)
|
||||||
|
@ -270,8 +270,10 @@ exports.decode = function (buf, filenameEncoding) {
|
||||||
// 'gnu'/'oldgnu' format. Similar to ustar, but has support for incremental and
|
// 'gnu'/'oldgnu' format. Similar to ustar, but has support for incremental and
|
||||||
// multi-volume tarballs.
|
// multi-volume tarballs.
|
||||||
} else {
|
} else {
|
||||||
|
if (!allowUnknownFormat) {
|
||||||
throw new Error('Invalid tar header: unknown format.')
|
throw new Error('Invalid tar header: unknown format.')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// to support old tar versions that use trailing / to indicate dirs
|
// to support old tar versions that use trailing / to indicate dirs
|
||||||
if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5
|
if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5
|
||||||
|
|
|
@ -679,3 +679,77 @@ test('v7 unsupported', function (t) { // correctly fails to parse v7 tarballs
|
||||||
|
|
||||||
extract.end(fs.readFileSync(fixtures.V7_TAR))
|
extract.end(fs.readFileSync(fixtures.V7_TAR))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('unknown format doesn\'t extract by default', function (t) {
|
||||||
|
t.plan(1)
|
||||||
|
|
||||||
|
var extract = tar.extract()
|
||||||
|
|
||||||
|
extract.on('error', function (err) {
|
||||||
|
t.ok(!!err)
|
||||||
|
extract.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.end(fs.readFileSync(fixtures.UNKNOWN_FORMAT))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('unknown format attempts to extract if allowed', function (t) {
|
||||||
|
t.plan(5)
|
||||||
|
|
||||||
|
var extract = tar.extract({ allowUnknownFormat: true })
|
||||||
|
var noEntries = false
|
||||||
|
|
||||||
|
var onfile1 = function (header, stream, callback) {
|
||||||
|
t.deepEqual(header, {
|
||||||
|
name: 'file-1.txt',
|
||||||
|
mode: parseInt('644', 8),
|
||||||
|
uid: 501,
|
||||||
|
gid: 20,
|
||||||
|
size: 12,
|
||||||
|
mtime: new Date(1387580181000),
|
||||||
|
type: 'file',
|
||||||
|
linkname: null,
|
||||||
|
uname: 'maf',
|
||||||
|
gname: 'staff',
|
||||||
|
devmajor: 0,
|
||||||
|
devminor: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.on('entry', onfile2)
|
||||||
|
stream.pipe(concat(function (data) {
|
||||||
|
t.same(data.toString(), 'i am file-1\n')
|
||||||
|
callback()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
var onfile2 = function (header, stream, callback) {
|
||||||
|
t.deepEqual(header, {
|
||||||
|
name: 'file-2.txt',
|
||||||
|
mode: parseInt('644', 8),
|
||||||
|
uid: 501,
|
||||||
|
gid: 20,
|
||||||
|
size: 12,
|
||||||
|
mtime: new Date(1387580181000),
|
||||||
|
type: 'file',
|
||||||
|
linkname: null,
|
||||||
|
uname: 'maf',
|
||||||
|
gname: 'staff',
|
||||||
|
devmajor: 0,
|
||||||
|
devminor: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
stream.pipe(concat(function (data) {
|
||||||
|
noEntries = true
|
||||||
|
t.same(data.toString(), 'i am file-2\n')
|
||||||
|
callback()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
extract.once('entry', onfile1)
|
||||||
|
|
||||||
|
extract.on('finish', function () {
|
||||||
|
t.ok(noEntries)
|
||||||
|
})
|
||||||
|
|
||||||
|
extract.end(fs.readFileSync(fixtures.UNKNOWN_FORMAT))
|
||||||
|
})
|
||||||
|
|
2
test/fixtures/index.js
vendored
2
test/fixtures/index.js
vendored
|
@ -21,5 +21,7 @@ exports.INCOMPLETE_TAR = path.join(__dirname, 'incomplete.tar')
|
||||||
exports.GNU_TAR = path.join(__dirname, 'gnu.tar')
|
exports.GNU_TAR = path.join(__dirname, 'gnu.tar')
|
||||||
// Created using gnu tar: tar cf gnu-incremental.tar -G --format gnu --owner=myuser:12345 --group=mygroup:67890 test.txt
|
// Created using gnu tar: tar cf gnu-incremental.tar -G --format gnu --owner=myuser:12345 --group=mygroup:67890 test.txt
|
||||||
exports.GNU_INCREMENTAL_TAR = path.join(__dirname, 'gnu-incremental.tar')
|
exports.GNU_INCREMENTAL_TAR = path.join(__dirname, 'gnu-incremental.tar')
|
||||||
|
// Created from multi-file.tar, removing the magic and recomputing the checksum
|
||||||
|
exports.UNKNOWN_FORMAT = path.join(__dirname, 'unknown-format.tar')
|
||||||
// Created using gnu tar: tar cf v7.tar --format v7 test.txt
|
// Created using gnu tar: tar cf v7.tar --format v7 test.txt
|
||||||
exports.V7_TAR = path.join(__dirname, 'v7.tar')
|
exports.V7_TAR = path.join(__dirname, 'v7.tar')
|
||||||
|
|
BIN
test/fixtures/unknown-format.tar
vendored
Normal file
BIN
test/fixtures/unknown-format.tar
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue