Skip to content

Commit bec6e92

Browse files
author
Akos Kitta
committed
fix: disallow nested sketch on save as
Do not wipe source sketch after save as if not a temp Closes #1882 Signed-off-by: Akos Kitta <[email protected]>
1 parent fef3b6a commit bec6e92

File tree

2 files changed

+67
-18
lines changed

2 files changed

+67
-18
lines changed

Diff for: arduino-ide-extension/src/browser/contributions/save-as-sketch.ts

+62-16
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,17 @@ export class SaveAsSketch extends CloudSketchContribution {
7474
if (cloudUri) {
7575
destinationUri = await this.createCloudCopy({ cloudUri, sketch });
7676
} else {
77-
destinationUri = await this.createLocalCopy(sketch, execOnlyIfTemp);
77+
const isTemp = await this.sketchesService.isTemp(sketch);
78+
if (!isTemp) {
79+
// If the current sketch is an ordinary non-temp sketch, do not delete it after the rename.
80+
// https://github.com/arduino/arduino-ide/issues/1882#issuecomment-1427524645
81+
wipeOriginal = false;
82+
}
83+
destinationUri = await this.createLocalCopy(
84+
sketch,
85+
isTemp,
86+
execOnlyIfTemp
87+
);
7888
}
7989
if (!destinationUri) {
8090
return false;
@@ -119,9 +129,9 @@ export class SaveAsSketch extends CloudSketchContribution {
119129

120130
private async createLocalCopy(
121131
sketch: Sketch,
132+
isTemp?: boolean,
122133
execOnlyIfTemp?: boolean
123134
): Promise<string | undefined> {
124-
const isTemp = await this.sketchesService.isTemp(sketch);
125135
if (!isTemp && !!execOnlyIfTemp) {
126136
return undefined;
127137
}
@@ -147,7 +157,7 @@ export class SaveAsSketch extends CloudSketchContribution {
147157
Sketch.toValidSketchFolderName(sketch.name, exists)
148158
);
149159
const defaultPath = await this.fileService.fsPath(defaultUri);
150-
return await this.promptLocalSketchFolderDestination(defaultPath);
160+
return await this.promptLocalSketchFolderDestination(sketch, defaultPath);
151161
}
152162

153163
/**
@@ -156,6 +166,7 @@ export class SaveAsSketch extends CloudSketchContribution {
156166
* or `undefined` if the operation was canceled.
157167
*/
158168
private async promptLocalSketchFolderDestination(
169+
sketch: Sketch,
159170
defaultPath: string
160171
): Promise<string | undefined> {
161172
let sketchFolderDestinationUri: string | undefined;
@@ -174,22 +185,51 @@ export class SaveAsSketch extends CloudSketchContribution {
174185
return undefined;
175186
}
176187
const destinationUri = await this.fileSystemExt.getUri(filePath);
177-
const sketchFolderName = new URI(destinationUri).path.base;
178-
const errorMessage = Sketch.validateSketchFolderName(sketchFolderName);
179-
if (errorMessage) {
188+
// The new location of the sketch cannot be inside the location of current sketch.
189+
// https://github.com/arduino/arduino-ide/issues/1882
190+
let dialogContent: InvalidSketchFolderDialogContent | undefined;
191+
if (new URI(sketch.uri).isEqualOrParent(new URI(destinationUri))) {
192+
dialogContent = {
193+
message: nls.localize(
194+
'arduino/sketch/invalidSketchFolderLocationMessage',
195+
"Invalid sketch folder location: '{0}'",
196+
filePath
197+
),
198+
details: nls.localize(
199+
'arduino/sketch/invalidSketchFolderLocationDetails',
200+
'You cannot save a sketch into a folder inside itself. This would go on forever.'
201+
),
202+
question: nls.localize(
203+
'arduino/sketch/editInvalidSketchFolderLocationQuestion',
204+
'Do you want to try to save the sketch to a different location?'
205+
),
206+
};
207+
}
208+
if (!dialogContent) {
209+
const sketchFolderName = new URI(destinationUri).path.base;
210+
const errorMessage = Sketch.validateSketchFolderName(sketchFolderName);
211+
if (errorMessage) {
212+
dialogContent = {
213+
message: nls.localize(
214+
'arduino/sketch/invalidSketchFolderNameMessage',
215+
"Invalid sketch folder name: '{0}'",
216+
sketchFolderName
217+
),
218+
details: errorMessage,
219+
question: nls.localize(
220+
'arduino/sketch/editInvalidSketchFolderQuestion',
221+
'Do you want to try to save the sketch with a different name?'
222+
),
223+
};
224+
}
225+
}
226+
if (dialogContent) {
180227
const message = `
181-
${nls.localize(
182-
'arduino/sketch/invalidSketchFolderNameTitle',
183-
"Invalid sketch folder name: '{0}'",
184-
sketchFolderName
185-
)}
228+
${dialogContent.message}
186229
187-
${errorMessage}
230+
${dialogContent.details}
188231
189-
${nls.localize(
190-
'arduino/sketch/editInvalidSketchFolderName',
191-
'Do you want to try to save the sketch folder with a different name?'
192-
)}`.trim();
232+
${dialogContent.question}`.trim();
193233
defaultPath = filePath;
194234
const { response } = await remote.dialog.showMessageBox(
195235
remote.getCurrentWindow(),
@@ -257,6 +297,12 @@ ${nls.localize(
257297
}
258298
}
259299

300+
interface InvalidSketchFolderDialogContent {
301+
readonly message: string;
302+
readonly details: string;
303+
readonly question: string;
304+
}
305+
260306
export namespace SaveAsSketch {
261307
export namespace Commands {
262308
export const SAVE_AS_SKETCH: Command = {

Diff for: i18n/en.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,13 @@
411411
"createdArchive": "Created archive '{0}'.",
412412
"doneCompiling": "Done compiling.",
413413
"doneUploading": "Done uploading.",
414-
"editInvalidSketchFolderName": "Do you want to try to save the sketch folder with a different name?",
414+
"editInvalidSketchFolderLocationQuestion": "Do you want to try to save the sketch to a different location?",
415+
"editInvalidSketchFolderQuestion": "Do you want to try to save the sketch with a different name?",
415416
"exportBinary": "Export Compiled Binary",
416417
"invalidCloudSketchName": "The name must start with a letter or number, followed by letters, numbers, dashes, dots and underscores. Maximum length is 36 characters.",
417-
"invalidSketchFolderNameTitle": "Invalid sketch folder name: '{0}'",
418+
"invalidSketchFolderLocationDetails": "You cannot save a sketch into a folder inside itself. This would go on forever.",
419+
"invalidSketchFolderLocationMessage": "Invalid sketch folder location: '{0}'",
420+
"invalidSketchFolderNameMessage": "Invalid sketch folder name: '{0}'",
418421
"invalidSketchName": "The name must start with a letter or number, followed by letters, numbers, dashes, dots and underscores. Maximum length is 63 characters.",
419422
"moving": "Moving",
420423
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",

0 commit comments

Comments
 (0)