public static IEnumerable <string> Extract(string file, string basePath) { // Extract and clean up names string path = Path.Combine(basePath, "A_" + Compare.Hash(Path.GetFileName(file)).Substring(0, 6)); // Create the directory to be used for storing the archives crap Directory.CreateDirectory(path); if (!File.Exists(file)) { throw new FileNotFoundException("Unable to find/access archive (" + file + ")."); } if (!Directory.Exists(path)) { throw new DirectoryNotFoundException("Unable to find/access the created directory (" + path + ")."); } FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 0x1000, useAsync: false); try { ZipArchive zip = new ZipArchive(fs, ZipArchiveMode.Read, leaveOpen: false, entryNameEncoding: System.Text.Encoding.ASCII); if (zip == null) { throw new ArgumentNullException(nameof(zip)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } // Rely on Directory.CreateDirectory for validation of destinationDirectoryName. // Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists: DirectoryInfo di = Directory.CreateDirectory(path); string destinationDirectoryFullPath = di.FullName; foreach (ZipArchiveEntry entry in zip.Entries) { // Handle malformed paths inside of zip if (entry.FullName.EndsWith("/", StringComparison.OrdinalIgnoreCase) || entry.FullName.EndsWith("\\", StringComparison.OrdinalIgnoreCase)) { continue; } string cleanPass = Platform.CleanPath(entry.FullName); string fileName = Path.GetFileName(cleanPass); string pass = cleanPass.TrimEnd(fileName.ToArray <char>()); string fileDestinationPath = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, pass, fileName)); if (!fileDestinationPath.StartsWith(destinationDirectoryFullPath, StringComparison.OrdinalIgnoreCase)) { throw new IOException("ExtractingResultsInOutside"); } // If it is a file: // Create containing directory: Directory.CreateDirectory(Path.GetDirectoryName(fileDestinationPath)); entry.ExtractToFile(fileDestinationPath, overwrite: true); } fs.Dispose(); } catch (Exception e) { fs.Dispose(); Logging.Log.Session.Add("Core.Compression.Extract", e.Message); } // Return files that were extracted return(Platform.GetFiles(path, string.Empty)); }