Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 11662db

Browse files
fix #418: File rename can break project file. The SVN AddIn should check if the rename operation is legal before attempting to rename a file.
1 parent ff7b87e commit 11662db

4 files changed

Lines changed: 64 additions & 26 deletions

File tree

src/AddIns/VersionControl/SubversionAddIn/Src/Commands/AutostartCommands.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ void FileRenaming(object sender, FileRenamingEventArgs e)
389389
if (!AddInOptions.AutomaticallyRenameFiles) return;
390390
string fullSource = Path.GetFullPath(e.SourceFile);
391391
if (!CanBeVersionControlledFile(fullSource)) return;
392+
if (!FileHelpers.CheckRenameOrReplacePossible(e)) {
393+
e.Cancel = true;
394+
return;
395+
}
392396
try {
393397
using (SvnClientWrapper client = new SvnClientWrapper()) {
394398
SvnMessageView.HandleNotifications(client);

src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@
366366
<Compile Include="Workbench\DisplayBinding\ISecondaryDisplayBinding.cs" />
367367
<Compile Include="Workbench\FakeXmlViewContent.cs" />
368368
<Compile Include="Workbench\FileChangeWatcher.cs" />
369+
<Compile Include="Workbench\File\FileHelpers.cs" />
369370
<Compile Include="Workbench\File\FileService.cs" />
370371
<Compile Include="Workbench\File\IRecentOpen.cs" />
371372
<Compile Include="Workbench\ICustomizedCommands.cs" />
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
// software and associated documentation files (the "Software"), to deal in the Software
5+
// without restriction, including without limitation the rights to use, copy, modify, merge,
6+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7+
// to whom the Software is furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in all copies or
10+
// substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17+
// DEALINGS IN THE SOFTWARE.
18+
19+
using System;
20+
using System.IO;
21+
using ICSharpCode.Core;
22+
23+
namespace ICSharpCode.SharpDevelop.Workbench
24+
{
25+
/// <summary>
26+
/// Utility/helper methods for IFileService to avoid changing the IFileService interface.
27+
/// </summary>
28+
public static class FileHelpers
29+
{
30+
/// <summary>
31+
/// Checks that the rename/overwrite operation is possible.
32+
/// </summary>
33+
public static bool CheckRenameOrReplacePossible(FileRenameEventArgs e, bool replaceAllowed = false)
34+
{
35+
if (e.IsDirectory && Directory.Exists(e.SourceFile)) {
36+
if (!replaceAllowed && Directory.Exists(e.TargetFile)) {
37+
SD.MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
38+
return false;
39+
}
40+
} else if (File.Exists(e.SourceFile)) {
41+
if (!replaceAllowed && File.Exists(e.TargetFile)) {
42+
SD.MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
43+
return false;
44+
}
45+
}
46+
return true;
47+
}
48+
}
49+
}

src/Main/SharpDevelop/Workbench/FileService.cs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -580,20 +580,12 @@ public bool RenameFile(string oldName, string newName, bool isDirectory)
580580
return false;
581581
if (!eargs.OperationAlreadyDone) {
582582
try {
583-
if (isDirectory && Directory.Exists(oldName)) {
584-
585-
if (Directory.Exists(newName)) {
586-
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
587-
return false;
583+
if (FileHelpers.CheckRenameOrReplacePossible(eargs)) {
584+
if (isDirectory) {
585+
Directory.Move(oldName, newName);
586+
} else {
587+
File.Move(oldName, newName);
588588
}
589-
Directory.Move(oldName, newName);
590-
591-
} else if (File.Exists(oldName)) {
592-
if (File.Exists(newName)) {
593-
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
594-
return false;
595-
}
596-
File.Move(oldName, newName);
597589
}
598590
} catch (Exception e) {
599591
if (isDirectory) {
@@ -624,20 +616,12 @@ public bool CopyFile(string oldName, string newName, bool isDirectory, bool over
624616
return false;
625617
if (!eargs.OperationAlreadyDone) {
626618
try {
627-
if (isDirectory && Directory.Exists(oldName)) {
628-
629-
if (!overwrite && Directory.Exists(newName)) {
630-
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
631-
return false;
632-
}
633-
FileUtility.DeepCopy(oldName, newName, overwrite);
634-
635-
} else if (File.Exists(oldName)) {
636-
if (!overwrite && File.Exists(newName)) {
637-
MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
638-
return false;
619+
if (FileHelpers.CheckRenameOrReplacePossible(eargs, overwrite)) {
620+
if (isDirectory) {
621+
FileUtility.DeepCopy(oldName, newName, overwrite);
622+
} else {
623+
File.Copy(oldName, newName, overwrite);
639624
}
640-
File.Copy(oldName, newName, overwrite);
641625
}
642626
} catch (Exception e) {
643627
if (isDirectory) {

0 commit comments

Comments
 (0)