Parcourir la source

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

Book Pauk il y a 5 ans
Parent
commit
639f726c83

+ 22 - 4
server/core/FileDecompressor.js

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

+ 2 - 2
server/core/Reader/ReaderWorker.js

@@ -27,8 +27,8 @@ class ReaderWorker {
             fs.ensureDirSync(this.config.tempPublicDir);
             fs.ensureDirSync(this.config.tempPublicDir);
 
 
             this.workerState = new WorkerState();
             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.bookConverter = new BookConverter(this.config);
 
 
             this.remoteWebDavStorage = false;
             this.remoteWebDavStorage = false;

+ 10 - 1
server/core/ZipStreamer.js

@@ -52,7 +52,7 @@ class ZipStreamer {
         })().catch(reject); });
         })().catch(reject); });
     }
     }
 
 
-    unpack(zipFile, outputDir, entryCallback) {
+    unpack(zipFile, outputDir, entryCallback, limitFileSize = 0) {
         return new Promise((resolve, reject) => {
         return new Promise((resolve, reject) => {
             entryCallback = (entryCallback ? entryCallback : () => {});
             entryCallback = (entryCallback ? entryCallback : () => {});
             const unzip = new unzipStream({file: zipFile});
             const unzip = new unzipStream({file: zipFile});
@@ -67,6 +67,15 @@ class ZipStreamer {
             });
             });
 
 
             unzip.on('ready', () => {
             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) => {
                 unzip.extract(null, outputDir, (err) => {
                     if (err) reject(err);
                     if (err) reject(err);
                     unzip.close();
                     unzip.close();