Skip to content

Commit

Permalink
Add support for rar, jar and 7z
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-sexenian committed Jun 11, 2024
1 parent ccae7e2 commit f6624e5
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 1 deletion.
137 changes: 136 additions & 1 deletion dotnet/GxCompress/GXCompressor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
using System.Security;
using GeneXus;
using ICSharpCode.SharpZipLib.Tar;
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Common;

namespace Genexus.Compression
{
public enum CompressionFormat
{
GZIP,
TAR,
ZIP
ZIP,
JAR
}

public class GXCompressor : IGXCompressor
Expand Down Expand Up @@ -48,6 +53,9 @@ public static int CompressFiles(List<string> files, string path, string format)
case CompressionFormat.GZIP:
CompressToGzip(toCompress, path);
return 0;
case CompressionFormat.JAR:
CompressToJar(toCompress, path);
return 0;
}
}
catch (ArgumentException)
Expand Down Expand Up @@ -107,6 +115,15 @@ public static int Decompress(string file, string path)
case "gz":
DecompressGzip(toCompress, path);
return 0;
case "jar":
DecompressJar(toCompress, path);
return 0;
case "7z":
Decompress7z(toCompress, path);
return 0;
case "rar":
DecompressRar(toCompress, path);
return 0;
default:
GXLogging.Error(log, "Unsupported compression format for decompression: {0}", extension);
return -3;
Expand Down Expand Up @@ -391,6 +408,124 @@ private static void DecompressGzip(FileInfo inputFile, string outputPath)
}
}

private static void Decompress7z(FileInfo file, string outputPath)
{
string targetDir = Path.GetFullPath(outputPath);
using (var sevenZFile = SevenZipArchive.Open(file.FullName))
{
foreach (var entry in sevenZFile.Entries)
{
if (!entry.IsDirectory)
{
string resolvedPath = Path.Combine(targetDir, entry.Key);
FileInfo outputFile = new FileInfo(resolvedPath);

if (!outputFile.FullName.StartsWith(targetDir, StringComparison.OrdinalIgnoreCase))
{
throw new IOException("Entry is outside of the target dir: " + entry.Key);
}

Directory.CreateDirectory(outputFile.DirectoryName);

using (var outStream = outputFile.Open(FileMode.Create, FileAccess.Write))
{
entry.WriteTo(outStream);
}
}
else
{
string dirPath = Path.Combine(targetDir, entry.Key);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
}
}
}
}

private static void CompressToJar(FileInfo[] files, string outputPath)
{
using (FileStream outputStream = new FileStream(outputPath, FileMode.Create))
using (ZipArchive jos = new ZipArchive(outputStream, ZipArchiveMode.Create))
{
byte[] buffer = new byte[1024];
foreach (FileInfo file in files)
{
using (FileStream fis = file.OpenRead())
{
ZipArchiveEntry entry = jos.CreateEntry(file.Name);
using (Stream entryStream = entry.Open())
{
int length;
while ((length = fis.Read(buffer, 0, buffer.Length)) > 0)
{
entryStream.Write(buffer, 0, length);
}
}
}
}
}
}

public static void DecompressJar(FileInfo jarFile, string outputPath)
{
if (!jarFile.Exists)
{
throw new IOException("The jar file does not exist.");
}

DirectoryInfo outputDir = new DirectoryInfo(outputPath);
if (!outputDir.Exists)
{
outputDir.Create();
}

using (FileStream jarFileStream = jarFile.OpenRead())
using (ZipArchive jis = new ZipArchive(jarFileStream, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in jis.Entries)
{
string entryPath = Path.Combine(outputPath, entry.FullName);

Check failure

Code scanning / CodeQL

Arbitrary file access during archive extraction ("Zip Slip") High

Unsanitized archive entry, which may contain '..', is used in a
file system operation
.
FileInfo outputFile = new FileInfo(entryPath);

if (entry.FullName.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
if (!Directory.Exists(outputFile.FullName))
{
Directory.CreateDirectory(outputFile.FullName);
}
}
else
{
Directory.CreateDirectory(outputFile.DirectoryName);
using (FileStream fos = new FileStream(outputFile.FullName, FileMode.Create))
{
using (Stream entryStream = entry.Open())
{
entryStream.CopyTo(fos);
}
}
}
}
}
}


public static void DecompressRar(FileInfo rarFile, string destinationPath)
{
using (var archive = RarArchive.Open(rarFile.FullName))
{
foreach (var entry in archive.Entries)
{
if (!entry.IsDirectory)
{
entry.WriteToDirectory(destinationPath, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
}
}
}
}

private static CompressionFormat GetCompressionFormat(string format)
{
try
Expand Down
1 change: 1 addition & 0 deletions dotnet/GxCompress/GxCompress.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.22.0" PrivateAssets="ALL" />
<PackageReference Include="SharpCompress" Version="0.37.2" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
</ItemGroup>

Expand Down

0 comments on commit f6624e5

Please sign in to comment.