Добавлен лимит на размер файла при распаковке

This commit is contained in:
Book Pauk
2020-01-26 15:17:45 +07:00
parent 7997c486cf
commit 639f726c83
3 changed files with 34 additions and 7 deletions

View File

@@ -10,8 +10,9 @@ const utils = require('./utils');
const FileDetector = require('./FileDetector');
class FileDecompressor {
constructor() {
constructor(limitFileSize = 0) {
this.detector = new FileDetector();
this.limitFileSize = limitFileSize;
}
async decompressNested(filename, outputDir) {
@@ -113,7 +114,7 @@ class FileDecompressor {
async unZip(filename, outputDir) {
const zip = new ZipStreamer();
return await zip.unpack(filename, outputDir);
return await zip.unpack(filename, outputDir, null, this.limitFileSize);
}
unBz2(filename, outputDir) {
@@ -125,9 +126,16 @@ class FileDecompressor {
}
unTar(filename, outputDir) {
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => { (async() => {
const files = [];
if (this.limitFileSize) {
if ((await fs.stat(filename)).size > this.limitFileSize) {
reject('Файл слишком большой');
return;
}
}
const tarExtract = tar.extract(outputDir, {
map: (header) => {
files.push({path: header.name, size: header.size});
@@ -149,7 +157,7 @@ class FileDecompressor {
});
inputStream.pipe(tarExtract);
});
})().catch(reject); });
}
decompressByStream(stream, filename, outputDir) {
@@ -174,6 +182,16 @@ class FileDecompressor {
});
stream.on('error', reject);
if (this.limitFileSize) {
let readSize = 0;
stream.on('data', (buffer) => {
readSize += buffer.length;
if (readSize > this.limitFileSize)
stream.destroy(new Error('Файл слишком большой'));
});
}
inputStream.on('error', reject);
outputStream.on('error', reject);

View File

@@ -27,8 +27,8 @@ class ReaderWorker {
fs.ensureDirSync(this.config.tempPublicDir);
this.workerState = new WorkerState();
this.down = new FileDownloader();
this.decomp = new FileDecompressor();
this.down = new FileDownloader(config.maxUploadFileSize);
this.decomp = new FileDecompressor(2*config.maxUploadFileSize);
this.bookConverter = new BookConverter(this.config);
this.remoteWebDavStorage = false;

View File

@@ -52,7 +52,7 @@ class ZipStreamer {
})().catch(reject); });
}
unpack(zipFile, outputDir, entryCallback) {
unpack(zipFile, outputDir, entryCallback, limitFileSize = 0) {
return new Promise((resolve, reject) => {
entryCallback = (entryCallback ? entryCallback : () => {});
const unzip = new unzipStream({file: zipFile});
@@ -67,6 +67,15 @@ class ZipStreamer {
});
unzip.on('ready', () => {
if (limitFileSize) {
for (const entry of Object.values(unzip.entries())) {
if (!entry.isDirectory && entry.size > limitFileSize) {
reject('Файл слишком большой');
return;
}
}
}
unzip.extract(null, outputDir, (err) => {
if (err) reject(err);
unzip.close();