Skip to content

Commit

Permalink
fix for laurent22#906, 1) windows paths like C:\a\b weren't accepted …
Browse files Browse the repository at this point in the history
…because backslashes were treated as escape sequences, 2) common paths like C:\Program Files\Foo\Foo.exe weren't accepted because of the space in the path
  • Loading branch information
Ben Fisher committed Oct 31, 2018
1 parent e41896d commit b2a1a4f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 5 deletions.
1 change: 1 addition & 0 deletions CliClient/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ npm test tests-build/services_ResourceService.js
npm test tests-build/urlUtils.js
npm test tests-build/encryption.js
npm test tests-build/services_rest_Api.js
npm test tests-build/StringUtils.js
npm test tests-build/synchronizer.js
51 changes: 51 additions & 0 deletions CliClient/tests/StringUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require('app-module-path').addPath(__dirname);

const { removeDiacritics, escapeFilename, wrap, prepareCmdStringWindows, splitCommandString, padLeft, toTitleCase } = require('lib/string-utils.js');

process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});

describe('StringUtils', function() {

beforeEach(async (done) => {
done();
});

it('adds quotes if whole string is an existing file', async (done) => {
let fnExists = async (fpath) => true;
let ret = await prepareCmdStringWindows('abc def /g', fnExists);
expect(ret).toBe('"abc def /g"');
ret = await prepareCmdStringWindows('abc def', fnExists);
expect(ret).toBe('"abc def"');
ret = await prepareCmdStringWindows('abc "def"', fnExists);
expect(ret).toBe('abc "def"');
ret = await prepareCmdStringWindows('abc', fnExists);
expect(ret).toBe('abc');
done();
});

it('doesn\'t add quotes if whole string is not an existing file', async (done) => {
let fnExists = async (fpath) => false;
let ret = await prepareCmdStringWindows('abc def /g', fnExists);
expect(ret).toBe('abc def /g');
ret = await prepareCmdStringWindows('abc def', fnExists);
expect(ret).toBe('abc def');
ret = await prepareCmdStringWindows('abc "def"', fnExists);
expect(ret).toBe('abc "def"');
ret = await prepareCmdStringWindows('abc', fnExists);
expect(ret).toBe('abc');
done();
});

it('doubles backslashes', async (done) => {
let fnExists = async (fpath) => false;
let ret = await prepareCmdStringWindows('C:\\Program Files\\Foo\\F', fnExists);
expect(ret).toBe('C:\\\\Program Files\\\\Foo\\\\F');
ret = await prepareCmdStringWindows('a/b/ c /d', fnExists);
expect(ret).toBe('a/b/ c /d');
ret = await prepareCmdStringWindows('a\\b c /d', fnExists);
expect(ret).toBe('a\\\\b c /d');
done();
});
});
13 changes: 9 additions & 4 deletions ReactNativeClient/lib/services/ExternalEditWatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const Setting = require('lib/models/Setting');
const { shim } = require('lib/shim');
const chokidar = require('chokidar');
const EventEmitter = require('events');
const { splitCommandString } = require('lib/string-utils');
const { prepareCmdStringWindows, splitCommandString } = require('lib/string-utils');
const spawn = require('child_process').spawn;

class ExternalEditWatcher {
Expand Down Expand Up @@ -123,10 +123,15 @@ class ExternalEditWatcher {
return false;
}

textEditorCommand() {
const editorCommand = Setting.value('editor');
async textEditorCommand() {
let editorCommand = Setting.value('editor');
if (!editorCommand) return null;

if (shim.isWindows()) {
editorCommand = await prepareCmdStringWindows(editorCommand,
(fpath) => shim.fsDriver().exists(fpath));
}

const s = splitCommandString(editorCommand);

const path = s.splice(0, 1);
Expand Down Expand Up @@ -166,7 +171,7 @@ class ExternalEditWatcher {
const filePath = await this.writeNoteToFile_(note);
this.watch(filePath);

const cmd = this.textEditorCommand();
const cmd = await this.textEditorCommand();
if (!cmd) {
bridge().openExternal('file://' + filePath);
} else {
Expand Down
16 changes: 15 additions & 1 deletion ReactNativeClient/lib/string-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@ function wrap(text, indent, width) {
});
}

async function prepareCmdStringWindows(cmd, fnExists) {
// in windows, paths often contain spaces, so
// if there are spaces and the entire string points to an existing file,
// it's probably something like C:\Program Files\Foo\Foo.exe
if (cmd.indexOf(" ") != -1 && cmd.indexOf('"') == -1 && await fnExists(cmd)) {
cmd = '"' + cmd + '"';
}

// in windows, \ usually is a path delim, not an escape sequence
cmd = cmd.replace(/\\/g, '\\\\');

return cmd;
}

function splitCommandString(command) {
let args = [];
let state = "start"
Expand Down Expand Up @@ -210,4 +224,4 @@ function urlDecode(string) {
return decodeURIComponent((string+'').replace(/\+/g, '%20'));
}

module.exports = { removeDiacritics, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase };
module.exports = { removeDiacritics, escapeFilename, wrap, prepareCmdStringWindows, splitCommandString, padLeft, toTitleCase };

0 comments on commit b2a1a4f

Please sign in to comment.