Skip to content

Commit afd005b

Browse files
committed
Generate temp filenames in AttributeParser to avoid collisions. Ref #2802
1 parent 8f00b4e commit afd005b

File tree

8 files changed

+57
-13
lines changed

8 files changed

+57
-13
lines changed

RetailCoder.VBE/App.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,27 @@ private static void EnsureLogFolderPathExists()
8181
}
8282
}
8383

84+
private static void EnsureTempPathExists()
85+
{
86+
// This is required by the parser - allow this to throw.
87+
if (!Directory.Exists(ApplicationConstants.RUBBERDUCK_TEMP_PATH))
88+
{
89+
Directory.CreateDirectory(ApplicationConstants.RUBBERDUCK_TEMP_PATH);
90+
}
91+
// The parser swallows the error if deletions fail - clean up any temp files on startup
92+
try
93+
{
94+
foreach (var file in new DirectoryInfo(ApplicationConstants.RUBBERDUCK_TEMP_PATH).GetFiles())
95+
{
96+
file.Delete();
97+
}
98+
}
99+
catch
100+
{
101+
// Yeah, don't care here either.
102+
}
103+
}
104+
84105
private void UpdateLoggingLevel()
85106
{
86107
LogLevelHelper.SetMinimumLogLevel(LogLevel.FromOrdinal(_config.UserSettings.GeneralSettings.MinimumLogLevel));
@@ -89,6 +110,7 @@ private void UpdateLoggingLevel()
89110
public void Startup()
90111
{
91112
EnsureLogFolderPathExists();
113+
EnsureTempPathExists();
92114
LogRubberduckSart();
93115
LoadConfig();
94116
CheckForLegacyIndenterSettings();

RetailCoder.VBE/Common/ApplicationConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ public static class ApplicationConstants
77
{
88
public static readonly string RUBBERDUCK_FOLDER_PATH = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Rubberduck");
99
public static readonly string LOG_FOLDER_PATH = Path.Combine(RUBBERDUCK_FOLDER_PATH, "Logs");
10+
public static readonly string RUBBERDUCK_TEMP_PATH = Path.Combine(Path.GetTempPath(), "Rubberduck");
1011
}
1112
}
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Reflection;
34
using Rubberduck.Parsing.VBA;
45
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
@@ -7,18 +8,22 @@ namespace Rubberduck.Common
78
{
89
public class ModuleExporter : IModuleExporter
910
{
11+
public bool TempFile { get; private set; }
12+
1013
public string ExportPath
1114
{
1215
get
1316
{
14-
var assemblyLocation = Assembly.GetAssembly(typeof(App)).Location;
15-
return Path.GetDirectoryName(assemblyLocation);
17+
return TempFile
18+
? ApplicationConstants.RUBBERDUCK_TEMP_PATH
19+
: Path.GetDirectoryName(Assembly.GetAssembly(typeof(App)).Location);
1620
}
1721
}
1822

19-
public string Export(IVBComponent component)
23+
public string Export(IVBComponent component, bool tempFile = false)
2024
{
21-
return component.ExportAsSourceFile(ExportPath);
25+
TempFile = tempFile;
26+
return component.ExportAsSourceFile(ExportPath, tempFile);
2227
}
2328
}
2429
}

Rubberduck.Parsing/VBA/AttributeParser.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,22 @@ public AttributeParser(IModuleExporter exporter, Func<IVBAPreprocessor> preproce
3232
public IDictionary<Tuple<string, DeclarationType>, Attributes> Parse(IVBComponent component, CancellationToken token)
3333
{
3434
token.ThrowIfCancellationRequested();
35-
var path = _exporter.Export(component);
35+
var path = _exporter.Export(component, true);
3636
if (!File.Exists(path))
3737
{
3838
// a document component without any code wouldn't be exported (file would be empty anyway).
3939
return new Dictionary<Tuple<string, DeclarationType>, Attributes>();
4040
}
4141
var code = File.ReadAllText(path);
42-
File.Delete(path);
42+
try
43+
{
44+
File.Delete(path);
45+
}
46+
catch
47+
{
48+
// Meh.
49+
}
50+
4351
token.ThrowIfCancellationRequested();
4452

4553
var type = component.Type == ComponentType.StandardModule

Rubberduck.Parsing/VBA/IModuleExporter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ namespace Rubberduck.Parsing.VBA
55
public interface IModuleExporter
66
{
77
string ExportPath { get; }
8+
bool TempFile { get; }
89

910
/// <summary>
1011
/// Exports the specified component and returns the path to the created file.
1112
/// </summary>
1213
/// <param name="component">The module to export.</param>
14+
/// <param name="tempFile">True if a unique temp file name should be generated.</param>
1315
/// <returns>Returns a string containing the path and filename of the created file.</returns>
14-
string Export(IVBComponent component);
16+
string Export(IVBComponent component, bool tempFile = false);
1517
}
1618
}

Rubberduck.VBEEditor/SafeComWrappers/Abstract/IVBComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public interface IVBComponent : ISafeComWrapper, IEquatable<IVBComponent>
2020
IWindow DesignerWindow();
2121
void Activate();
2222
void Export(string path);
23-
string ExportAsSourceFile(string folder);
23+
string ExportAsSourceFile(string folder, bool tempFile = false);
2424

2525
IVBProject ParentProject { get; }
2626
}

Rubberduck.VBEEditor/SafeComWrappers/VB6/VBComponent.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,12 @@ public void Export(string path)
128128
/// Exports the component to the folder. The file name matches the component name and file extension is based on the component's type.
129129
/// </summary>
130130
/// <param name="folder">Destination folder for the resulting source file.</param>
131-
public string ExportAsSourceFile(string folder)
131+
/// <param name="tempFile">True if a unique temp file name should be generated. WARNING: filenames generated with this flag are not persisted.</param>
132+
public string ExportAsSourceFile(string folder, bool tempFile = false)
132133
{
133-
var fullPath = Path.Combine(folder, Name + Type.FileExtension());
134+
var fullPath = tempFile
135+
? Path.Combine(folder, Path.GetRandomFileName())
136+
: Path.Combine(folder, Name + Type.FileExtension());
134137
switch (Type)
135138
{
136139
case ComponentType.UserForm:

Rubberduck.VBEEditor/SafeComWrappers/VBA/VBComponent.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,12 @@ public void Export(string path)
124124
/// Exports the component to the folder. The file is name matches the component name and file extension is based on the component's type.
125125
/// </summary>
126126
/// <param name="folder">Destination folder for the resulting source file.</param>
127-
public string ExportAsSourceFile(string folder)
127+
/// <param name="tempFile">True if a unique temp file name should be generated. WARNING: filenames generated with this flag are not persisted.</param>
128+
public string ExportAsSourceFile(string folder, bool tempFile = false)
128129
{
129-
var fullPath = Path.Combine(folder, SafeName + Type.FileExtension());
130+
var fullPath = tempFile
131+
? Path.Combine(folder, Path.GetRandomFileName())
132+
: Path.Combine(folder, SafeName + Type.FileExtension());
130133
switch (Type)
131134
{
132135
case ComponentType.UserForm:

0 commit comments

Comments
 (0)