Skip to content

Commit e02f83a

Browse files
Ensure unique filenames when downloading email attachments with duplicate names. (#1106)
Fixed issue where email attachments with the same name were overwritten. Now, duplicate filenames are saved as "file (1).ext", "file (2).ext", etc
1 parent adde1ed commit e02f83a

File tree

7 files changed

+43
-40
lines changed

7 files changed

+43
-40
lines changed

dotnet/src/dotnetcore/GxMail/GxMail.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<Compile Include="..\..\dotnetframework\GxMail\Exchange\UserData.cs" Link="Exchange\UserData.cs" />
2626
<Compile Include="..\..\dotnetframework\GxMail\GXInternetConstants.cs" Link="GXInternetConstants.cs" />
2727
<Compile Include="..\..\dotnetframework\GxMail\GXMailException.cs" Link="GXMailException.cs" />
28+
<Compile Include="..\..\dotnetframework\GxMail\GXMailHelper.cs" Link="GXMailHelper.cs" />
2829
<Compile Include="..\..\dotnetframework\GxMail\GXMailMessage.cs" Link="GXMailMessage.cs" />
2930
<Compile Include="..\..\dotnetframework\GxMail\GXMailRecipient.cs" Link="GXMailRecipient.cs" />
3031
<Compile Include="..\..\dotnetframework\GxMail\GXMailRecipientCollection.cs" Link="GXMailRecipientCollection.cs" />

dotnet/src/dotnetframework/GxMail/Exchange/ExchangeSession.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Linq;
44
using System.Net;
5+
using GeneXus.Mail.Util;
56
using Microsoft.Exchange.WebServices.Data;
67
using Microsoft.Identity.Client;
78

@@ -383,8 +384,8 @@ private void FetchEntireMessage(EmailMessage msg, GXMailMessage gxmessage)
383384
if (attach is FileAttachment)
384385
{
385386
FileAttachment fileAttachment = attach as FileAttachment;
386-
string attachFileName = fileAttachment.Name;
387-
string filePath = System.IO.Path.Combine(_attachDir, attachFileName);
387+
string attachFileName = GXMailHelper.FixAndEnsureUniqueFileName(_attachDir, fileAttachment.Name);
388+
string filePath = Path.Combine(_attachDir, attachFileName);
388389
fileAttachment.Load(filePath);
389390
gxmessage.Attachments.addNew(attachFileName);
390391
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.IO;
2+
using GeneXus.Utils;
3+
4+
namespace GeneXus.Mail.Util
5+
{
6+
internal class GXMailHelper
7+
{
8+
internal static string FixAndEnsureUniqueFileName(string attachDir, string name)
9+
{
10+
if (string.IsNullOrEmpty(name))
11+
{
12+
name = Path.GetRandomFileName();
13+
}
14+
int idx = 1;
15+
string nameOri = Path.GetFileNameWithoutExtension(name);
16+
while (File.Exists(Path.Combine(attachDir, name)))
17+
{
18+
name = $"{nameOri} ({idx}).{Path.GetExtension(name)}";
19+
idx = idx + 1;
20+
}
21+
22+
if (Path.Combine(attachDir, name).Length > 200)
23+
{
24+
name = Path.GetRandomFileName().Replace(".", "") + "." + Path.GetExtension(name);
25+
}
26+
return FileUtil.FixFileName(name, attachDir);
27+
}
28+
29+
}
30+
}

dotnet/src/dotnetframework/GxMail/MailMessage.cs

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Text;
77
using System.Text.RegularExpressions;
88
using System.Threading;
9+
using GeneXus.Mail.Util;
910
using GeneXus.Utils;
11+
using Org.Mentalis.Security.Certificates;
1012

1113
namespace GeneXus.Mail.Internals.Pop3
1214
{
@@ -142,19 +144,6 @@ public void ReadEntireMessage()
142144
}
143145
}
144146

145-
private string FixFileName(string AttachDir, string name)
146-
{
147-
if (string.IsNullOrEmpty(name))
148-
{
149-
name = Path.GetRandomFileName();
150-
}
151-
if (Path.Combine(AttachDir, name).Length > 200)
152-
{
153-
name = Path.GetRandomFileName().Replace(".", "") + "." + Path.GetExtension(name);
154-
}
155-
Regex validChars = new Regex(@"[\\\/\*\?\|:<>]");
156-
return validChars.Replace(name, "_");
157-
}
158147

159148
private static void FillMonthList()
160149
{
@@ -319,15 +308,7 @@ private string GetFileName(string path, string name, string contentType)
319308
extension = "." + ExtensionFromContentType(contentType);
320309
}
321310

322-
int idx = 1;
323-
string nameOri = "" + name;
324-
while(File.Exists(path + name + extension))
325-
{
326-
name = nameOri + " (" + idx + ")";
327-
idx = idx + 1;
328-
}
329-
330-
return FixFileName(path, name + extension);
311+
return GXMailHelper.FixAndEnsureUniqueFileName(path, name + extension);
331312
}
332313

