Skip to content

Commit

Permalink
Cli: Fixes laurent22#5341: Ignore newline between quotes while spliti…
Browse files Browse the repository at this point in the history
…ng batch (laurent22#5540)
  • Loading branch information
kkoyung authored and runchard committed Oct 17, 2021
1 parent c833aff commit eac8ef6
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
5 changes: 3 additions & 2 deletions packages/app-cli/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Tag = require('@joplin/lib/models/Tag').default;
const Setting = require('@joplin/lib/models/Setting').default;
const { reg } = require('@joplin/lib/registry.js');
const { fileExtension } = require('@joplin/lib/path-utils');
const { splitCommandString } = require('@joplin/lib/string-utils');
const { splitCommandString, splitCommandBatch } = require('@joplin/lib/string-utils');
const { _ } = require('@joplin/lib/locale');
const fs = require('fs-extra');
const { cliUtils } = require('./cli-utils.js');
Expand Down Expand Up @@ -390,7 +390,8 @@ class Application extends BaseApplication {
async commandList(argv) {
if (argv.length && argv[0] === 'batch') {
const commands = [];
const commandLines = (await fs.readFile(argv[1], 'utf-8')).split('\n');
const commandLines = splitCommandBatch(await fs.readFile(argv[1], 'utf-8'));

for (const commandLine of commandLines) {
if (!commandLine.trim()) continue;
const splitted = splitCommandString(commandLine.trim());
Expand Down
23 changes: 23 additions & 0 deletions packages/lib/StringUtils.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-unused-vars */

const { splitCommandBatch } = require('./string-utils');
const StringUtils = require('./string-utils');

describe('StringUtils', function() {
Expand Down Expand Up @@ -53,4 +54,26 @@ describe('StringUtils', function() {
});
}));

it('should split the command batch by newlines not inside quotes', (async () => {
const eol = '\n';
const testCases = [
['',
['']],
['command1',
['command1']],
['command1 arg1 arg2 arg3',
['command1 arg1 arg2 arg3']],
[`command1 arg1 'arg2${eol}continue' arg3`,
[`command1 arg1 'arg2${eol}continue' arg3`]],
[`command1 arg1 'arg2${eol}continue'${eol}command2${eol}command3 'arg1${eol}continue${eol}continue' arg2 arg3`,
[`command1 arg1 'arg2${eol}continue'`, 'command2', `command3 'arg1${eol}continue${eol}continue' arg2 arg3`]],
[`command1 arg\\1 'arg2${eol}continue\\'continue' arg3`,
[`command1 arg\\1 'arg2${eol}continue\\'continue' arg3`]],
];

testCases.forEach((t) => {
expect(splitCommandBatch(t[0])).toEqual(t[1]);
});
}));

});
55 changes: 54 additions & 1 deletion packages/lib/string-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,59 @@ function splitCommandString(command, options = null) {
return args;
}

function splitCommandBatch(commandBatch) {
const commandLines = [];
const eol = '\n';

let state = 'command';
let current = '';
let quote = '';
for (let i = 0; i < commandBatch.length; i++) {
const c = commandBatch[i];

if (state === 'command') {
if (c === eol) {
commandLines.push(current);
current = '';
} else if (c === '"' || c === '\'') {
quote = c;
current += c;
state = 'quoted';
} else if (c === '\\') {
current += c;
if (i + 1 < commandBatch.length) {
current += commandBatch[i + 1];
i++;
}
} else {
current += c;
}
} else if (state === 'quoted') {
if (c === quote) {
quote = '';
current += c;
state = 'command';
} else if (c === '\\') {
current += c;
if (i + 1 < commandBatch.length) {
current += commandBatch[i + 1];
i++;
}
} else {
current += c;
}
}
}
if (current.length > 0) {
commandLines.push(current);
}
if (commandLines.length === 0) {
commandLines.push('');
}

return commandLines;
}

function padLeft(string, length, padString) {
if (!string) return '';

Expand Down Expand Up @@ -307,4 +360,4 @@ function scriptType(s) {
return 'en';
}

module.exports = Object.assign({ formatCssSize, camelCaseToDash, removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString }, stringUtilsCommon);
module.exports = Object.assign({ formatCssSize, camelCaseToDash, removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, splitCommandBatch, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString }, stringUtilsCommon);

0 comments on commit eac8ef6

Please sign in to comment.