From a99c193cf2d783308a0777e6c6ee606590bfa263 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 1 Dec 2015 11:57:32 -0400 Subject: [PATCH] :checkered_flag: Preserve file extension when extracting from asar Currently, when calling `copyFileOut`, the original extension from the file is lost, and a generic `*.tmp` is added instead. This becomes problematic in the scenario where we use `child_process.execFile` on a Windows Batch script that lives inside the `asar` package. Windows relies on the extension being present in order to interpret the script accordingly, which results in the following bug because the operating system doesn't know what do to with this `*.tmp` file: ``` Error: spawn UNKNOWN ``` Steps to reproduce: 1. Create a dummy batch script (test.bat): ``` @echo off echo "Hello world" ``` 2. Create an electron app that attemps to call this script with `child_process.execFile`: ```js var child_process = require('child_process'); var path = require('path'); child_process.execFile(path.join(__dirname, 'test.bat'), function(error, stdout) { if (error) throw error; console.log(stdout); }); ``` 3. Package this small application as an asar archive: ```sh > asar pack mytestapp app.asar ``` 4. Execute the application: ```sh > electron.exe app.asar ``` --- atom/common/asar/archive.cc | 3 ++- atom/common/asar/scoped_temporary_file.cc | 14 +++++++++++--- atom/common/asar/scoped_temporary_file.h | 8 +++++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index ab93e301b1ab..ebb80cc2c485 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -272,7 +272,8 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { } scoped_ptr temp_file(new ScopedTemporaryFile); - if (!temp_file->InitFromFile(&file_, info.offset, info.size)) + base::FilePath::StringType ext = path.Extension(); + if (!temp_file->InitFromFile(&file_, ext, info.offset, info.size)) return false; #if defined(OS_POSIX) diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 6fccc9434fdb..2cc51991e185 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -28,20 +28,28 @@ ScopedTemporaryFile::~ScopedTemporaryFile() { } } -bool ScopedTemporaryFile::Init() { +bool ScopedTemporaryFile::Init(const base::FilePath::StringType ext) { if (!path_.empty()) return true; base::ThreadRestrictions::ScopedAllowIO allow_io; - return base::CreateTemporaryFile(&path_); + + base::FilePath temporaryPath_; + if (!base::CreateTemporaryFile(&temporaryPath_)) { + return false; + } + + path_ = temporaryPath_.AddExtension(ext); + return base::Move(temporaryPath_, path_); } bool ScopedTemporaryFile::InitFromFile(base::File* src, + const base::FilePath::StringType ext, uint64 offset, uint64 size) { if (!src->IsValid()) return false; - if (!Init()) + if (!Init(ext)) return false; std::vector buf(size); diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index ffaee22e514e..c0804a4e6e5f 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -22,11 +22,13 @@ class ScopedTemporaryFile { ScopedTemporaryFile(); virtual ~ScopedTemporaryFile(); - // Init an empty temporary file. - bool Init(); + // Init an empty temporary file with a certain extension. + bool Init(const base::FilePath::StringType ext); // Init an temporary file and fill it with content of |path|. - bool InitFromFile(base::File* src, uint64 offset, uint64 size); + bool InitFromFile(base::File* src, + const base::FilePath::StringType ext, + uint64 offset, uint64 size); base::FilePath path() const { return path_; }