diff --git a/LICENSE b/LICENSE index 32ae3e57..c75242b0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017-2023 Thomas Zoechling (https://www.peakstep.com) +Copyright (c) 2017-2024 Thomas Zoechling (https://www.peakstep.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Sources/ZIPFoundation/Archive+BackingConfiguration.swift b/Sources/ZIPFoundation/Archive+BackingConfiguration.swift index f33aef63..167cbd7c 100644 --- a/Sources/ZIPFoundation/Archive+BackingConfiguration.swift +++ b/Sources/ZIPFoundation/Archive+BackingConfiguration.swift @@ -2,7 +2,7 @@ // Archive+BackingConfiguration.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+Helpers.swift b/Sources/ZIPFoundation/Archive+Helpers.swift index 7a291e47..3b89e0e5 100644 --- a/Sources/ZIPFoundation/Archive+Helpers.swift +++ b/Sources/ZIPFoundation/Archive+Helpers.swift @@ -2,7 +2,7 @@ // Archive+Helpers.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+MemoryFile.swift b/Sources/ZIPFoundation/Archive+MemoryFile.swift index b49542c6..8d01536f 100644 --- a/Sources/ZIPFoundation/Archive+MemoryFile.swift +++ b/Sources/ZIPFoundation/Archive+MemoryFile.swift @@ -2,7 +2,7 @@ // Archive+MemoryFile.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+Progress.swift b/Sources/ZIPFoundation/Archive+Progress.swift index 416757ad..ec17e9aa 100644 --- a/Sources/ZIPFoundation/Archive+Progress.swift +++ b/Sources/ZIPFoundation/Archive+Progress.swift @@ -2,7 +2,7 @@ // Archive+Progress.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+Reading.swift b/Sources/ZIPFoundation/Archive+Reading.swift index 3dd64b1d..216ad5c7 100644 --- a/Sources/ZIPFoundation/Archive+Reading.swift +++ b/Sources/ZIPFoundation/Archive+Reading.swift @@ -2,7 +2,7 @@ // Archive+Reading.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. @@ -18,10 +18,12 @@ extension Archive { /// - url: The destination file URL. /// - bufferSize: The maximum size of the read buffer and the decompression buffer (if needed). /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - allowUncontainedSymlinks: Optional flag to allow symlinks that point to paths outside the destination. /// - progress: A progress object that can be used to track or cancel the extract operation. /// - Returns: The checksum of the processed content or 0 if the `skipCRC32` flag was set to `true`. /// - Throws: An error if the destination file cannot be written or the entry contains malformed content. - public func extract(_ entry: Entry, to url: URL, bufferSize: Int = defaultReadChunkSize, skipCRC32: Bool = false, + public func extract(_ entry: Entry, to url: URL, bufferSize: Int = defaultReadChunkSize, + skipCRC32: Bool = false, allowUncontainedSymlinks: Bool = false, progress: Progress? = nil) throws -> CRC32 { guard bufferSize > 0 else { throw ArchiveError.invalidBufferSize @@ -30,7 +32,7 @@ extension Archive { var checksum = CRC32(0) switch entry.type { case .file: - guard !fileManager.itemExists(at: url) else { + guard fileManager.itemExists(at: url) == false else { throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: url.path]) } try fileManager.createParentDirectoryStructure(for: url) @@ -49,11 +51,18 @@ extension Archive { checksum = try self.extract(entry, bufferSize: bufferSize, skipCRC32: skipCRC32, progress: progress, consumer: consumer) case .symlink: - guard !fileManager.itemExists(at: url) else { + guard fileManager.itemExists(at: url) == false else { throw CocoaError(.fileWriteFileExists, userInfo: [NSFilePathErrorKey: url.path]) } let consumer = { (data: Data) in guard let linkPath = String(data: data, encoding: .utf8) else { throw ArchiveError.invalidEntryPath } + + let parentURL = url.deletingLastPathComponent() + let isAbsolutePath = (linkPath as NSString).isAbsolutePath + let linkURL = URL(fileURLWithPath: linkPath, relativeTo: isAbsolutePath ? nil : parentURL) + let isContained = allowUncontainedSymlinks || linkURL.isContained(in: parentURL) + guard isContained else { throw ArchiveError.uncontainedSymlink } + try fileManager.createParentDirectoryStructure(for: url) try fileManager.createSymbolicLink(atPath: url.path, withDestinationPath: linkPath) } diff --git a/Sources/ZIPFoundation/Archive+ReadingDeprecated.swift b/Sources/ZIPFoundation/Archive+ReadingDeprecated.swift index 627adf91..85fab9ee 100644 --- a/Sources/ZIPFoundation/Archive+ReadingDeprecated.swift +++ b/Sources/ZIPFoundation/Archive+ReadingDeprecated.swift @@ -2,7 +2,7 @@ // Archive+ReadingDeprecated.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+Writing.swift b/Sources/ZIPFoundation/Archive+Writing.swift index 083b8151..4274face 100644 --- a/Sources/ZIPFoundation/Archive+Writing.swift +++ b/Sources/ZIPFoundation/Archive+Writing.swift @@ -2,7 +2,7 @@ // Archive+Writing.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+WritingDeprecated.swift b/Sources/ZIPFoundation/Archive+WritingDeprecated.swift index 673a5d4c..9dbd2294 100644 --- a/Sources/ZIPFoundation/Archive+WritingDeprecated.swift +++ b/Sources/ZIPFoundation/Archive+WritingDeprecated.swift @@ -2,7 +2,7 @@ // Archive+WritingDeprecated.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive+ZIP64.swift b/Sources/ZIPFoundation/Archive+ZIP64.swift index e97cddf1..f48e8042 100644 --- a/Sources/ZIPFoundation/Archive+ZIP64.swift +++ b/Sources/ZIPFoundation/Archive+ZIP64.swift @@ -2,7 +2,7 @@ // Archive+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Archive.swift b/Sources/ZIPFoundation/Archive.swift index 870419d5..8e79794c 100644 --- a/Sources/ZIPFoundation/Archive.swift +++ b/Sources/ZIPFoundation/Archive.swift @@ -2,7 +2,7 @@ // Archive.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. @@ -90,6 +90,8 @@ public final class Archive: Sequence { case invalidCentralDirectoryEntryCount /// Thrown when an archive does not contain the required End of Central Directory Record. case missingEndOfCentralDirectoryRecord + /// Thrown when an entry contains a symlink pointing to a path outside the destination directory. + case uncontainedSymlink } /// The access mode for an `Archive`. diff --git a/Sources/ZIPFoundation/Data+Compression.swift b/Sources/ZIPFoundation/Data+Compression.swift index 3bee1501..a3d9ae66 100644 --- a/Sources/ZIPFoundation/Data+Compression.swift +++ b/Sources/ZIPFoundation/Data+Compression.swift @@ -2,7 +2,7 @@ // Data+Compression.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Data+CompressionDeprecated.swift b/Sources/ZIPFoundation/Data+CompressionDeprecated.swift index 90bad790..d1ac71c0 100644 --- a/Sources/ZIPFoundation/Data+CompressionDeprecated.swift +++ b/Sources/ZIPFoundation/Data+CompressionDeprecated.swift @@ -2,7 +2,7 @@ // Data+CompressionDeprecated.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Data+Serialization.swift b/Sources/ZIPFoundation/Data+Serialization.swift index 16705f16..f008a9ae 100644 --- a/Sources/ZIPFoundation/Data+Serialization.swift +++ b/Sources/ZIPFoundation/Data+Serialization.swift @@ -2,7 +2,7 @@ // Data+Serialization.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Entry+Serialization.swift b/Sources/ZIPFoundation/Entry+Serialization.swift index a8e360b9..884d747d 100644 --- a/Sources/ZIPFoundation/Entry+Serialization.swift +++ b/Sources/ZIPFoundation/Entry+Serialization.swift @@ -2,7 +2,7 @@ // Entry+Serialization.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Entry+ZIP64.swift b/Sources/ZIPFoundation/Entry+ZIP64.swift index 47b00678..dec18688 100644 --- a/Sources/ZIPFoundation/Entry+ZIP64.swift +++ b/Sources/ZIPFoundation/Entry+ZIP64.swift @@ -2,7 +2,7 @@ // Entry+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/Entry.swift b/Sources/ZIPFoundation/Entry.swift index 58a9ec27..300ab802 100644 --- a/Sources/ZIPFoundation/Entry.swift +++ b/Sources/ZIPFoundation/Entry.swift @@ -2,7 +2,7 @@ // Entry.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Sources/ZIPFoundation/FileManager+ZIP.swift b/Sources/ZIPFoundation/FileManager+ZIP.swift index a2f8ecd4..b0bbf9bd 100644 --- a/Sources/ZIPFoundation/FileManager+ZIP.swift +++ b/Sources/ZIPFoundation/FileManager+ZIP.swift @@ -2,7 +2,7 @@ // FileManager+ZIP.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. @@ -87,10 +87,12 @@ extension FileManager { /// - sourceURL: The file URL pointing to an existing ZIP file. /// - destinationURL: The file URL that identifies the destination directory of the unzip operation. /// - skipCRC32: Optional flag to skip calculation of the CRC32 checksum to improve performance. + /// - allowUncontainedSymlinks: Optional flag to allow symlinks that point to paths outside the destination. /// - progress: A progress object that can be used to track or cancel the unzip operation. /// - pathEncoding: Encoding for entry paths. Overrides the encoding specified in the archive. /// - Throws: Throws an error if the source item does not exist or the destination URL is not writable. - public func unzipItem(at sourceURL: URL, to destinationURL: URL, skipCRC32: Bool = false, + public func unzipItem(at sourceURL: URL, to destinationURL: URL, + skipCRC32: Bool = false, allowUncontainedSymlinks: Bool = false, progress: Progress? = nil, pathEncoding: String.Encoding? = nil) throws { let fileManager = FileManager() guard fileManager.itemExists(at: sourceURL) else { @@ -114,9 +116,12 @@ extension FileManager { if let progress = progress { let entryProgress = archive.makeProgressForReading(entry) progress.addChild(entryProgress, withPendingUnitCount: entryProgress.totalUnitCount) - crc32 = try archive.extract(entry, to: entryURL, skipCRC32: skipCRC32, progress: entryProgress) + crc32 = try archive.extract(entry, to: entryURL, + skipCRC32: skipCRC32, allowUncontainedSymlinks: allowUncontainedSymlinks, + progress: entryProgress) } else { - crc32 = try archive.extract(entry, to: entryURL, skipCRC32: skipCRC32) + crc32 = try archive.extract(entry, to: entryURL, + skipCRC32: skipCRC32, allowUncontainedSymlinks: allowUncontainedSymlinks) } func verifyChecksumIfNecessary() throws { diff --git a/Sources/ZIPFoundation/URL+ZIP.swift b/Sources/ZIPFoundation/URL+ZIP.swift index bc2febbb..40aa4c62 100644 --- a/Sources/ZIPFoundation/URL+ZIP.swift +++ b/Sources/ZIPFoundation/URL+ZIP.swift @@ -2,7 +2,7 @@ // URL+ZIP.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/Resources/testUnzipUncontainedSymlink.zip b/Tests/ZIPFoundationTests/Resources/testUnzipUncontainedSymlink.zip new file mode 100644 index 00000000..17186121 Binary files /dev/null and b/Tests/ZIPFoundationTests/Resources/testUnzipUncontainedSymlink.zip differ diff --git a/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests+ZIP64.swift index 74863e1a..32f29d37 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationArchiveTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests.swift index 41cae616..40873b1b 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationArchiveTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationErrorConditionTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationDataSerializationTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationDataSerializationTests.swift index b9fac178..f8df5c77 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationDataSerializationTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationDataSerializationTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationDataSerializationTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationEntryTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationEntryTests+ZIP64.swift index 96f92f99..ea0e7a52 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationEntryTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationEntryTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationEntryTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationEntryTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationEntryTests.swift index 0c0ef3c9..c19fa182 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationEntryTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationEntryTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationEntryTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests+ZIP64.swift index 2c1ef156..e77eedbd 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationErrorConditionTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests.swift index 1ab713fc..b0f90355 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationErrorConditionTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationErrorConditionTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationFileAttributeTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationFileAttributeTests.swift index 6e496c04..c0927825 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationFileAttributeTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationFileAttributeTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationFileAttributeTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests+ZIP64.swift index b24b1ff9..36d77e69 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationFileManagerTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests.swift index 251e26fd..a2c13514 100755 --- a/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationFileManagerTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationFileManagerTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. @@ -97,7 +97,7 @@ extension ZIPFoundationTests { for entry in archive { let directoryURL = destinationURL.appendingPathComponent(entry.path) itemsExist = fileManager.itemExists(at: directoryURL) - if !itemsExist { break } + if itemsExist == false { break } } XCTAssert(itemsExist) } @@ -142,6 +142,26 @@ extension ZIPFoundationTests { throws: Archive.ArchiveError.missingEndOfCentralDirectoryRecord) } + func testUnzipUncontainedSymlink() throws { + let fileManager = FileManager() + let archive = self.archive(for: #function, mode: .read) + let destinationURL = self.createDirectory(for: #function) + XCTAssertSwiftError(try fileManager.unzipItem(at: archive.url, to: destinationURL), + throws: Archive.ArchiveError.uncontainedSymlink) + + var linkArchiveURL = ZIPFoundationTests.tempZipDirectoryURL + linkArchiveURL.appendPathComponent(self.archiveName(for: #function)) + let linkURL = linkArchiveURL.deletingLastPathComponent() + let linkTarget = linkURL.path + let linkArchive = try XCTUnwrap(try? Archive(url: linkArchiveURL, accessMode: .create)) + try? linkArchive.addEntry(with: "link", type: .symlink, uncompressedSize: Int64(4), + provider: { (_, _) -> Data in + return linkTarget.data(using: .utf8) ?? Data() + }) + try? fileManager.unzipItem(at: linkArchiveURL, to: destinationURL, allowUncontainedSymlinks: true) + XCTAssert(fileManager.itemExists(at: destinationURL.appendingPathComponent("link"))) + } + // On Darwin platforms, we want the same behavior as the system-provided ZIP utilities. // On the Mac, this includes the graphical Archive Utility as well as the `ditto` // command line tool. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationMemoryTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationMemoryTests.swift index 3fbecec6..7f8c1314 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationMemoryTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationMemoryTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationMemoryTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationPerformanceTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationPerformanceTests.swift index ad83e070..7160d580 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationPerformanceTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationPerformanceTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationPerformanceTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationProgressTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationProgressTests.swift index de182994..a582538c 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationProgressTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationProgressTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationProgressTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationReadingTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationReadingTests+ZIP64.swift index be34d366..89c01fa6 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationReadingTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationReadingTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationReadingTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationReadingTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationReadingTests.swift index a7d25d39..c7eed563 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationReadingTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationReadingTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationReadingTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationTests.swift index c78b6ecb..6c244617 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. @@ -258,6 +258,7 @@ extension ZIPFoundationTests { ("testUnzipItem", testUnzipItem), ("testUnzipItemWithPreferredEncoding", testUnzipItemWithPreferredEncoding), ("testUnzipItemErrorConditions", testUnzipItemErrorConditions), + ("testUnzipUncontainedSymlink", testUnzipUncontainedSymlink), ("testZipItem", testZipItem), ("testLinuxTestSuiteIncludesAllTests", testLinuxTestSuiteIncludesAllTests) ] + zip64Tests + darwinOnlyTests + swift5OnlyTests diff --git a/Tests/ZIPFoundationTests/ZIPFoundationWritingTests+ZIP64.swift b/Tests/ZIPFoundationTests/ZIPFoundationWritingTests+ZIP64.swift index d2acff1a..e75f3e3c 100644 --- a/Tests/ZIPFoundationTests/ZIPFoundationWritingTests+ZIP64.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationWritingTests+ZIP64.swift @@ -2,7 +2,7 @@ // ZIPFoundationWritingTests+ZIP64.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information. diff --git a/Tests/ZIPFoundationTests/ZIPFoundationWritingTests.swift b/Tests/ZIPFoundationTests/ZIPFoundationWritingTests.swift index cdf81641..66b72d0d 100755 --- a/Tests/ZIPFoundationTests/ZIPFoundationWritingTests.swift +++ b/Tests/ZIPFoundationTests/ZIPFoundationWritingTests.swift @@ -2,7 +2,7 @@ // ZIPFoundationWritingTests.swift // ZIPFoundation // -// Copyright © 2017-2023 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. +// Copyright © 2017-2024 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors. // Released under the MIT License. // // See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information.