Skip to content

Commit

Permalink
Improve unsafe path detection
Browse files Browse the repository at this point in the history
  • Loading branch information
GarboMuffin committed May 13, 2024
1 parent 471febd commit f375019
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
8 changes: 4 additions & 4 deletions src-main/l10n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -444,11 +444,11 @@
"developer_comment": "Part of the extension security prompt window"
},
"unsafe-path.title": {
"string": "Invalid file location",
"developer_comment": "Title of alert that appears when someone tries to save project in an 'unsafe' place where their work will be deleted."
"string": "Invalid File Location",
"developer_comment": "Title of alert that appears when someone tries to save project in an 'unsafe' place where their work would end up being deleted."
},
"unsafe-path.details": {
"string": "The file you selected ({file}) is in an internal folder used by {APP_NAME}. Everything in this folder is deleted each time the app updates. You must pick a different path.",
"developer_comment": "Message of alert that appears when someone tries to save project in a folder used internally by the app. {file} is replaced with the path."
"string": "The file you selected ({file}) is in a folder used internally by {APP_NAME}. It is not safe to save projects here as they can be deleted when the app updates. You must choose a different folder.",
"developer_comment": "Message of alert that appears when someone tries to save project in a folder used internally by the app. {file} is replaced with the path and {APP_NAME} with the name of the app."
}
}
65 changes: 59 additions & 6 deletions src-main/windows/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,60 @@ const parseOpenedFile = (file, workingDirectory) => {
return new OpenedFile(TYPE_FILE, path.resolve(workingDirectory, file));
};

/**
* @returns {Array<{path: string; app: string;}>}
*/
const getUnsafePaths = () => {
if (process.platform !== 'win32') {
// This problem doesn't really exist on other platforms
return [];
}

const localPrograms = path.join(app.getPath('home'), 'AppData', 'Local', 'Programs');
const appData = app.getPath('appData');
return [
// Current app, regardless of where it is installed or how modded it is
{
path: path.dirname(app.getPath('exe')),
app: APP_NAME,
},
{
path: path.dirname(app.getPath('userData')),
app: APP_NAME,
},

// TurboWarp Desktop defaults
{
path: path.join(appData, 'turbowarp-desktop'),
app: 'TurboWarp Desktop'
},
{
path: path.join(localPrograms, 'TurboWarp'),
app: 'TurboWarp Desktop'
},

// Scratch Desktop defaults
{
path: path.join(appData, 'Scratch'),
app: 'Scratch Desktop'
},
{
path: path.join(localPrograms, 'Scratch 3'),
app: 'Scratch Desktop'
}
];
};

/**
* @param {string} parent
* @param {string} child
* @returns {boolean}
*/
const isChildPath = (parent, child) => {
const relative = path.relative(parent, child);
return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
};

class EditorWindow extends ProjectRunningWindow {
/**
* @param {OpenedFile|null} file
Expand Down Expand Up @@ -290,17 +344,16 @@ class EditorWindow extends ProjectRunningWindow {

const file = result.filePath;

// Refuse to let people save new projects in our installation directory as it is
// deleted each time the app updates.
const installDir = path.dirname(app.getPath('exe'));
const pathToInstallDir = path.relative(installDir, file);
if (pathToInstallDir && !pathToInstallDir.startsWith('..') && !path.isAbsolute(pathToInstallDir)) {
const unsafePath = getUnsafePaths().find(i => isChildPath(i.path, file));
if (unsafePath) {
// No need to wait for the message box to close
dialog.showMessageBox(this.window, {
type: 'error',
title: APP_NAME,
message: translate('unsafe-path.title'),
detail: translate(`unsafe-path.details`).replace('{APP_NAME}', APP_NAME).replace('{file}', file),
detail: translate(`unsafe-path.details`)
.replace('{APP_NAME}', unsafePath.app)
.replace('{file}', file),
noLink: true
});
return null;
Expand Down

0 comments on commit f375019

Please sign in to comment.