From aac5f29f8e2303086a950ed03401ead8f460b465 Mon Sep 17 00:00:00 2001 From: sebastienlorber Date: Thu, 26 May 2022 18:03:57 +0200 Subject: [PATCH] add shellUtils --- .../src/__tests__/shellUtils.test.ts | 19 +++++++++++++++ packages/docusaurus-utils/src/index.ts | 1 + packages/docusaurus-utils/src/shellUtils.ts | 24 +++++++++++++++++++ project-words.txt | 2 ++ 4 files changed, 46 insertions(+) create mode 100644 packages/docusaurus-utils/src/__tests__/shellUtils.test.ts create mode 100644 packages/docusaurus-utils/src/shellUtils.ts diff --git a/packages/docusaurus-utils/src/__tests__/shellUtils.test.ts b/packages/docusaurus-utils/src/__tests__/shellUtils.test.ts new file mode 100644 index 000000000000..3503bffc868c --- /dev/null +++ b/packages/docusaurus-utils/src/__tests__/shellUtils.test.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {escapeShellArg} from '../shellUtils'; + +describe('shellUtils', () => { + it('escapeShellArg', () => { + expect(escapeShellArg('hello')).toBe('hello'); + expect(escapeShellArg('*')).toBe('"*"'); + expect(escapeShellArg('hello world')).toBe('"hello world"'); + expect(escapeShellArg("'hello'")).toBe('"\'hello\'"'); + expect(escapeShellArg('$(pwd)')).toBe('"$(pwd)"'); + expect(escapeShellArg('hello$(pwd)')).toBe('"hello$(pwd)"'); + }); +}); diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index fb2c66435ea2..520f5f73aab2 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -96,6 +96,7 @@ export { createAbsoluteFilePathMatcher, } from './globUtils'; export {getFileLoaderUtils} from './webpackUtils'; +export {escapeShellArg} from './shellUtils'; export { getDataFilePath, getDataFileData, diff --git a/packages/docusaurus-utils/src/shellUtils.ts b/packages/docusaurus-utils/src/shellUtils.ts new file mode 100644 index 000000000000..ca615134ac55 --- /dev/null +++ b/packages/docusaurus-utils/src/shellUtils.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// TODO move from shelljs to execa later? +// Execa is well maintained and widely used +// Even shelljs recommends execa for security / escaping: +// https://github.com/shelljs/shelljs/wiki/Security-guidelines + +const NO_ESCAPE_REGEXP = /^[\w.-]+$/; +const DOUBLE_QUOTES_REGEXP = /"/g; + +// Inspired from Execa escaping function +// https://github.com/sindresorhus/execa/blob/main/lib/command.js#L12 +export function escapeShellArg(arg: string): string { + if (NO_ESCAPE_REGEXP.test(arg)) { + return arg; + } + + return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`; +} diff --git a/project-words.txt b/project-words.txt index 2e029e7f7c3f..9ca37195ee29 100644 --- a/project-words.txt +++ b/project-words.txt @@ -87,6 +87,8 @@ esbuild eslintcache estree evaluable +execa +Execa externalwaiting failfast fbid