Skip to content

Commit

Permalink
Implement icsharpcode#539
Browse files Browse the repository at this point in the history
  • Loading branch information
HowToDoThis committed Nov 21, 2020
1 parent a1cf337 commit a6d103a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 101 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
using System.IO;

namespace ICSharpCode.SharpZipLib.Core
{
/// <summary>
/// WindowsPathUtils provides simple utilities for handling windows paths.
/// PathUtils provides simple utilities for handling paths.
/// </summary>
public abstract class WindowsPathUtils
public static class PathUtils
{
/// <summary>
/// Initializes a new instance of the <see cref="WindowsPathUtils"/> class.
/// </summary>
internal WindowsPathUtils()
{
}

/// <summary>
/// Remove any path root present in the path
/// </summary>
/// <param name="path">A <see cref="string"/> containing path information.</param>
/// <returns>The path with the root removed if it was present; path otherwise.</returns>
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isnt otherwise checked for validity.</remarks>
/// <remarks>Unlike the <see cref="System.IO.Path"/> class the path isn't otherwise checked for validity.</remarks>
public static string DropPathRoot(string path)
{
string result = path;
Expand All @@ -33,35 +28,48 @@ public static string DropPathRoot(string path)
int elements = 2;

// Scan for two separate elements \\machine\share\restofpath
while ((index <= path.Length) &&
(((path[index] != '\\') && (path[index] != '/')) || (--elements > 0)))
while ((index <= path.Length) && (((path[index] != '\\') && (path[index] != '/')) || (--elements > 0)))
{
index++;
}

index++;

if (index < path.Length)
{
result = path[index..];
}
else
{
result = "";
}
}
}
else if ((path.Length > 1) && (path[1] == ':'))
{
int dropCount = 2;
if ((path.Length > 2) && ((path[2] == '\\') || (path[2] == '/')))
{
dropCount = 3;
}

result = result.Remove(0, dropCount);
}
}

return result;
}

/// <summary>
/// Returns a random file name in the users temporary directory, or in directory of <paramref name="orig"/> if specified
/// </summary>
/// <param name="orig">If specified, used as the base file name for the temporary file</param>
/// <returns>Returns a temporary file name</returns>
public static string GetTempFileName(string orig)
{
string fileName;
var tempPath = Path.GetTempPath();

do
{
fileName = orig == null ? Path.Combine(tempPath, Path.GetRandomFileName()) : $"{orig}.{Path.GetRandomFileName()}";
} while (File.Exists(fileName));

return fileName;
}
}
}
2 changes: 1 addition & 1 deletion src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static string MakeValidName(string name, char replacement)
throw new ArgumentNullException(nameof(name));
}

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

// Drop any leading slashes.
while ((name.Length > 0) && (name[0] == Path.DirectorySeparatorChar))
Expand Down
91 changes: 11 additions & 80 deletions src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ private long TestLocalHeader(ZipEntry entry, HeaderTest tests)
bool testData = (tests & HeaderTest.Extract) != 0;

var entryAbsOffset = offsetOfFirstEntry + entry.Offset;

baseStream_.Seek(entryAbsOffset, SeekOrigin.Begin);
var signature = (int)ReadLEUint();

