From 639f726c837675bd21eedef07e3175251260ac8f Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Sun, 26 Jan 2020 15:17:45 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BB=D0=B8=D0=BC=D0=B8=D1=82=20=D0=BD=D0=B0=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D1=80=D0=B0=D1=81=D0=BF=D0=B0=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/core/FileDecompressor.js | 26 ++++++++++++++++++++++---- server/core/Reader/ReaderWorker.js | 4 ++-- server/core/ZipStreamer.js | 11 ++++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/server/core/FileDecompressor.js b/server/core/FileDecompressor.js index 6460cf46..cc7a4c0f 100644 --- a/server/core/FileDecompressor.js +++ b/server/core/FileDecompressor.js @@ -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); diff --git a/server/core/Reader/ReaderWorker.js b/server/core/Reader/ReaderWorker.js index ab407406..74c7eb2c 100644 --- a/server/core/Reader/ReaderWorker.js +++ b/server/core/Reader/ReaderWorker.js @@ -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; diff --git a/server/core/ZipStreamer.js b/server/core/ZipStreamer.js index 03f59ff5..c761eaa9 100644 --- a/server/core/ZipStreamer.js +++ b/server/core/ZipStreamer.js @@ -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();