333314
private static string ExtensionFromContentType(string contentType)

dotnet/src/dotnetframework/GxMail/POP3SessionOpenPop.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Net.Mail;
55
using System.Reflection;
6+
using GeneXus.Mail.Util;
67
using GeneXus.Utils;
78
using OpenPop.Mime;
89
using OpenPop.Pop3;
@@ -180,7 +181,7 @@ private void ProcessMailAttachments(GXMailMessage gxmessage, List<MessagePart> a
180181

181182
foreach (var attach in attachs)
182183
{
183-
string attachName = FixFileName(AttachDir, attach.FileName);
184+
string attachName = GXMailHelper.FixAndEnsureUniqueFileName(AttachDir, attach.FileName);
184185
if (!string.IsNullOrEmpty(attach.ContentId) && attach.ContentDisposition != null && attach.ContentDisposition.Inline)
185186
{
186187
string cid = "cid:" + attach.ContentId;

dotnet/src/dotnetframework/GxMail/Pop3MailKit.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Security.Authentication;
5+
using GeneXus.Mail.Util;
56
using GeneXus.Utils;
67
using MailKit;
78
using MailKit.Net.Pop3;
@@ -206,14 +207,14 @@ private void ProcessMailAttachments(GXMailMessage gxmessage, MimeMessage msg)
206207

207208
foreach (MimeEntity attach in attachs)
208209
{
209-
string attachName = FixFileName(AttachDir, attach is MessagePart ? attach.ContentDisposition?.FileName : ((MimePart)attach).FileName);
210+
string attachName = GXMailHelper.FixAndEnsureUniqueFileName(AttachDir, attach is MessagePart ? attach.ContentDisposition?.FileName : ((MimePart)attach).FileName);
210211
ProcessMailAttachment(gxmessage, attach, attachName);
211212
}
212213
foreach (MimeEntity attach in msg.BodyParts)
213214
{
214215
if (IsEmbeddedImage(attach, msg))
215216
{
216-
string attachName = FixFileName(AttachDir, attach.ContentDisposition!=null ? attach.ContentDisposition?.FileName : ((MimePart)attach).FileName);
217+
string attachName = GXMailHelper.FixAndEnsureUniqueFileName(AttachDir, attach.ContentDisposition!=null ? attach.ContentDisposition?.FileName : ((MimePart)attach).FileName);
217218
ProcessMailAttachment(gxmessage, attach, attachName);
218219
}
219220
}

dotnet/src/dotnetframework/GxMail/Pop3SessionBase.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,6 @@ protected static void AddHeader(GXMailMessage msg, string key, string value)
103103
}
104104
}
105105

106-
protected string FixFileName(string attachDir, string name)
107-
{
108-
if (string.IsNullOrEmpty(name))
109-
{
110-
name = Path.GetRandomFileName();
111-
}
112-
if (Path.Combine(AttachDir, name).Length > 200)
113-
{
114-
name = Path.GetRandomFileName().Replace(".", "") + "." + Path.GetExtension(name);
115-
}
116-
Regex validChars = new Regex(@"[\\\/\*\?\|:<>]");
117-
return validChars.Replace(name, "_");
118-
}
106+
119107
}
120108
}

0 commit comments

Comments
 (0)