Expand Down Expand Up @@ -3826,7 +3826,7 @@ private void MakeBytesAvailable()
/// </summary>
/// <param name="zipString">The <see cref="ZipString"/> to convert to a string.</param>
/// <returns>The textual equivalent for the input value.</returns>
static public implicit operator string(ZipString zipString)
public static implicit operator string(ZipString zipString)
{
zipString.MakeTextAvailable();
return zipString.comment_;
Expand Down Expand Up @@ -4463,7 +4463,7 @@ public interface IArchiveStorage
/// <summary>
/// An abstract <see cref="IArchiveStorage"/> suitable for extension by inheritance.
/// </summary>
abstract public class BaseArchiveStorage : IArchiveStorage
public abstract class BaseArchiveStorage : IArchiveStorage
{
#region Constructors

Expand Down Expand Up @@ -4577,18 +4577,8 @@ public DiskArchiveStorage(ZipFile file)
/// <returns>Returns the temporary output stream.</returns>
public override Stream GetTemporaryOutput()
{
if (temporaryName_ != null)
{
temporaryName_ = GetTempFileName(temporaryName_, true);
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
}
else
{
// Determine where to place files based on internal strategy.
// Currently this is always done in system temp directory.
temporaryName_ = Path.GetTempFileName();
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
}
temporaryName_ = PathUtils.GetTempFileName(temporaryName_);
temporaryStream_ = File.Open(temporaryName_, FileMode.OpenOrCreate, FileAccess.Write);

return temporaryStream_;
}
Expand All @@ -4601,20 +4591,19 @@ public override Stream GetTemporaryOutput()
public override Stream ConvertTemporaryToFinal()
{
if (temporaryStream_ == null)
{
throw new ZipException("No temporary stream has been created");
}

string moveTempName = GetTempFileName(fileName_, false);
string moveTempName = PathUtils.GetTempFileName(fileName_);
bool newFileCreated = false;


Stream result;
try
{
temporaryStream_.Dispose();

File.Move(fileName_, moveTempName);
File.Move(temporaryName_, fileName_);

newFileCreated = true;
File.Delete(moveTempName);

Expand Down Expand Up @@ -4645,12 +4634,10 @@ public override Stream MakeTemporaryCopy(Stream stream)
{
stream.Dispose();

temporaryName_ = GetTempFileName(fileName_, true);
temporaryName_ = PathUtils.GetTempFileName(fileName_);
File.Copy(fileName_, temporaryName_, true);

temporaryStream_ = new FileStream(temporaryName_,
FileMode.Open,
FileAccess.ReadWrite);
temporaryStream_ = new FileStream(temporaryName_, FileMode.Open, FileAccess.ReadWrite);
return temporaryStream_;
}

Expand All @@ -4666,18 +4653,12 @@ public override Stream OpenForDirectUpdate(Stream stream)
if ((stream == null) || !stream.CanWrite)
{
if (stream != null)
{
stream.Dispose();
}

result = new FileStream(fileName_,
FileMode.Open,
FileAccess.ReadWrite);
result = new FileStream(fileName_, FileMode.Open, FileAccess.ReadWrite);
}
else
{
result = stream;
}

return result;
}
Expand All @@ -4688,61 +4669,11 @@ public override Stream OpenForDirectUpdate(Stream stream)
public override void Dispose()
{
if (temporaryStream_ != null)
{
temporaryStream_.Dispose();
}
}

#endregion IArchiveStorage Members

#region Internal routines

private static string GetTempFileName(string original, bool makeTempFile)
{
string result = null;

if (original == null)
{
result = Path.GetTempFileName();
}
else
{
int counter = 0;
int suffixSeed = DateTime.Now.Second;

while (result == null)
{
counter += 1;
string newName = string.Format("{0}.{1}{2}.tmp", original, suffixSeed, counter);
if (!File.Exists(newName))
{
if (makeTempFile)
{
try
{
// Try and create the file.
using (FileStream stream = File.Create(newName))
{
}
result = newName;
}
catch
{
suffixSeed = DateTime.Now.Second;
}
}
else
{
result = newName;
}
}
}
}
return result;
}

#endregion Internal routines

#region Instance Fields

private Stream temporaryStream_;
Expand Down
4 changes: 2 additions & 2 deletions src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public string TransformFile(string name)
}

name = name.Replace(@"\", "/");
name = WindowsPathUtils.DropPathRoot(name);
name = PathUtils.DropPathRoot(name);

// Drop any leading and trailing slashes.
name = name.Trim('/');
Expand Down Expand Up @@ -289,7 +289,7 @@ public string TransformFile(string name)
name = name.Replace(@"\", "/");

// Remove the path root.
name = WindowsPathUtils.DropPathRoot(name);
name = PathUtils.DropPathRoot(name);

// Drop any leading and trailing slashes.
name = name.Trim('/');
Expand Down

0 comments on commit a6d103a

Please sign in to comment.