From 06f73919bd6d01400853398fbe416f6f04d743b3 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 23 Oct 2020 13:21:37 +0100 Subject: [PATCH] Desktop: Fixed Cut menu item and test units --- CliClient/tests/fsDriver.ts | 19 +++++++++++++++---- .../gui/NoteEditor/utils/contextMenu.ts | 16 ++++++++++------ ReactNativeClient/lib/fs-driver-node.ts | 5 +++-- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CliClient/tests/fsDriver.ts b/CliClient/tests/fsDriver.ts index 2f5257828d..0f0791a6b2 100644 --- a/CliClient/tests/fsDriver.ts +++ b/CliClient/tests/fsDriver.ts @@ -1,14 +1,25 @@ import FsDriverNode from 'lib/fs-driver-node'; +import shim from 'lib/shim'; const { expectThrow } = require('test-utils.js'); +// On Windows, path.resolve is going to convert a path such as +// /tmp/file.txt to c:\tmp\file.txt +function platformPath(path:string) { + if (shim.isWindows()) { + return `C:${path.replace(/\//g, '\\')}`; + } else { + return path; + } +} + describe('fsDriver', function() { it('should resolveRelativePathWithinDir', () => { const fsDriver = new FsDriverNode(); - expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './my/file.txt')).toBe('/test/temp/my/file.txt'); - expect(fsDriver.resolveRelativePathWithinDir('/', './test')).toBe('/test'); - expect(fsDriver.resolveRelativePathWithinDir('/test', 'myfile.txt')).toBe('/test/myfile.txt'); - expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../test.txt')).toBe('/test/temp/test.txt'); + expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './my/file.txt')).toBe(platformPath('/test/temp/my/file.txt')); + expect(fsDriver.resolveRelativePathWithinDir('/', './test')).toBe(platformPath('/test')); + expect(fsDriver.resolveRelativePathWithinDir('/test', 'myfile.txt')).toBe(platformPath('/test/myfile.txt')); + expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../test.txt')).toBe(platformPath('/test/temp/test.txt')); expectThrow(() => fsDriver.resolveRelativePathWithinDir('/test/temp', '../myfile.txt')); expectThrow(() => fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../../test.txt')); diff --git a/ElectronClient/gui/NoteEditor/utils/contextMenu.ts b/ElectronClient/gui/NoteEditor/utils/contextMenu.ts index 170d2ff476..65302d6e8a 100644 --- a/ElectronClient/gui/NoteEditor/utils/contextMenu.ts +++ b/ElectronClient/gui/NoteEditor/utils/contextMenu.ts @@ -43,6 +43,14 @@ async function resourceInfo(options:ContextMenuOptions):Promise { return { resource, resourcePath }; } +function handleCopyToClipboard(options:ContextMenuOptions) { + if (options.textToCopy) { + clipboard.writeText(options.textToCopy); + } else if (options.htmlToCopy) { + clipboard.writeHTML(options.htmlToCopy); + } +} + export function menuItems():ContextMenuItems { return { open: { @@ -88,7 +96,7 @@ export function menuItems():ContextMenuItems { cut: { label: _('Cut'), onAction: async (options:ContextMenuOptions) => { - clipboard.writeText(options.textToCopy); + handleCopyToClipboard(options); options.insertContent(''); }, isActive: (_itemType:ContextMenuItemType, options:ContextMenuOptions) => !options.isReadOnly && (!!options.textToCopy || !!options.htmlToCopy), @@ -96,11 +104,7 @@ export function menuItems():ContextMenuItems { copy: { label: _('Copy'), onAction: async (options:ContextMenuOptions) => { - if (options.textToCopy) { - clipboard.writeText(options.textToCopy); - } else if (options.htmlToCopy) { - clipboard.writeHTML(options.htmlToCopy); - } + handleCopyToClipboard(options); }, isActive: (_itemType:ContextMenuItemType, options:ContextMenuOptions) => !!options.textToCopy || !!options.htmlToCopy, }, diff --git a/ReactNativeClient/lib/fs-driver-node.ts b/ReactNativeClient/lib/fs-driver-node.ts index 650c6744ce..35a1422aed 100644 --- a/ReactNativeClient/lib/fs-driver-node.ts +++ b/ReactNativeClient/lib/fs-driver-node.ts @@ -195,13 +195,14 @@ export default class FsDriverNode extends FsDriverBase { public resolve(path:string) { return require('path').resolve(path); } - + // Resolves the provided relative path to an absolute path within baseDir. The function // also checks that the absolute path is within baseDir, to avoid security issues. // It is expected that baseDir is a safe path (not user-provided). public resolveRelativePathWithinDir(baseDir:string, relativePath:string) { + const resolvedBaseDir = nodeResolve(baseDir); const resolvedPath = nodeResolve(baseDir, relativePath); - if (resolvedPath.indexOf(baseDir) !== 0) throw new Error('Resolved path for relative path "' + relativePath + '" is not within base directory "' + baseDir + '"'); + if (resolvedPath.indexOf(resolvedBaseDir) !== 0) throw new Error(`Resolved path for relative path "${relativePath}" is not within base directory "${baseDir}" (Was resolved to ${resolvedPath})`); return resolvedPath; }