Skip to content

Commit 134b8f4

Browse files
authored
PR #539: Use securely generated random temporary file names
- Use GetRandomFileName() instead of GetTempFileName() - Unify random file name creation into PathUtils - Do not create new random files before use - Rename WindowsPathUtils to PathUtils and make a proper static class
1 parent d0efee0 commit 134b8f4

File tree

4 files changed

+32
-75
lines changed

4 files changed

+32
-75
lines changed

src/ICSharpCode.SharpZipLib/Core/WindowsPathUtils.cs src/ICSharpCode.SharpZipLib/Core/PathUtils.cs

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1+
using System.IO;
2+
13
namespace ICSharpCode.SharpZipLib.Core
24
{
35
/// <summary>
4-
/// WindowsPathUtils provides simple utilities for handling windows paths.
6+
/// PathUtils provides simple utilities for handling paths.
57
/// </summary>
6-
public abstract class WindowsPathUtils
8+
public static class PathUtils
79
{
8-
/// <summary>
9-
/// Initializes a new instance of the <see cref="WindowsPathUtils"/> class.
10-
/// </summary>
11-
internal WindowsPathUtils()
12-
{
13-
}
14-
1510
/// <summary>
1611
/// Remove any path root present in the path
1712
/// </summary>
1813
/// <param name="path">A <see cref="string"/> containing path information.</param>
1914
/// <returns>The path with the root removed if it was present; path otherwise.</returns>
20-
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isnt otherwise checked for validity.</remarks>
15+
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isn't otherwise checked for validity.</remarks>
2116
public static string DropPathRoot(string path)
2217
{
2318
string result = path;
@@ -63,5 +58,25 @@ public static string DropPathRoot(string path)
6358
}
6459
return result;
6560
}
61+
62+
/// <summary>
63+
/// Returns a random file name in the users temporary directory, or in directory of <paramref name="original"/> if specified
64+
/// </summary>
65+
/// <param name="original">If specified, used as the base file name for the temporary file</param>
66+
/// <returns>Returns a temporary file name</returns>
67+
public static string GetTempFileName(string original)
68+
{
69+
string fileName;
70+
var tempPath = Path.GetTempPath();
71+
72+
do
73+
{
74+
fileName = original == null
75+
? Path.Combine(tempPath, Path.GetRandomFileName())
76+
: $"{original}.{Path.GetRandomFileName()}";
77+
} while (File.Exists(fileName));
78+
79+
return fileName;
80+
}
6681
}
6782
}

src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public static string MakeValidName(string name, char replacement)
176176
throw new ArgumentNullException(nameof(name));
177177
}
178178

179-
name = WindowsPathUtils.DropPathRoot(name.Replace("/", Path.DirectorySeparatorChar.ToString()));
179+
name = PathUtils.DropPathRoot(name.Replace("/", Path.DirectorySeparatorChar.ToString()));
180180

181181
// Drop any leading slashes.
182182
while ((name.Length > 0) && (name[0] == Path.DirectorySeparatorChar))

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

+4-62
Original file line numberDiff line numberDiff line change
@@ -4622,18 +4622,8 @@ public DiskArchiveStorage(ZipFile file)
46224622
/// <returns>Returns the temporary output stream.</returns>
46234623
public override Stream GetTemporaryOutput()
46244624
{
4625-
if (temporaryName_ != null)
4626-
{
4627-
temporaryName_ = GetTempFileName(temporaryName_, true);
4628-
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
4629-
}
4630-
else
4631-
{
4632-
// Determine where to place files based on internal strategy.
4633-
// Currently this is always done in system temp directory.
4634-
temporaryName_ = Path.GetTempFileName();
4635-
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
4636-
}
4625+
temporaryName_ = PathUtils.GetTempFileName(temporaryName_);
4626+
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
46374627

46384628
return temporaryStream_;
46394629
}
@@ -4652,7 +4642,7 @@ public override Stream ConvertTemporaryToFinal()
46524642

46534643
Stream result = null;
46544644

4655-
string moveTempName = GetTempFileName(fileName_, false);
4645+
string moveTempName = PathUtils.GetTempFileName(fileName_);
46564646
bool newFileCreated = false;
46574647

46584648
try
@@ -4691,7 +4681,7 @@ public override Stream MakeTemporaryCopy(Stream stream)
46914681
{
46924682
stream.Dispose();
46934683

4694-
temporaryName_ = GetTempFileName(fileName_, true);
4684+
temporaryName_ = PathUtils.GetTempFileName(fileName_);
46954685
File.Copy(fileName_, temporaryName_, true);
46964686

46974687
temporaryStream_ = new FileStream(temporaryName_,
@@ -4741,54 +4731,6 @@ public override void Dispose()
47414731

47424732
#endregion IArchiveStorage Members
47434733

4744-
#region Internal routines
4745-
4746-
private static string GetTempFileName(string original, bool makeTempFile)
4747-
{
4748-
string result = null;
4749-
4750-
if (original == null)
4751-
{
4752-
result = Path.GetTempFileName();
4753-
}
4754-
else
4755-
{
4756-
int counter = 0;
4757-
int suffixSeed = DateTime.Now.Second;
4758-
4759-
while (result == null)
4760-
{
4761-
counter += 1;
4762-
string newName = string.Format("{0}.{1}{2}.tmp", original, suffixSeed, counter);
4763-
if (!File.Exists(newName))
4764-
{
4765-
if (makeTempFile)
4766-
{
4767-
try
4768-
{
4769-
// Try and create the file.
4770-
using (FileStream stream = File.Create(newName))
4771-
{
4772-
}
4773-
result = newName;
4774-
}
4775-
catch
4776-
{
4777-
suffixSeed = DateTime.Now.Second;
4778-
}
4779-
}
4780-
else
4781-
{
4782-
result = newName;
4783-
}
4784-
}
4785-
}
4786-
}
4787-
return result;
4788-
}
4789-
4790-
#endregion Internal routines
4791-
47924734
#region Instance Fields
47934735

47944736
private Stream temporaryStream_;

src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public string TransformFile(string name)
9393
}
9494

9595
name = name.Replace(@"\", "/");
96-
name = WindowsPathUtils.DropPathRoot(name);
96+
name = PathUtils.DropPathRoot(name);
9797

9898
// Drop any leading and trailing slashes.
9999
name = name.Trim('/');
@@ -289,7 +289,7 @@ public string TransformFile(string name)
289289
name = name.Replace(@"\", "/");
290290

291291
// Remove the path root.
292-
name = WindowsPathUtils.DropPathRoot(name);
292+
name = PathUtils.DropPathRoot(name);
293293

294294
// Drop any leading and trailing slashes.
295295
name = name.Trim('/');

0 commit comments

Comments
 (0)