diff --git a/atom.gyp b/atom.gyp index 9d667410523..202a414003f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.35.1', + 'version%': '0.35.2', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 481945b8e89..fb4a2332334 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.35.1 + 0.35.2 CFBundleShortVersionString - 0.35.1 + 0.35.2 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 875727cdaff..773871fd558 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,35,1,0 - PRODUCTVERSION 0,35,1,0 + FILEVERSION 0,35,2,0 + PRODUCTVERSION 0,35,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.35.1" + VALUE "FileVersion", "0.35.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.35.1" + VALUE "ProductVersion", "0.35.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 489118bd70a..4ea7d8c5c36 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -54,7 +54,6 @@ class Archive : public mate::Wrappable { mate::Dictionary dict(isolate, v8::Object::New(isolate)); dict.Set("size", stats.size); dict.Set("offset", stats.offset); - dict.Set("executable", stats.executable); dict.Set("isFile", stats.is_file); dict.Set("isDirectory", stats.is_directory); dict.Set("isLink", stats.is_link); diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 61b22e9013f..ab93e301b1a 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -13,6 +13,7 @@ #include "atom/common/asar/scoped_temporary_file.h" #include "base/files/file.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/pickle.h" #include "base/json/json_reader.h" @@ -96,7 +97,6 @@ bool FillFileInfoWithNode(Archive::FileInfo* info, return false; info->size = static_cast(size); - info->unpacked = false; if (node->GetBoolean("unpacked", &info->unpacked) && info->unpacked) return true; @@ -107,7 +107,6 @@ bool FillFileInfoWithNode(Archive::FileInfo* info, return false; info->offset += header_size; - info->executable = false; node->GetBoolean("executable", &info->executable); return true; @@ -276,6 +275,13 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { if (!temp_file->InitFromFile(&file_, info.offset, info.size)) return false; +#if defined(OS_POSIX) + if (info.executable) { + // chmod a+x temp_file; + base::SetPosixFilePermissions(temp_file->path(), 0755); + } +#endif + *out = temp_file->path(); external_files_.set(path, temp_file.Pass()); return true; diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index fb52c6265d3..de5b9de605a 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -25,7 +25,7 @@ class ScopedTemporaryFile; class Archive { public: struct FileInfo { - FileInfo() : size(0), offset(0) {} + FileInfo() : unpacked(false), executable(false), size(0), offset(0) {} bool unpacked; bool executable; uint32 size; diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 093da7b5c60..b5cc0982d0d 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 35 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/atom/common/lib/asar.coffee b/atom/common/lib/asar.coffee index fba3faed8ce..f7eeceb3f31 100644 --- a/atom/common/lib/asar.coffee +++ b/atom/common/lib/asar.coffee @@ -1,6 +1,5 @@ asar = process.binding 'atom_common_asar' child_process = require 'child_process' -fs = require 'fs' path = require 'path' util = require 'util' @@ -84,11 +83,6 @@ overrideAPISync = (module, name, arg = 0) -> newPath = archive.copyFileOut filePath notFoundError asarPath, filePath unless newPath - stat = archive.stat filePath - - if stat.executable - fs.chmodSync(newPath, 0o755) - arguments[arg] = newPath old.apply this, arguments @@ -108,11 +102,6 @@ overrideAPI = (module, name, arg = 0) -> newPath = archive.copyFileOut filePath return notFoundError asarPath, filePath, callback unless newPath - stat = archive.stat filePath - - if stat.executable - fs.chmodSync(newPath, 0o755) - arguments[arg] = newPath old.apply this, arguments diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index a0f069d7f1c..ab6123bd877 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -46,7 +46,10 @@ The `global-shortcut` module has the following methods: * `callback` Function Registers a global shortcut of `accelerator`. The `callback` is called when -the registered shortcut is pressed by the user. +the registered shortcut is pressed by the user. Returns `true` if the shortcut +`accelerator` was registered, `false` otherwise. For example, the specified +`accelerator` has already been registered by another caller or other native +applications. ### `globalShortcut.isRegistered(accelerator)` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2612d621227..e976b0ddb81 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -499,7 +499,14 @@ win.webContents.on("did-finish-load", function() { * `path` String -Adds the specified path to DevTools workspace. +Adds the specified path to DevTools workspace. Must be used after DevTools +creation: + +```javascript +mainWindow.webContents.on('devtools-opened', function() { + mainWindow.webContents.addWorkSpace(__dirname); +}); +``` ### `webContents.removeWorkSpace(path)` diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md index 45973e49eaa..c6e0ae3c410 100644 --- a/docs/tutorial/application-packaging.md +++ b/docs/tutorial/application-packaging.md @@ -132,6 +132,7 @@ work. This adds a little overhead for those APIs. APIs that requires extra unpacking are: * `child_process.execFile` +* `child_process.execFileSync` * `fs.open` * `fs.openSync` * `process.dlopen` - Used by `require` on native modules @@ -143,6 +144,17 @@ archives is generated by guessing, because those files do not exist on the filesystem. So you should not trust the `Stats` object except for getting file size and checking file type. +### Executing Binaries Inside `asar` Archive + +There are Node APIs that can execute binaries like `child_process.exec`, +`child_process.spawn` and `child_process.execFile`, but only `execFile` is +supported to execute binaries inside `asar` archive. + +This is because `exec` and `spawn` accept `command` instead of `file` as input, +and `command`s are executed under shell. There is no reliable way to determine +whether a command uses a file in asar archive, and even if we do, we can not be +sure whether we can replace the path in command without side effects. + ## Adding Unpacked Files in `asar` Archive As stated above, some Node APIs will unpack the file to filesystem when diff --git a/spec/asar-spec.coffee b/spec/asar-spec.coffee index ad480a58252..af39fa3ec5e 100644 --- a/spec/asar-spec.coffee +++ b/spec/asar-spec.coffee @@ -392,6 +392,22 @@ describe 'asar package', -> done() child.send file + describe 'child_process.execFile', -> + return unless process.platform is 'darwin' + + {execFile, execFileSync} = require 'child_process' + echo = path.join fixtures, 'asar', 'echo.asar', 'echo' + + it 'executes binaries', (done) -> + child = execFile echo, ['test'], (error, stdout) -> + assert.equal error, null + assert.equal stdout, 'test\n' + done() + + it 'execFileSync executes binaries', -> + output = execFileSync echo, ['test'] + assert.equal String(output), 'test\n' + describe 'internalModuleReadFile', -> internalModuleReadFile = process.binding('fs').internalModuleReadFile diff --git a/spec/fixtures/asar/echo.asar b/spec/fixtures/asar/echo.asar new file mode 100644 index 00000000000..4d72f7a92a7 Binary files /dev/null and b/spec/fixtures/asar/echo.asar differ