From 3968ec0b1c4ed0a7a6eaadf2c8069ce88539887e Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 30 Mar 2021 11:01:37 +0100 Subject: [PATCH] Restrict file creation to workspace --- apps/remix-ide/src/app/files/fileManager.js | 10 +--- .../src/app/files/workspaceFileProvider.js | 16 +++++- .../file-explorer/src/lib/file-explorer.tsx | 49 +++++++++++-------- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index 6ae21450db..2efd5322b0 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -9,7 +9,6 @@ const globalRegistry = require('../../global/registry') const toaster = require('../ui/tooltip') const modalDialogCustom = require('../ui/modal-dialog-custom') const helper = require('../../lib/helper.js') -const path = require('path') /* attach to files event (removed renamed) @@ -59,14 +58,7 @@ class FileManager extends Plugin { } limitPluginScope (path) { - const workspace = this.fileManager.currentWorkspace() - - if (workspace) { - - } else { - - } - + return path.replace(/^\/browser\//, '').replace(/^browser\//, '') // forbids plugin to access the root filesystem } /** diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index fe4e6825cb..e4184685fd 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -1,6 +1,7 @@ 'use strict' const FileProvider = require('./fileProvider') +const path = require('path') class WorkspaceFileProvider extends FileProvider { constructor () { @@ -32,8 +33,19 @@ class WorkspaceFileProvider extends FileProvider { if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace path = super.removePrefix(path) - const ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path) - return ret.replace(/^\/|\/$/g, '') + let ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path) + + ret = ret.replace(/^\/|\/$/g, '') + if (!this.isSubDirectory(this.workspacesPath + '/' + this.workspace, ret)) throw new Error('Cannot read/write to path outside workspace') + return ret + } + + isSubDirectory (parent, child) { + if (!parent) return false + if (parent === child) return true + const relative = path.relative(parent, child) + + return !!relative && relative.split(path.sep)[0] !== '..' } resolveDirectory (path, callback) { diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index ec292017a4..cd04bf89a4 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -314,26 +314,32 @@ export const FileExplorer = (props: FileExplorerProps) => { const createNewFile = (newFilePath: string) => { const fileManager = state.fileManager - if (helper.checkSpecialChars(newFilePath) || helper.checkSlash(newFilePath)) return toast('special characters are not allowed') - helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { - if (error) { - modal('Create File Failed', error, { - label: 'Close', - fn: async () => {} - }, null) - } else { - const createFile = await fileManager.writeFile(newName, '') - - if (!createFile) { - return toast('Failed to create file ' + newName) + try { + helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { + if (error) { + modal('Create File Failed', error, { + label: 'Close', + fn: async () => {} + }, null) } else { - await fileManager.open(newName) - setState(prevState => { - return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } - }) + const createFile = await fileManager.writeFile(newName, '') + + if (!createFile) { + return toast('Failed to create file ' + newName) + } else { + await fileManager.open(newName) + setState(prevState => { + return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } + }) + } } - } - }) + }) + } catch (error) { + return modal('File Creation Failed', error.message, { + label: 'Close', + fn: async () => {} + }, null) + } } const createNewFolder = async (newFolderPath: string) => { @@ -354,8 +360,10 @@ export const FileExplorer = (props: FileExplorerProps) => { return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } }) } catch (e) { - console.log('error: ', e) - toast('Failed to create folder: ' + newFolderPath) + return modal('File Creation Failed', e.message, { + label: 'Close', + fn: async () => {} + }, null) } } @@ -393,7 +401,6 @@ export const FileExplorer = (props: FileExplorerProps) => { fn: () => {} }, null) } else { - if (helper.checkSpecialChars(newPath) || helper.checkSlash(newPath)) throw new Error('special characters are not allowed') await fileManager.rename(oldPath, newPath) } } catch (error) {