Добавлено декодирование имен файлов при распаковке Zip-архива в случае,

если кодировка имени не дает создать файл на диске
This commit is contained in:
Book Pauk
2020-02-06 20:20:29 +07:00
parent 29082a10e6
commit 950bab3023
4 changed files with 1111 additions and 12 deletions

View File

@@ -3,11 +3,13 @@ const zlib = require('zlib');
const path = require('path');
const unbzip2Stream = require('unbzip2-stream');
const tar = require('tar-fs');
const ZipStreamer = require('./ZipStreamer');
const iconv = require('iconv-lite');
const ZipStreamer = require('./Zip/ZipStreamer');
const appLogger = new (require('./AppLogger'))();//singleton
const utils = require('./utils');
const FileDetector = require('./FileDetector');
const textUtils = require('./Reader/BookConverter/textUtils');
const utils = require('./utils');
class FileDecompressor {
constructor(limitFileSize = 0) {
@@ -114,7 +116,25 @@ class FileDecompressor {
async unZip(filename, outputDir) {
const zip = new ZipStreamer();
return await zip.unpack(filename, outputDir, null, this.limitFileSize);
try {
return await zip.unpack(filename, outputDir, {
limitFileSize: this.limitFileSize,
limitFileCount: 1000
});
} catch (e) {
fs.emptyDir(outputDir);
return await zip.unpack(filename, outputDir, {
limitFileSize: this.limitFileSize,
limitFileCount: 1000,
decodeEntryNameCallback: (nameRaw) => {
const enc = textUtils.getEncodingLite(nameRaw);
if (enc.indexOf('ISO-8859') < 0) {
return iconv.decode(nameRaw, enc);
}
return nameRaw;
}
});
}
}
unBz2(filename, outputDir) {

View File

@@ -3,7 +3,7 @@ const fs = require('fs-extra');
const path = require('path');
const log = new (require('../AppLogger'))().log;//singleton
const ZipStreamer = require('../ZipStreamer');
const ZipStreamer = require('../Zip/ZipStreamer');
const utils = require('../utils');

View File

@@ -2,7 +2,7 @@ const fs = require('fs-extra');
const path = require('path');
const zipStream = require('zip-stream');
const unzipStream = require('node-stream-zip');
const unzipStream = require('./node_stream_zip');
class ZipStreamer {
constructor() {
@@ -52,9 +52,15 @@ class ZipStreamer {
})().catch(reject); });
}
unpack(zipFile, outputDir, entryCallback, limitFileSize = 0) {
unpack(zipFile, outputDir, options, entryCallback) {
return new Promise((resolve, reject) => {
entryCallback = (entryCallback ? entryCallback : () => {});
const {
limitFileSize = 0,
limitFileCount = 0,
decodeEntryNameCallback = false,
} = options;
const unzip = new unzipStream({file: zipFile});
unzip.on('error', reject);
@@ -67,23 +73,41 @@ class ZipStreamer {
});
unzip.on('ready', () => {
if (limitFileSize) {
for (const entry of Object.values(unzip.entries())) {
if (!entry.isDirectory && entry.size > limitFileSize) {
if (limitFileCount || limitFileSize || decodeEntryNameCallback) {
const entries = Object.values(unzip.entries());
if (limitFileCount && entries.length > limitFileCount) {
reject('Слишком много файлов');
return;
}
for (const entry of entries) {
if (limitFileSize && !entry.isDirectory && entry.size > limitFileSize) {
reject('Файл слишком большой');
return;
}
if (decodeEntryNameCallback) {
entry.name = (decodeEntryNameCallback(entry.nameRaw)).toString();
}
}
}
unzip.extract(null, outputDir, (err) => {
if (err) reject(err);
unzip.close();
resolve(files);
if (err) {
reject(err);
return;
}
try {
unzip.close();
resolve(files);
} catch (e) {
reject(e);
}
});
});
});
}
}
module.exports = ZipStreamer;

File diff suppressed because it is too large Load Diff