From 694fe274982c0a9ad2421c6b226abceae1602c3a Mon Sep 17 00:00:00 2001 From: Oleguer Llopart Date: Tue, 10 Oct 2023 14:59:59 -0700 Subject: [PATCH] Fix: RAR error on extract with files some special chars (Changed unrar to node-unrar-js) --- CHANGELOG.md | 1 + package.json | 2 +- scripts/app.js | 8 +++ scripts/file-manager.js | 136 +++++++++++++--------------------------- 4 files changed, 55 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b89e351bf..4b3514b23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Error opening some images [`8b97435`](https://github.com/ollm/OpenComic/commit/8b974356dfcbb7222bdef5ace604caeda93e4663) - Wrong cache folder in windows causing some bugs [`8b97435`](https://github.com/ollm/OpenComic/commit/dd6facaf67343185fa06b2377fdc64e66ad9090d) - Extract large RAR and ZIP files blocks the app for a while [`adbdced`](https://github.com/ollm/OpenComic/commit/adbdceda278e6184bc477581be9a25b8fc0f166b) +- RAR error on extract with files some special chars (Changed unrar to node-unrar-js) ## [v1.0.0-beta.3](https://github.com/ollm/OpenComic/releases/tag/v1.0.0-beta.3) (09-10-2023) diff --git a/package.json b/package.json index 959fb83e6..abdebfad1 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "sharp": "^0.30.7", "shosho": "^1.4.2", "tar-fs": "^3.0.4", - "unrar": "^0.2.0", + "node-unrar-js": "^2.0.0", "unzipper": "^0.10.14" }, "devDependencies": { diff --git a/scripts/app.js b/scripts/app.js index 255d3e1bd..ba4f51ad9 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -156,6 +156,13 @@ function sleep(ms) }); } +function setImmediate(ms) +{ + return new Promise(function(resolve){ + window.setImmediate(resolve); + }); +} + module.exports = { event: event, eventOff: eventOff, @@ -171,4 +178,5 @@ module.exports = { clientX: clientX, rand: rand, sleep: sleep, + setImmediate: setImmediate, }; \ No newline at end of file diff --git a/scripts/file-manager.js b/scripts/file-manager.js index b4cec323f..222d29e6d 100644 --- a/scripts/file-manager.js +++ b/scripts/file-manager.js @@ -1350,19 +1350,9 @@ var fileCompressed = function(path, _realPath = false) { if(this.rar) return this.rar; - if(unrar === false) unrar = require('unrar'); + if(unrar === false) unrar = require('node-unrar-js'); - let bin = false; - - if(process.platform == 'win32' || process.platform == 'win64') - bin = asarToAsarUnpacked(p.join(appDir, 'unrar/UnRAR.exe')); - else if(process.platform == 'darwin') - bin = asarToAsarUnpacked(p.join(appDir, 'unrar/unrar_MacOSX_10.13.2_64bit')); - - this.rar = new unrar({ - path: this.realPath, - bin: bin, - }); + this.rar = await unrar.createExtractorFromFile({filepath: this.realPath, targetPath: this.tmp}); return this.rar; @@ -1375,36 +1365,30 @@ var fileCompressed = function(path, _realPath = false) { console.time('readRar'); let _this = this; - let rar = await this.openRar(); - - return new Promise(function(resolve, reject) { - - rar.list(async function(error, entries) { - - if(!error) - { - for(let i = 0, len = entries.length; i < len; i++) - { - let entry = entries[i]; - let name = _this.removeTmp(p.normalize(entry.name)); - - files.push({name: name, path: p.join(_this.path, name), folder: (entry.type === 'Directory' ? true : false)}); - _this.setFileStatus(name, {extracted: false}); - } + try + { + let rar = await this.openRar(); + let list = rar.getFileList(); + list = [...list.fileHeaders]; - console.timeEnd('readRar'); + for(let i = 0, len = list.length; i < len; i++) + { + let file = list[i]; + let name = _this.removeTmp(p.normalize(file.name)); - _this.files = _this.filesToMultidimension(files); - resolve(_this.files); - } - else - { - resolve(_this.readIfTypeFromBinaryIsDifferent(error)); - } + files.push({name: name, path: p.join(_this.path, name), folder: !!file.flags.directory}); + _this.setFileStatus(name, {extracted: false}); + } - }); + console.timeEnd('readRar'); - }); + _this.files = _this.filesToMultidimension(files); + return _this.files; + } + catch(error) + { + return _this.readIfTypeFromBinaryIsDifferent(error); + } } @@ -1417,68 +1401,38 @@ var fileCompressed = function(path, _realPath = false) { let only = this.config.only; let _this = this; - let rar = await this.openRar(); - - return new Promise(function(resolve, reject) { - - rar.list(async function(error, entries) { - - if(!error) - { - for(let i = 0, len = entries.length; i < len; i++) - { - let entry = entries[i]; - let name = p.normalize(entry.name); - let extract = !only || only[name] ? true : false; - - if(extract) - { - let path = p.join(_this.tmp, name); - let virtualPath = p.join(_this.path, name); - - if(entry.type === 'Directory') - { - if(!fs.existsSync(path)) - fs.mkdirSync(path); - } - else - { - let folderPath = _this.folderPath(path); - - if(!fs.existsSync(folderPath)) - fs.mkdirSync(folderPath, {recursive: true}); - - _this.setFileStatus(name, {extracted: true}); + try + { + let rar = await this.openRar(); - await new Promise(function(resolve, reject) { - rar.stream(name).on('error', reject).on('end', function() { + let regexp = new RegExp(pregQuote(p.sep, '/'), 'g'); - _this.setProgress(_this.progressIndex++ / len); - _this.whenExtractFile(virtualPath); + for(let i = 0, len = this.config._only.length; i < len; i++) + { + let _name = this.config._only[i]; - resolve(); + let extracted = rar.extract({files: [_name.replace(regexp, '/')]}); + extracted = [...extracted.files]; - }).pipe(fs.createWriteStream(path)); - }); - } - } - } + await app.setImmediate(); - _this.setProgress(1); + let virtualPath = p.join(this.path, _name); - console.timeEnd('extractRar'); + this.setProgress(_this.progressIndex++ / len); + this.setFileStatus(_name, {extracted: true}); + this.whenExtractFile(virtualPath); + } - resolve(); - } - else - { - resolve(_this.extractIfTypeFromBinaryIsDifferent(error)); - } + _this.setProgress(1); - }); + console.timeEnd('extractRar'); - }); - + return; + } + catch(error) + { + return _this.readIfTypeFromBinaryIsDifferent(error); + } }