Zip importing: Handle spaces in filenames correctly

Previously, if a filename of a .conf file inside the zip file
contained spaces, it was not imported.
This commit is contained in:
Roopesh Chander 2018-12-12 16:01:24 +05:30
parent 440073ad9a
commit 964dd8f723
2 changed files with 14 additions and 13 deletions

View File

@ -39,9 +39,9 @@ class ZipArchive {
zipClose(zipFile, nil) zipClose(zipFile, nil)
} }
static func unarchive(url: URL, requiredFileExtensions: [String]) throws -> [(fileName: String, contents: Data)] { static func unarchive(url: URL, requiredFileExtensions: [String]) throws -> [(fileBaseName: String, contents: Data)] {
var results: [(fileName: String, contents: Data)] = [] var results: [(fileBaseName: String, contents: Data)] = []
guard let zipFile = unzOpen64(url.path) else { guard let zipFile = unzOpen64(url.path) else {
throw ZipArchiveError.cantOpenInputZipFile throw ZipArchiveError.cantOpenInputZipFile
@ -72,10 +72,11 @@ class ZipArchive {
throw ZipArchiveError.badArchive throw ZipArchiveError.badArchive
} }
if let fileURL = URL(string: String(cString: fileNameBuffer)), let lastChar = String(cString: fileNameBuffer).suffix(1)
!fileURL.hasDirectoryPath, let isDirectory = (lastChar == "/" || lastChar == "\\")
requiredFileExtensions.contains(fileURL.pathExtension) { let fileURL = URL(fileURLWithFileSystemRepresentation: fileNameBuffer, isDirectory: isDirectory, relativeTo: nil)
if (!isDirectory && requiredFileExtensions.contains(fileURL.pathExtension)) {
var unzippedData = Data() var unzippedData = Data()
var bytesRead: Int32 = 0 var bytesRead: Int32 = 0
repeat { repeat {
@ -88,7 +89,7 @@ class ZipArchive {
unzippedData.append(dataRead) unzippedData.append(dataRead)
} }
} while (bytesRead > 0) } while (bytesRead > 0)
results.append((fileName: fileURL.lastPathComponent, contents: unzippedData)) results.append((fileBaseName: fileURL.deletingPathExtension().lastPathComponent, contents: unzippedData))
} }
guard (unzCloseCurrentFile(zipFile) == UNZ_OK) else { guard (unzCloseCurrentFile(zipFile) == UNZ_OK) else {

View File

@ -17,14 +17,14 @@ enum ZipImporterError: WireGuardAppError {
class ZipImporter { class ZipImporter {
static func importConfigFiles(from url: URL, completion: @escaping (WireGuardResult<[TunnelConfiguration?]>) -> Void) { static func importConfigFiles(from url: URL, completion: @escaping (WireGuardResult<[TunnelConfiguration?]>) -> Void) {
DispatchQueue.global(qos: .userInitiated).async { DispatchQueue.global(qos: .userInitiated).async {
var unarchivedFiles: [(fileName: String, contents: Data)] var unarchivedFiles: [(fileBaseName: String, contents: Data)]
do { do {
unarchivedFiles = try ZipArchive.unarchive(url: url, requiredFileExtensions: ["conf"]) unarchivedFiles = try ZipArchive.unarchive(url: url, requiredFileExtensions: ["conf"])
for (i, unarchivedFile) in unarchivedFiles.enumerated().reversed() { for (i, unarchivedFile) in unarchivedFiles.enumerated().reversed() {
let fileBaseName = URL(string: unarchivedFile.fileName)?.deletingPathExtension().lastPathComponent let fileBaseName = unarchivedFile.fileBaseName
if let trimmedName = fileBaseName?.trimmingCharacters(in: .whitespacesAndNewlines), !trimmedName.isEmpty { let trimmedName = fileBaseName.trimmingCharacters(in: .whitespacesAndNewlines)
unarchivedFiles[i].fileName = trimmedName if (!trimmedName.isEmpty) {
unarchivedFiles[i].fileBaseName = trimmedName
} else { } else {
unarchivedFiles.remove(at: i) unarchivedFiles.remove(at: i)
} }
@ -40,7 +40,7 @@ class ZipImporter {
fatalError() fatalError()
} }
unarchivedFiles.sort { $0.fileName < $1.fileName } unarchivedFiles.sort { $0.fileBaseName < $1.fileBaseName }
var configs = Array<TunnelConfiguration?>(repeating: nil, count: unarchivedFiles.count) var configs = Array<TunnelConfiguration?>(repeating: nil, count: unarchivedFiles.count)
for (i, file) in unarchivedFiles.enumerated() { for (i, file) in unarchivedFiles.enumerated() {
if (i > 0 && file == unarchivedFiles[i - 1]) { if (i > 0 && file == unarchivedFiles[i - 1]) {
@ -49,7 +49,7 @@ class ZipImporter {
guard let fileContents = String(data: file.contents, encoding: .utf8) else { guard let fileContents = String(data: file.contents, encoding: .utf8) else {
continue continue
} }
guard let tunnelConfig = try? WgQuickConfigFileParser.parse(fileContents, name: file.fileName) else { guard let tunnelConfig = try? WgQuickConfigFileParser.parse(fileContents, name: file.fileBaseName) else {
continue continue
} }
configs[i] = tunnelConfig configs[i] = tunnelConfig