diff --git a/Cartfile.resolved b/Cartfile.resolved
index 145a4d4..9457c9c 100644
--- a/Cartfile.resolved
+++ b/Cartfile.resolved
@@ -1,3 +1,3 @@
-github "abbeycode/UnrarKit" "2.9"
+github "abbeycode/UnrarKit" "2.10"
github "abbeycode/UnzipKit" "1.9"
github "sindresorhus/DockProgress" "v3.2.0"
diff --git a/Carthage/Build/.DockProgress.version b/Carthage/Build/.DockProgress.version
index ce0bf86..2de2d76 100644
--- a/Carthage/Build/.DockProgress.version
+++ b/Carthage/Build/.DockProgress.version
@@ -2,10 +2,10 @@
"commitish" : "v3.2.0",
"Mac" : [
{
- "hash" : "13e7fe07ca491fe900ae7c858e66797a66d0a2e1dffde3a2c0b64188b211012e",
+ "hash" : "19676367de93b3ec3bc61b60e454d565ca1c47fe32c4116ef78955c7ecdfcd1e",
"name" : "DockProgress",
"linking" : "dynamic",
- "swiftToolchainVersion" : "5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55)"
+ "swiftToolchainVersion" : "5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)"
}
]
}
\ No newline at end of file
diff --git a/Carthage/Build/.UnrarKit.version b/Carthage/Build/.UnrarKit.version
index ba37cb6..672368e 100644
--- a/Carthage/Build/.UnrarKit.version
+++ b/Carthage/Build/.UnrarKit.version
@@ -2,7 +2,7 @@
"Mac" : [
{
"name" : "UnrarKit",
- "hash" : "0ee8db439c431777277ec76976faa8a1d19ba93d3f6977094746350e942215d3",
+ "hash" : "e18e69a1e9f0344776a442bf542e0a45be0427977b765897399058bb766e83db",
"linking" : "dynamic"
}
],
@@ -12,11 +12,11 @@
"tvOS" : [
],
- "commitish" : "2.9",
+ "commitish" : "2.10",
"iOS" : [
{
"name" : "UnrarKit",
- "hash" : "2c752a88c360be277b938f55190d07bc6688ce0452932b4fbf52a12e9bfcf5d0",
+ "hash" : "308b414f23c29d8599f7b214fb8ef39ea574ac8117b21b6946a7c969b9cf38b4",
"linking" : "dynamic"
}
]
diff --git a/Carthage/Build/Mac/DockProgress.framework.dSYM/Contents/Resources/DWARF/DockProgress b/Carthage/Build/Mac/DockProgress.framework.dSYM/Contents/Resources/DWARF/DockProgress
index 5c1abd4..5be8595 100644
Binary files a/Carthage/Build/Mac/DockProgress.framework.dSYM/Contents/Resources/DWARF/DockProgress and b/Carthage/Build/Mac/DockProgress.framework.dSYM/Contents/Resources/DWARF/DockProgress differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/DockProgress b/Carthage/Build/Mac/DockProgress.framework/Versions/A/DockProgress
index 661f474..cd2aa90 100755
Binary files a/Carthage/Build/Mac/DockProgress.framework/Versions/A/DockProgress and b/Carthage/Build/Mac/DockProgress.framework/Versions/A/DockProgress differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Headers/DockProgress-Swift.h b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Headers/DockProgress-Swift.h
index 6c8dac0..16e39b8 100644
--- a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Headers/DockProgress-Swift.h
+++ b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Headers/DockProgress-Swift.h
@@ -1,6 +1,6 @@
#if 0
#elif defined(__arm64__) && __arm64__
-// Generated by Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55)
+// Generated by Apple Swift version 5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)
#ifndef DOCKPROGRESS_SWIFT_H
#define DOCKPROGRESS_SWIFT_H
#pragma clang diagnostic push
@@ -186,6 +186,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#if !defined(IBSegueAction)
# define IBSegueAction
#endif
+#if !defined(SWIFT_EXTERN)
+# if defined(__cplusplus)
+# define SWIFT_EXTERN extern "C"
+# else
+# define SWIFT_EXTERN extern
+# endif
+#endif
#if __has_feature(modules)
#if __has_warning("-Watimport-in-framework-header")
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
@@ -221,7 +228,7 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#endif
#elif defined(__x86_64__) && __x86_64__
-// Generated by Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55)
+// Generated by Apple Swift version 5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)
#ifndef DOCKPROGRESS_SWIFT_H
#define DOCKPROGRESS_SWIFT_H
#pragma clang diagnostic push
@@ -407,6 +414,13 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#if !defined(IBSegueAction)
# define IBSegueAction
#endif
+#if !defined(SWIFT_EXTERN)
+# if defined(__cplusplus)
+# define SWIFT_EXTERN extern "C"
+# else
+# define SWIFT_EXTERN extern
+# endif
+#endif
#if __has_feature(modules)
#if __has_warning("-Watimport-in-framework-header")
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftdoc b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftdoc
index eb5053c..e89e249 100644
Binary files a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftdoc and b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftdoc differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftmodule b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftmodule
index 512a204..fd94511 100644
Binary files a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftmodule and b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/arm64-apple-macos.swiftmodule differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftdoc b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftdoc
index 3d42eac..2efe353 100644
Binary files a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftdoc and b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftdoc differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftmodule b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftmodule
index 71c14e4..4bc7c54 100644
Binary files a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftmodule and b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Modules/DockProgress.swiftmodule/x86_64-apple-macos.swiftmodule differ
diff --git a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Resources/Info.plist b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Resources/Info.plist
index 422ce73..5b1d695 100644
--- a/Carthage/Build/Mac/DockProgress.framework/Versions/A/Resources/Info.plist
+++ b/Carthage/Build/Mac/DockProgress.framework/Versions/A/Resources/Info.plist
@@ -3,7 +3,7 @@
BuildMachineOSBuild
- 20E241
+ 21F5048e
CFBundleExecutable
DockProgress
CFBundleIdentifier
@@ -23,19 +23,19 @@
DTCompiler
com.apple.compilers.llvm.clang.1_0
DTPlatformBuild
- 12E262
+ 13E500a
DTPlatformName
macosx
DTPlatformVersion
- 11.3
+ 12.3
DTSDKBuild
- 20E214
+ 21E226
DTSDKName
- macosx11.3
+ macosx12.3
DTXcode
- 1250
+ 1331
DTXcodeBuild
- 12E262
+ 13E500a
LSMinimumSystemVersion
10.12
diff --git a/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Info.plist b/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Info.plist
index c7fe283..cf0c25f 100644
--- a/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Info.plist
+++ b/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Info.plist
@@ -13,8 +13,8 @@
CFBundleSignature
????
CFBundleShortVersionString
- 2.9
+ 2.10-beta8
CFBundleVersion
- 2.9
+ 2.10-beta8
diff --git a/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit b/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit
index ca76e96..9ee2500 100644
Binary files a/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit and b/Carthage/Build/Mac/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit differ
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKArchive.h b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKArchive.h
index bd064cb..367862d 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKArchive.h
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKArchive.h
@@ -6,14 +6,14 @@
#import
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
@class URKFileInfo;
@@ -25,7 +25,7 @@ DllHppIgnore
typedef NS_ENUM(NSInteger, URKErrorCode) {
/**
- * The archive's header is empty
+ * The last file of the archive has been read
*/
URKErrorCodeEndOfArchive = ERAR_END_ARCHIVE,
@@ -35,7 +35,7 @@ typedef NS_ENUM(NSInteger, URKErrorCode) {
URKErrorCodeNoMemory = ERAR_NO_MEMORY,
/**
- * The header is broken
+ * The header's CRC doesn't match the decompressed data's CRC
*/
URKErrorCodeBadData = ERAR_BAD_DATA,
@@ -173,6 +173,17 @@ extern NSString *URKErrorDomain;
*/
@property(nullable, strong) NSProgress *progress;
+/**
+ * When performing operations on a RAR archive, the contents of compressed files are checked
+ * against the record of what they were when the archive was created. If there's a mismatch,
+ * either the metadata (header) or archive contents have become corrupted. You can defeat this check by
+ * setting this property to YES, though there may be security implications to turning the
+ * warnings off, as it may indicate a maliciously crafted archive intended to exploit a vulnerability.
+ *
+ * It's recommended to leave the decision of how to treat archives with mismatched CRCs to the user
+ */
+@property (assign) BOOL ignoreCRCMismatches;
+
/**
* **DEPRECATED:** Creates and returns an archive at the given path
@@ -475,15 +486,34 @@ extern NSString *URKErrorDomain;
- (BOOL)validatePassword;
/**
- Extract each file in the archive, checking whether the data matches the CRC checksum
- stored at the time it was written
-
- @return YES if the data is all correct, false if any check failed
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header
+
+ @return YES if the data is all correct, false if any check failed (_even if ignoreCRCMismatches is YES_)
*/
- (BOOL)checkDataIntegrity;
/**
- Extract a particular file, to determine if its data matches the CRC
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header. If any file's CRC doesn't match, run the given block
+ to allow the API consumer to decide whether to ignore mismatches. NOTE: This may be a
+ security risk. The block is intended to prompt the user, which is why it's forced onto
+ the main thread, rather than making a design-time decision
+
+ @param ignoreCRCMismatches This block, called on the main thread, allows a consuming API to
+ prompt the user whether or not he'd like to ignore CRC mismatches.
+ This block is called the first time a CRC mismatch is detected, if
+ at all. It won't be called if all CRCs match. If this returns YES,
+ then all further CRC mismatches will be ignored for the
+ archive instance
+
+ @return YES if the data is all correct and/or the block returns YES; returns false if
+ any check failed and the given block also returns NO
+ */
+- (BOOL)checkDataIntegrityIgnoringCRCMismatches:(BOOL(^)(void))ignoreCRCMismatches;
+
+/**
+ Check a particular file, to determine if its data matches the CRC
checksum stored at the time it written
@param filePath The file in the archive to check
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKFileInfo.h b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKFileInfo.h
index 5bf2c95..8cd29fb 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKFileInfo.h
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/URKFileInfo.h
@@ -4,14 +4,14 @@
//
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
/* See http://www.forensicswiki.org/wiki/RAR and
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKit.h b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKit.h
index 78db3b3..d2e390e 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKit.h
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKit.h
@@ -15,5 +15,5 @@ FOUNDATION_EXPORT double UnrarKitVersionNumber;
FOUNDATION_EXPORT const unsigned char UnrarKitVersionString[];
-#import "URKArchive.h"
-#import "URKFileInfo.h"
+#import
+#import
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKitMacros.h b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKitMacros.h
index aea9343..38e466f 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKitMacros.h
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/UnrarKitMacros.h
@@ -60,7 +60,7 @@ __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000 \
#import
// Called from +[UnrarKit initialize] and +[URKArchiveTestCase setUp]
-extern os_log_t unrarkit_log; // Declared in URKArchive.m
+extern os_log_t unrarkit_log; // Declared in URKArchive.mm
extern BOOL unrarkitIsAtLeast10_13SDK; // Declared in URKArchive.m
#define URKLogInit() \
unrarkit_log = os_log_create("com.abbey-code.UnrarKit", "General"); \
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/dll.hpp b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/dll.hpp
index 7f82906..c785ff1 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/dll.hpp
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Headers/dll.hpp
@@ -1,7 +1,7 @@
#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_
-#pragma pack(1)
+#pragma pack(push, 1)
#define ERAR_SUCCESS 0
#define ERAR_END_ARCHIVE 10
@@ -135,6 +135,8 @@ typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM
#define ROADF_ENCHEADERS 0x0080
#define ROADF_FIRSTVOLUME 0x0100
+#define ROADOF_KEEPBROKEN 0x0001
+
struct RAROpenArchiveDataEx
{
char *ArcName;
@@ -148,7 +150,9 @@ struct RAROpenArchiveDataEx
unsigned int Flags;
UNRARCALLBACK Callback;
LPARAM UserData;
- unsigned int Reserved[28];
+ unsigned int OpFlags;
+ wchar_t *CmtBufW;
+ unsigned int Reserved[25];
};
enum UNRARCALLBACK_MESSAGES {
@@ -180,6 +184,6 @@ int PASCAL RARGetDllVersion();
}
#endif
-#pragma pack()
+#pragma pack(pop)
#endif
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/Info.plist b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/Info.plist
index 49d07d6..fbb0c36 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/Info.plist
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/Info.plist
@@ -3,7 +3,7 @@
BuildMachineOSBuild
- 17D47
+ 19H2
CFBundleDevelopmentRegion
English
CFBundleExecutable
@@ -17,7 +17,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.9
+ 2.10-beta8
CFBundleSignature
????
CFBundleSupportedPlatforms
@@ -25,20 +25,24 @@
MacOSX
CFBundleVersion
- 2.9
+ 2.10-beta8
DTCompiler
com.apple.compilers.llvm.clang.1_0
DTPlatformBuild
- 9E145
+ 12A7300
+ DTPlatformName
+ macosx
DTPlatformVersion
- GM
+ 10.15.6
DTSDKBuild
- 17E189
+ 19G68
DTSDKName
- macosx10.13
+ macosx10.15
DTXcode
- 0930
+ 1201
DTXcodeBuild
- 9E145
+ 12A7300
+ LSMinimumSystemVersion
+ 10.15
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/UnrarKitResources.bundle/Contents/Info.plist b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/UnrarKitResources.bundle/Contents/Info.plist
index e9f384d..da6edfb 100644
--- a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/UnrarKitResources.bundle/Contents/Info.plist
+++ b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/Resources/UnrarKitResources.bundle/Contents/Info.plist
@@ -3,7 +3,7 @@
BuildMachineOSBuild
- 17D47
+ 19H2
CFBundleDevelopmentRegion
English
CFBundleIdentifier
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.9
+ 2.10-beta8
CFBundleSignature
????
CFBundleSupportedPlatforms
@@ -23,21 +23,25 @@
MacOSX
CFBundleVersion
- 2.9
+ 2.10-beta8
DTCompiler
com.apple.compilers.llvm.clang.1_0
DTPlatformBuild
- 9E145
+ 12A7300
+ DTPlatformName
+ macosx
DTPlatformVersion
- GM
+ 10.15.6
DTSDKBuild
- 17E189
+ 19G68
DTSDKName
- macosx10.13
+ macosx10.15
DTXcode
- 0930
+ 1201
DTXcodeBuild
- 9E145
+ 12A7300
+ LSMinimumSystemVersion
+ 10.15
NSHumanReadableCopyright
Copyright © 2017 Abbey Code. All rights reserved.
diff --git a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/UnrarKit b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/UnrarKit
index d2fb1ee..a620327 100755
Binary files a/Carthage/Build/Mac/UnrarKit.framework/Versions/A/UnrarKit and b/Carthage/Build/Mac/UnrarKit.framework/Versions/A/UnrarKit differ
diff --git a/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Info.plist b/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Info.plist
index c7fe283..cf0c25f 100644
--- a/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Info.plist
+++ b/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Info.plist
@@ -13,8 +13,8 @@
CFBundleSignature
????
CFBundleShortVersionString
- 2.9
+ 2.10-beta8
CFBundleVersion
- 2.9
+ 2.10-beta8
diff --git a/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit b/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit
index 1aa0730..7ae3f97 100644
Binary files a/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit and b/Carthage/Build/iOS/UnrarKit.framework.dSYM/Contents/Resources/DWARF/UnrarKit differ
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Headers/URKArchive.h b/Carthage/Build/iOS/UnrarKit.framework/Headers/URKArchive.h
index bd064cb..367862d 100644
--- a/Carthage/Build/iOS/UnrarKit.framework/Headers/URKArchive.h
+++ b/Carthage/Build/iOS/UnrarKit.framework/Headers/URKArchive.h
@@ -6,14 +6,14 @@
#import
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
@class URKFileInfo;
@@ -25,7 +25,7 @@ DllHppIgnore
typedef NS_ENUM(NSInteger, URKErrorCode) {
/**
- * The archive's header is empty
+ * The last file of the archive has been read
*/
URKErrorCodeEndOfArchive = ERAR_END_ARCHIVE,
@@ -35,7 +35,7 @@ typedef NS_ENUM(NSInteger, URKErrorCode) {
URKErrorCodeNoMemory = ERAR_NO_MEMORY,
/**
- * The header is broken
+ * The header's CRC doesn't match the decompressed data's CRC
*/
URKErrorCodeBadData = ERAR_BAD_DATA,
@@ -173,6 +173,17 @@ extern NSString *URKErrorDomain;
*/
@property(nullable, strong) NSProgress *progress;
+/**
+ * When performing operations on a RAR archive, the contents of compressed files are checked
+ * against the record of what they were when the archive was created. If there's a mismatch,
+ * either the metadata (header) or archive contents have become corrupted. You can defeat this check by
+ * setting this property to YES, though there may be security implications to turning the
+ * warnings off, as it may indicate a maliciously crafted archive intended to exploit a vulnerability.
+ *
+ * It's recommended to leave the decision of how to treat archives with mismatched CRCs to the user
+ */
+@property (assign) BOOL ignoreCRCMismatches;
+
/**
* **DEPRECATED:** Creates and returns an archive at the given path
@@ -475,15 +486,34 @@ extern NSString *URKErrorDomain;
- (BOOL)validatePassword;
/**
- Extract each file in the archive, checking whether the data matches the CRC checksum
- stored at the time it was written
-
- @return YES if the data is all correct, false if any check failed
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header
+
+ @return YES if the data is all correct, false if any check failed (_even if ignoreCRCMismatches is YES_)
*/
- (BOOL)checkDataIntegrity;
/**
- Extract a particular file, to determine if its data matches the CRC
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header. If any file's CRC doesn't match, run the given block
+ to allow the API consumer to decide whether to ignore mismatches. NOTE: This may be a
+ security risk. The block is intended to prompt the user, which is why it's forced onto
+ the main thread, rather than making a design-time decision
+
+ @param ignoreCRCMismatches This block, called on the main thread, allows a consuming API to
+ prompt the user whether or not he'd like to ignore CRC mismatches.
+ This block is called the first time a CRC mismatch is detected, if
+ at all. It won't be called if all CRCs match. If this returns YES,
+ then all further CRC mismatches will be ignored for the
+ archive instance
+
+ @return YES if the data is all correct and/or the block returns YES; returns false if
+ any check failed and the given block also returns NO
+ */
+- (BOOL)checkDataIntegrityIgnoringCRCMismatches:(BOOL(^)(void))ignoreCRCMismatches;
+
+/**
+ Check a particular file, to determine if its data matches the CRC
checksum stored at the time it written
@param filePath The file in the archive to check
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Headers/URKFileInfo.h b/Carthage/Build/iOS/UnrarKit.framework/Headers/URKFileInfo.h
index 5bf2c95..8cd29fb 100644
--- a/Carthage/Build/iOS/UnrarKit.framework/Headers/URKFileInfo.h
+++ b/Carthage/Build/iOS/UnrarKit.framework/Headers/URKFileInfo.h
@@ -4,14 +4,14 @@
//
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
/* See http://www.forensicswiki.org/wiki/RAR and
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKit.h b/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKit.h
index 78db3b3..d2e390e 100644
--- a/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKit.h
+++ b/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKit.h
@@ -15,5 +15,5 @@ FOUNDATION_EXPORT double UnrarKitVersionNumber;
FOUNDATION_EXPORT const unsigned char UnrarKitVersionString[];
-#import "URKArchive.h"
-#import "URKFileInfo.h"
+#import
+#import
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKitMacros.h b/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKitMacros.h
index aea9343..38e466f 100644
--- a/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKitMacros.h
+++ b/Carthage/Build/iOS/UnrarKit.framework/Headers/UnrarKitMacros.h
@@ -60,7 +60,7 @@ __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000 \
#import
// Called from +[UnrarKit initialize] and +[URKArchiveTestCase setUp]
-extern os_log_t unrarkit_log; // Declared in URKArchive.m
+extern os_log_t unrarkit_log; // Declared in URKArchive.mm
extern BOOL unrarkitIsAtLeast10_13SDK; // Declared in URKArchive.m
#define URKLogInit() \
unrarkit_log = os_log_create("com.abbey-code.UnrarKit", "General"); \
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Headers/dll.hpp b/Carthage/Build/iOS/UnrarKit.framework/Headers/dll.hpp
index 7f82906..c785ff1 100644
--- a/Carthage/Build/iOS/UnrarKit.framework/Headers/dll.hpp
+++ b/Carthage/Build/iOS/UnrarKit.framework/Headers/dll.hpp
@@ -1,7 +1,7 @@
#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_
-#pragma pack(1)
+#pragma pack(push, 1)
#define ERAR_SUCCESS 0
#define ERAR_END_ARCHIVE 10
@@ -135,6 +135,8 @@ typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM
#define ROADF_ENCHEADERS 0x0080
#define ROADF_FIRSTVOLUME 0x0100
+#define ROADOF_KEEPBROKEN 0x0001
+
struct RAROpenArchiveDataEx
{
char *ArcName;
@@ -148,7 +150,9 @@ struct RAROpenArchiveDataEx
unsigned int Flags;
UNRARCALLBACK Callback;
LPARAM UserData;
- unsigned int Reserved[28];
+ unsigned int OpFlags;
+ wchar_t *CmtBufW;
+ unsigned int Reserved[25];
};
enum UNRARCALLBACK_MESSAGES {
@@ -180,6 +184,6 @@ int PASCAL RARGetDllVersion();
}
#endif
-#pragma pack()
+#pragma pack(pop)
#endif
diff --git a/Carthage/Build/iOS/UnrarKit.framework/Info.plist b/Carthage/Build/iOS/UnrarKit.framework/Info.plist
index 66dcb2e..c7321d2 100644
Binary files a/Carthage/Build/iOS/UnrarKit.framework/Info.plist and b/Carthage/Build/iOS/UnrarKit.framework/Info.plist differ
diff --git a/Carthage/Build/iOS/UnrarKit.framework/UnrarKit b/Carthage/Build/iOS/UnrarKit.framework/UnrarKit
index 23fe062..2fd324d 100755
Binary files a/Carthage/Build/iOS/UnrarKit.framework/UnrarKit and b/Carthage/Build/iOS/UnrarKit.framework/UnrarKit differ
diff --git a/Carthage/Build/iOS/UnrarKit.framework/UnrarKitResources.bundle/Info.plist b/Carthage/Build/iOS/UnrarKit.framework/UnrarKitResources.bundle/Info.plist
index 30476c2..5f63634 100644
Binary files a/Carthage/Build/iOS/UnrarKit.framework/UnrarKitResources.bundle/Info.plist and b/Carthage/Build/iOS/UnrarKit.framework/UnrarKitResources.bundle/Info.plist differ
diff --git a/Carthage/Checkouts/UnrarKit/.travis.yml b/Carthage/Checkouts/UnrarKit/.travis.yml
index 4be4f70..2b46075 100644
--- a/Carthage/Checkouts/UnrarKit/.travis.yml
+++ b/Carthage/Checkouts/UnrarKit/.travis.yml
@@ -1,7 +1,12 @@
language: objective-c
-osx_image: xcode9.3
+osx_image: xcode12
+
+branches:
+ except:
+ - circle-ci
before_script:
+ - pod --version
# Make log level less verbose. Temporarily undo if more info is needed
- sudo log config --mode "level:default"
@@ -15,7 +20,7 @@ matrix:
- stage: Test
env: Name=iOS
# The CLANG arguments and find command fail the build on analyzer errors
- script: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -destination 'platform=iOS Simulator,name=iPhone 7,OS=latest' -configuration Release analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]]
+ script: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -destination 'platform=iOS Simulator,name=iPhone 11,OS=latest' -configuration Release analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]]
- stage: Test
env: Name=ExampleAppBuild
@@ -32,5 +37,4 @@ matrix:
- stage: Release
if: tag IS present
- before_install: brew upgrade python # Needs Python 3
script: ./Scripts/push-output.sh
diff --git a/Carthage/Checkouts/UnrarKit/CHANGELOG.md b/Carthage/Checkouts/UnrarKit/CHANGELOG.md
index f47b8a4..d75cd5b 100644
--- a/Carthage/Checkouts/UnrarKit/CHANGELOG.md
+++ b/Carthage/Checkouts/UnrarKit/CHANGELOG.md
@@ -1,5 +1,14 @@
# UnrarKit CHANGELOG
+## 2.10
+
+* Added method (`checkDataIntegrityIgnoringCRCMismatches:`) to prompt user for a decision on whether or not to ignore CRC mismatches (Issue #82)
+* Fixed crash in `+pathIsARAR:` when a file is unreadable (Issue #85)
+* Fixed crash in `-_unrarOpenFile:inMode:withPassword:error:` (PR #97)
+* Updated to v5.9.4 of UnRAR library
+* Xcode 12 compatibility in Carthage
+
+
## 2.9
* Added support for `NSProgress` and `NSProgressReporting` in all extraction and iteration methods (Issue #34)
diff --git a/Carthage/Checkouts/UnrarKit/Classes/URKArchive.h b/Carthage/Checkouts/UnrarKit/Classes/URKArchive.h
index bd064cb..367862d 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/URKArchive.h
+++ b/Carthage/Checkouts/UnrarKit/Classes/URKArchive.h
@@ -6,14 +6,14 @@
#import
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
@class URKFileInfo;
@@ -25,7 +25,7 @@ DllHppIgnore
typedef NS_ENUM(NSInteger, URKErrorCode) {
/**
- * The archive's header is empty
+ * The last file of the archive has been read
*/
URKErrorCodeEndOfArchive = ERAR_END_ARCHIVE,
@@ -35,7 +35,7 @@ typedef NS_ENUM(NSInteger, URKErrorCode) {
URKErrorCodeNoMemory = ERAR_NO_MEMORY,
/**
- * The header is broken
+ * The header's CRC doesn't match the decompressed data's CRC
*/
URKErrorCodeBadData = ERAR_BAD_DATA,
@@ -173,6 +173,17 @@ extern NSString *URKErrorDomain;
*/
@property(nullable, strong) NSProgress *progress;
+/**
+ * When performing operations on a RAR archive, the contents of compressed files are checked
+ * against the record of what they were when the archive was created. If there's a mismatch,
+ * either the metadata (header) or archive contents have become corrupted. You can defeat this check by
+ * setting this property to YES, though there may be security implications to turning the
+ * warnings off, as it may indicate a maliciously crafted archive intended to exploit a vulnerability.
+ *
+ * It's recommended to leave the decision of how to treat archives with mismatched CRCs to the user
+ */
+@property (assign) BOOL ignoreCRCMismatches;
+
/**
* **DEPRECATED:** Creates and returns an archive at the given path
@@ -475,15 +486,34 @@ extern NSString *URKErrorDomain;
- (BOOL)validatePassword;
/**
- Extract each file in the archive, checking whether the data matches the CRC checksum
- stored at the time it was written
-
- @return YES if the data is all correct, false if any check failed
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header
+
+ @return YES if the data is all correct, false if any check failed (_even if ignoreCRCMismatches is YES_)
*/
- (BOOL)checkDataIntegrity;
/**
- Extract a particular file, to determine if its data matches the CRC
+ Iterate through the archive, checking for any errors, including CRC mismatches between
+ the archived file and its header. If any file's CRC doesn't match, run the given block
+ to allow the API consumer to decide whether to ignore mismatches. NOTE: This may be a
+ security risk. The block is intended to prompt the user, which is why it's forced onto
+ the main thread, rather than making a design-time decision
+
+ @param ignoreCRCMismatches This block, called on the main thread, allows a consuming API to
+ prompt the user whether or not he'd like to ignore CRC mismatches.
+ This block is called the first time a CRC mismatch is detected, if
+ at all. It won't be called if all CRCs match. If this returns YES,
+ then all further CRC mismatches will be ignored for the
+ archive instance
+
+ @return YES if the data is all correct and/or the block returns YES; returns false if
+ any check failed and the given block also returns NO
+ */
+- (BOOL)checkDataIntegrityIgnoringCRCMismatches:(BOOL(^)(void))ignoreCRCMismatches;
+
+/**
+ Check a particular file, to determine if its data matches the CRC
checksum stored at the time it written
@param filePath The file in the archive to check
diff --git a/Carthage/Checkouts/UnrarKit/Classes/URKArchive.mm b/Carthage/Checkouts/UnrarKit/Classes/URKArchive.mm
index d00c3b8..ae669cc 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/URKArchive.mm
+++ b/Carthage/Checkouts/UnrarKit/Classes/URKArchive.mm
@@ -28,6 +28,11 @@ BOOL unrarkitIsAtLeast10_13SDK;
static NSBundle *_resources = nil;
+typedef enum : NSUInteger {
+ URKReadHeaderLoopActionStopReading,
+ URKReadHeaderLoopActionContinueReading,
+} URKReadHeaderLoopAction;
+
@interface URKArchive ()
@@ -46,6 +51,9 @@ NS_DESIGNATED_INITIALIZER
@property (strong) NSObject *threadLock;
+@property (copy) NSString *lastArchivePath;
+@property (copy) NSString *lastFilepath;
+
@end
@@ -160,6 +168,10 @@ NS_DESIGNATED_INITIALIZER
error:&bookmarkError];
_password = password;
_threadLock = [[NSObject alloc] init];
+
+ _lastArchivePath = nil;
+ _lastFilepath = nil;
+ _ignoreCRCMismatches = NO;
if (bookmarkError) {
URKLogFault("Error creating bookmark to RAR archive: %{public}@", bookmarkError);
@@ -336,6 +348,9 @@ NS_DESIGNATED_INITIALIZER
URKLogDebug("File is not a RAR. Unknown contents in 7th and 8th bytes (%02X %02X)", dataBytes[6], dataBytes[7]);
}
+ @catch (NSException *e) {
+ URKLogError("Error checking if %{public}@ is a RAR archive: %{public}@", filePath, e);
+ }
@finally {
[handle closeFile];
}
@@ -508,8 +523,7 @@ NS_DESIGNATED_INITIALIZER
URKLogInfo("Extracting to %{public}@", filePath);
URKLogDebug("Reading through RAR header looking for files...");
- while ((RHCode = RARReadHeaderEx(welf.rarFile, welf.header)) == ERAR_SUCCESS) {
- fileInfo = [URKFileInfo fileInfo:welf.header];
+ while ([welf readHeader:&RHCode info:&fileInfo] == URKReadHeaderLoopActionContinueReading) {
URKLogDebug("Extracting %{public}@ (%{iec-bytes}lld)", fileInfo.filename, fileInfo.uncompressedSize);
NSURL *extractedURL = [[NSURL fileURLWithPath:filePath] URLByAppendingPathComponent:fileInfo.filename];
[progress setUserInfoObject:extractedURL
@@ -517,7 +531,7 @@ NS_DESIGNATED_INITIALIZER
[progress setUserInfoObject:fileInfo
forKey:URKProgressInfoKeyFileInfoExtracting];
- if ([self headerContainsErrors:innerError]) {
+ if ([welf headerContainsErrors:innerError]) {
URKLogError("Header contains an error")
result = NO;
return;
@@ -525,7 +539,7 @@ NS_DESIGNATED_INITIALIZER
if (progress.isCancelled) {
NSString *errorName = nil;
- [self assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
+ [welf assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
URKLogInfo("Halted file extraction due to user cancellation: %{public}@", errorName);
result = NO;
return;
@@ -537,7 +551,7 @@ NS_DESIGNATED_INITIALIZER
encoding:NSUTF8StringEncoding];
if (!utf8ConversionSucceeded) {
NSString *errorName = nil;
- [self assignError:innerError code:URKErrorCodeStringConversion errorName:&errorName];
+ [welf assignError:innerError code:URKErrorCodeStringConversion errorName:&errorName];
URKLogError("Error converting file to UTF-8 (buffer too short?)");
result = NO;
return;
@@ -550,12 +564,13 @@ NS_DESIGNATED_INITIALIZER
};
RARSetCallback(welf.rarFile, AllowCancellationCallbackProc, (long)shouldCancelBlock);
- if ((PFCode = RARProcessFile(welf.rarFile, RAR_EXTRACT, cFilePath, NULL)) != 0) {
+ PFCode = RARProcessFile(welf.rarFile, RAR_EXTRACT, cFilePath, NULL);
+ if (![welf didReturnSuccessfully:PFCode]) {
RARSetCallback(welf.rarFile, NULL, NULL);
-
+
NSString *errorName = nil;
NSInteger errorCode = progress.isCancelled ? URKErrorCodeUserCancelled : PFCode;
- [self assignError:innerError code:errorCode errorName:&errorName];
+ [welf assignError:innerError code:errorCode errorName:&errorName];
URKLogError("Error extracting file: %{public}@ (%ld)", errorName, (long)errorCode);
result = NO;
return;
@@ -582,14 +597,14 @@ NS_DESIGNATED_INITIALIZER
}
RARSetCallback(welf.rarFile, NULL, NULL);
-
- if (RHCode != ERAR_SUCCESS && RHCode != ERAR_END_ARCHIVE) {
+
+ if (![welf didReturnSuccessfully:RHCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:RHCode errorName:&errorName];
+ [welf assignError:innerError code:RHCode errorName:&errorName];
URKLogError("Error reading file header: %{public}@ (%d)", errorName, RHCode);
result = NO;
}
-
+
if (progressBlock) {
progressBlock(fileInfo, 1.0);
}
@@ -642,14 +657,12 @@ NS_DESIGNATED_INITIALIZER
URKFileInfo *fileInfo;
URKLogDebug("Reading through RAR header looking for files...");
- while ((RHCode = RARReadHeaderEx(welf.rarFile, welf.header)) == ERAR_SUCCESS) {
- if ([self headerContainsErrors:innerError]) {
+ while ([welf readHeader:&RHCode info:&fileInfo] == URKReadHeaderLoopActionContinueReading) {
+ if ([welf headerContainsErrors:innerError]) {
URKLogError("Header contains an error")
return;
}
- fileInfo = [URKFileInfo fileInfo:welf.header];
-
if ([fileInfo.filename isEqualToString:filePath]) {
URKLogDebug("Extracting %{public}@", fileInfo.filename);
break;
@@ -658,7 +671,7 @@ NS_DESIGNATED_INITIALIZER
URKLogDebug("Skipping %{public}@", fileInfo.filename);
if ((PFCode = RARProcessFileW(welf.rarFile, RAR_SKIP, NULL, NULL)) != 0) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Error skipping file: %{public}@ (%d)", errorName, PFCode);
return;
}
@@ -667,7 +680,7 @@ NS_DESIGNATED_INITIALIZER
if (RHCode != ERAR_SUCCESS) {
NSString *errorName = nil;
- [self assignError:innerError code:RHCode errorName:&errorName];
+ [welf assignError:innerError code:RHCode errorName:&errorName];
URKLogError("Error reading file header: %{public}@ (%d)", errorName, RHCode);
return;
}
@@ -715,14 +728,14 @@ NS_DESIGNATED_INITIALIZER
if (progress.isCancelled) {
NSString *errorName = nil;
- [self assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
+ [welf assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
URKLogInfo("Returning nil data from extraction due to user cancellation: %{public}@", errorName);
return;
}
- if (PFCode != 0) {
+ if (![welf didReturnSuccessfully:PFCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Error extracting file data: %{public}@ (%d)", errorName, PFCode);
return;
}
@@ -813,27 +826,36 @@ NS_DESIGNATED_INITIALIZER
BOOL stop = NO;
- NSProgress *progress = [self beginProgressOperation:totalSize.longLongValue];
+ NSProgress *progress = [welf beginProgressOperation:totalSize.longLongValue];
URKLogDebug("Reading through RAR header looking for files...");
- while ((RHCode = RARReadHeaderEx(welf.rarFile, welf.header)) == 0) {
+
+ URKFileInfo *info = nil;
+ while ([welf readHeader:&RHCode info:&info] == URKReadHeaderLoopActionContinueReading) {
if (stop || progress.isCancelled) {
URKLogDebug("Action dictated an early stop");
return;
}
- if ([self headerContainsErrors:innerError]) {
+ if ([welf headerContainsErrors:innerError]) {
URKLogError("Header contains an error")
return;
}
- URKFileInfo *info = [URKFileInfo fileInfo:welf.header];
URKLogDebug("Performing action on %{public}@", info.filename);
// Empty file, or a directory
- if (info.uncompressedSize == 0) {
+ if (info.isDirectory || info.uncompressedSize == 0) {
URKLogDebug("%{public}@ is an empty file, or a directory", info.filename);
action(info, [NSData data], &stop);
+ PFCode = RARProcessFile(welf.rarFile, RAR_SKIP, NULL, NULL);
+ if (PFCode != 0) {
+ NSString *errorName = nil;
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ URKLogError("Error skipping directory: %{public}@ (%d)", errorName, PFCode);
+ return;
+ }
+
continue;
}
@@ -845,9 +867,9 @@ NS_DESIGNATED_INITIALIZER
URKLogInfo("Processing file...");
PFCode = RARProcessFile(welf.rarFile, RAR_TEST, NULL, NULL);
- if (PFCode != 0) {
+ if (![welf didReturnSuccessfully:PFCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Error processing file: %{public}@ (%d)", errorName, PFCode);
return;
}
@@ -861,14 +883,14 @@ NS_DESIGNATED_INITIALIZER
if (progress.isCancelled) {
NSString *errorName = nil;
- [self assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
+ [welf assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
URKLogInfo("Returning NO from performOnData:error: due to user cancellation: %{public}@", errorName);
return;
}
- if (RHCode != ERAR_SUCCESS && RHCode != ERAR_END_ARCHIVE) {
+ if (![welf didReturnSuccessfully:RHCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:RHCode errorName:&errorName];
+ [welf assignError:innerError code:RHCode errorName:&errorName];
URKLogError("Error reading file header: %{public}@ (%d)", errorName, RHCode);
return;
}
@@ -897,24 +919,22 @@ NS_DESIGNATED_INITIALIZER
URKLogInfo("Looping through files, looking for %{public}@...", filePath);
- while ((RHCode = RARReadHeaderEx(welf.rarFile, welf.header)) == ERAR_SUCCESS) {
- if ([self headerContainsErrors:innerError]) {
+ while ([welf readHeader:&RHCode info:&fileInfo] == URKReadHeaderLoopActionContinueReading) {
+ if ([welf headerContainsErrors:innerError]) {
URKLogDebug("Header contains error")
return;
}
- URKLogDebug("Getting file info from header");
- fileInfo = [URKFileInfo fileInfo:welf.header];
-
if ([fileInfo.filename isEqualToString:filePath]) {
URKLogDebug("Found desired file");
break;
}
else {
URKLogDebug("Skipping file...");
- if ((PFCode = RARProcessFile(welf.rarFile, RAR_SKIP, NULL, NULL)) != 0) {
+ PFCode = RARProcessFile(welf.rarFile, RAR_SKIP, NULL, NULL);
+ if (![welf didReturnSuccessfully:PFCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Failed to skip file: %{public}@ (%d)", errorName, PFCode);
return;
}
@@ -924,9 +944,9 @@ NS_DESIGNATED_INITIALIZER
long long totalBytes = fileInfo.uncompressedSize;
progress.totalUnitCount = totalBytes;
- if (RHCode != ERAR_SUCCESS) {
+ if (![welf didReturnSuccessfully:RHCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:RHCode errorName:&errorName];
+ [welf assignError:innerError code:RHCode errorName:&errorName];
URKLogError("Header read yielded error: %{public}@ (%d)", errorName, RHCode);
return;
}
@@ -965,14 +985,14 @@ NS_DESIGNATED_INITIALIZER
if (progress.isCancelled) {
NSString *errorName = nil;
- [self assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
+ [welf assignError:innerError code:URKErrorCodeUserCancelled errorName:&errorName];
URKLogError("Buffered data extraction has been cancelled: %{public}@", errorName);
return;
}
- if (PFCode != 0) {
+ if (![welf didReturnSuccessfully:PFCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Error processing file: %{public}@ (%d)", errorName, PFCode);
}
} inMode:RAR_OM_EXTRACT error:&actionError];
@@ -1049,7 +1069,7 @@ NS_DESIGNATED_INITIALIZER
int RHCode = RARReadHeaderEx(welf.rarFile, welf.header);
int PFCode = RARProcessFile(welf.rarFile, RAR_TEST, NULL, NULL);
- if ([self headerContainsErrors:innerError]) {
+ if ([welf headerContainsErrors:innerError]) {
if (error.code == ERAR_MISSING_PASSWORD) {
URKLogDebug("Password invalidated by header");
passwordIsGood = NO;
@@ -1062,13 +1082,18 @@ NS_DESIGNATED_INITIALIZER
}
if (RHCode == ERAR_MISSING_PASSWORD || PFCode == ERAR_MISSING_PASSWORD
- || RHCode == ERAR_BAD_DATA || PFCode == ERAR_BAD_DATA
|| RHCode == ERAR_BAD_PASSWORD || PFCode == ERAR_BAD_PASSWORD)
{
URKLogDebug("Missing/bad password indicated by RHCode (%d) or PFCode (%d)", RHCode, PFCode);
passwordIsGood = NO;
return;
}
+
+ if ([welf hasBadCRC:RHCode] || [welf hasBadCRC:PFCode]) {
+ URKLogDebug("Missing/bad password indicated via CRC mismatch by RHCode (%d) or PFCode (%d)", RHCode, PFCode);
+ passwordIsGood = NO;
+ return;
+ }
} inMode:RAR_OM_EXTRACT error:&error];
if (!success) {
@@ -1084,47 +1109,96 @@ NS_DESIGNATED_INITIALIZER
return [self checkDataIntegrityOfFile:(NSString *_Nonnull)nil];
}
-- (BOOL)checkDataIntegrityOfFile:(NSString *)filePath
+- (BOOL)checkDataIntegrityIgnoringCRCMismatches:(BOOL(^)())ignoreCRCMismatches
+{
+ int rhCode = [self dataIntegrityCodeOfFile:nil];
+ if (rhCode == ERAR_SUCCESS) {
+ return YES;
+ }
+
+ if (rhCode == ERAR_BAD_DATA) {
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+
+ __block BOOL blockResult;
+
+ if ([NSOperationQueue currentQueue] == mainQueue) {
+ blockResult = ignoreCRCMismatches();
+ } else {
+ [mainQueue addOperations:@[[NSBlockOperation blockOperationWithBlock:^{
+ blockResult = ignoreCRCMismatches();
+ }]]
+ waitUntilFinished:YES];
+ }
+
+ self.ignoreCRCMismatches = blockResult;
+ return self.ignoreCRCMismatches;
+ }
+
+ return NO;
+}
+
+- (BOOL)checkDataIntegrityOfFile:(NSString *)filePath {
+ return [self dataIntegrityCodeOfFile:filePath] == ERAR_SUCCESS;
+}
+
+- (int)dataIntegrityCodeOfFile:(NSString *)filePath
{
URKCreateActivity("Checking Data Integrity");
URKLogInfo("Checking integrity of %{public}@", filePath ? filePath : @"whole archive");
- __block BOOL corruptDataFound = YES;
+ __block int RHCode = 0;
+ __block int PFCode = 0;
+
+ __weak URKArchive *welf = self;
NSError *performOnFilesError = nil;
- [self performOnFilesInArchive:^(URKFileInfo *fileInfo, BOOL *stop) {
+ BOOL wasSuccessful = [self performActionWithArchiveOpen:^(NSError **innerError) {
URKCreateActivity("Iterating through each file");
- corruptDataFound = NO; // Set inside here so invalid archives are marked as corrupt
- if (filePath && ![fileInfo.filename isEqualToString:filePath]) return;
-
- URKLogDebug("Extracting '%{public}@ to check its CRC...", fileInfo.filename);
- NSError *extractError = nil;
- NSData *fileData = [self extractData:fileInfo error:&extractError];
- if (!fileData) {
- URKLogError("Error extracting %{public}@: %{public}@", fileInfo.filename, extractError);
- *stop = YES;
- return;
+ while (true) {
+ URKFileInfo *fileInfo = nil;
+ [welf readHeader:&RHCode info:&fileInfo];
+ welf.lastFilepath = nil;
+ welf.lastArchivePath = nil;
+
+ if (RHCode == ERAR_END_ARCHIVE) {
+ RHCode = ERAR_SUCCESS;
+ break;
+ }
+
+ if (filePath && ![fileInfo.filename isEqualToString:filePath]) continue;
+
+ if (RHCode != ERAR_SUCCESS) {
+ break;
+ }
+
+ if ((PFCode = RARProcessFile(welf.rarFile, RAR_TEST, NULL, NULL)) != ERAR_SUCCESS) {
+ RHCode = PFCode;
+ break;
+ }
+
+ if (filePath) {
+ break;
+ }
}
-
- uLong expectedCRC = fileInfo.CRC;
- uLong actualCRC = crc32((uLong)0, (const Bytef*)fileData.bytes, (uint)fileData.length);
- URKLogDebug("Checking integrity of %{public}@. Expected CRC: %010lu vs. Actual: %010lu",
- fileInfo.filename, expectedCRC, actualCRC);
- if (expectedCRC != actualCRC) {
- corruptDataFound = YES;
- URKLogError("Corrupt data found (filename: %{public}@, expected CRC: %010lu, actual CRC: %010lu",
- fileInfo.filename, expectedCRC, actualCRC);
- }
-
- if (filePath) *stop = YES;
- } error:&performOnFilesError];
+ } inMode:RAR_OM_EXTRACT error:&performOnFilesError];
+
+ if (RHCode == ERAR_END_ARCHIVE) {
+ RHCode = ERAR_SUCCESS;
+ }
if (performOnFilesError) {
URKLogError("Error checking data integrity: %{public}@", performOnFilesError);
}
- return !corruptDataFound;
+ if (!wasSuccessful) {
+ URKLogError("Error checking data integrity");
+ if (RHCode == ERAR_SUCCESS) {
+ RHCode = ERAR_UNKNOWN;
+ }
+ }
+
+ return RHCode;
}
@@ -1269,22 +1343,24 @@ int CALLBACK AllowCancellationCallbackProc(UINT msg, long UserData, long P1, lon
URKLogDebug("Setting archive name...");
- const char *filenameData = (const char *) [rarFile UTF8String];
- self.flags->ArcName = new char[strlen(filenameData) + 1];
- strcpy(self.flags->ArcName, filenameData);
- self.flags->OpenMode = (uint)mode;
+ self.flags->ArcName = strdup(rarFile.UTF8String);
+ self.flags->OpenMode = (uint)mode;
+ self.flags->OpFlags = self.ignoreCRCMismatches ? ROADOF_KEEPBROKEN : 0;
URKLogDebug("Opening archive %{public}@...", rarFile);
- self.rarFile = RAROpenArchiveEx(self.flags);
- if (self.rarFile == 0 || self.flags->OpenResult != 0) {
+ self.rarFile = RAROpenArchiveEx(self.flags);
+ if (self.rarFile == 0 || self.flags->OpenResult != 0) {
NSString *errorName = nil;
[self assignError:error code:(NSInteger)self.flags->OpenResult errorName:&errorName];
URKLogError("Error opening archive: %{public}@ (%d)", errorName, self.flags->OpenResult);
return NO;
}
- if(aPassword != nil) {
+ self.lastFilepath = nil;
+ self.lastArchivePath = nil;
+
+ if (aPassword != nil) {
URKLogDebug("Setting password...");
char cPassword[2048];
@@ -1339,10 +1415,10 @@ int CALLBACK AllowCancellationCallbackProc(UINT msg, long UserData, long P1, lon
URKLogDebug("Reading through RAR header looking for files...");
- while ((RHCode = RARReadHeaderEx(welf.rarFile, welf.header)) == 0) {
+ URKFileInfo *info = nil;
+ while ([welf readHeader:&RHCode info:&info] == URKReadHeaderLoopActionContinueReading) {
URKLogDebug("Calling iterateAllFileInfo handler");
BOOL shouldStop = NO;
- URKFileInfo *info = [URKFileInfo fileInfo:welf.header];
action(info, &shouldStop);
if (shouldStop) {
@@ -1353,15 +1429,15 @@ int CALLBACK AllowCancellationCallbackProc(UINT msg, long UserData, long P1, lon
URKLogDebug("Skipping to next file...");
if ((PFCode = RARProcessFile(welf.rarFile, RAR_SKIP, NULL, NULL)) != 0) {
NSString *errorName = nil;
- [self assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
+ [welf assignError:innerError code:(NSInteger)PFCode errorName:&errorName];
URKLogError("Error skipping to next header file: %{public}@ (%d)", errorName, PFCode);
return;
}
}
- if (RHCode != ERAR_SUCCESS && RHCode != ERAR_END_ARCHIVE) {
+ if (![welf didReturnSuccessfully:RHCode]) {
NSString *errorName = nil;
- [self assignError:innerError code:RHCode errorName:&errorName];
+ [welf assignError:innerError code:RHCode errorName:&errorName];
URKLogError("Error reading RAR header: %{public}@ (%d)", errorName, RHCode);
}
} inMode:RAR_OM_LIST_INCSPLIT error:error];
@@ -1485,7 +1561,7 @@ int CALLBACK AllowCancellationCallbackProc(UINT msg, long UserData, long P1, lon
default:
errorName = [NSString stringWithFormat:@"Unknown (%ld)", (long)errorCode];
- detail = [NSString localizedStringWithFormat:NSLocalizedStringFromTableInBundle(@"Unknown error encountered (code %ld)", @"UnrarKit", _resources, @"Error detail string"), errorCode];
+ detail = [NSString localizedStringWithFormat:NSLocalizedStringFromTableInBundle(@"Unknown error encountered (code %ld)", @"UnrarKit", _resources, @"Error detail string"), (long)errorCode];
break;
}
@@ -1641,4 +1717,71 @@ int CALLBACK AllowCancellationCallbackProc(UINT msg, long UserData, long P1, lon
return volumeURL;
}
+- (URKReadHeaderLoopAction) readHeader:(int *)returnCode
+ info:(URKFileInfo *__autoreleasing *)info
+{
+ NSAssert(returnCode != NULL, @"otherReturnCode argument is required");
+ NSAssert(info != NULL, @"info argument is required");
+
+ URKLogDebug("Reading RAR header");
+ *returnCode = RARReadHeaderEx(self.rarFile, self.header);
+ URKLogDebug("Reading file info from RAR header");
+ *info = [URKFileInfo fileInfo:self.header];
+ URKLogDebug("RARReadHeaderEx returned %d", *returnCode);
+
+ URKReadHeaderLoopAction result;
+
+ switch (*returnCode) {
+ case ERAR_SUCCESS:
+ result = URKReadHeaderLoopActionContinueReading;
+ break;
+
+ case ERAR_END_ARCHIVE:
+ URKLogDebug("Successful return code from RARReadHeaderEx");
+ result = URKReadHeaderLoopActionStopReading;
+ break;
+
+ case ERAR_BAD_DATA:
+ if (self.ignoreCRCMismatches) {
+ URKLogError("Ignoring CRC mismatch in %{public}@", (*info).filename);
+ result = URKReadHeaderLoopActionContinueReading;
+ } else {
+ URKLogError("CRC mismatch when reading %{public}@. To read the archive and ignore CRC mismatches, use -checkDataIntegrityIgnoringCRCMismatches:", (*info).filename);
+ result = URKReadHeaderLoopActionStopReading;
+ }
+ break;
+
+ default:
+ result = URKReadHeaderLoopActionStopReading;
+ break;
+ }
+
+ if (result == URKReadHeaderLoopActionContinueReading
+ && [self.lastFilepath isEqualToString:(*info).filename]
+ && [self.lastArchivePath isEqualToString:(*info).archiveName])
+ {
+ URKLogInfo("Same header returned twice. Presuming archive done being read. Probably a bad CRC")
+ result = URKReadHeaderLoopActionStopReading;
+ }
+
+ self.lastFilepath = (result == URKReadHeaderLoopActionStopReading
+ ? nil
+ : (*info).filename);
+ self.lastArchivePath = (result == URKReadHeaderLoopActionStopReading
+ ? nil
+ : (*info).archiveName);
+
+ return result;
+}
+
+- (BOOL)didReturnSuccessfully:(int)returnCode {
+ return (returnCode == ERAR_SUCCESS
+ || returnCode == ERAR_END_ARCHIVE
+ || (returnCode == ERAR_BAD_DATA && self.ignoreCRCMismatches));
+}
+
+- (BOOL)hasBadCRC:(int)returnCode {
+ return returnCode == ERAR_BAD_DATA && !self.ignoreCRCMismatches;
+}
+
@end
diff --git a/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.h b/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.h
index 5bf2c95..8cd29fb 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.h
+++ b/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.h
@@ -4,14 +4,14 @@
//
#import
-#import "UnrarKitMacros.h"
+#import
RarosHppIgnore
-#import "raros.hpp"
+#import
#pragma clang diagnostic pop
DllHppIgnore
-#import "dll.hpp"
+#import
#pragma clang diagnostic pop
/* See http://www.forensicswiki.org/wiki/RAR and
diff --git a/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.m b/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.m
index 24232eb..6b1c083 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.m
+++ b/Carthage/Checkouts/UnrarKit/Classes/URKFileInfo.m
@@ -40,7 +40,7 @@
_isEncryptedWithPassword = fileHeader->Flags & (1 << 2);
//_fileHasComment = fileHeader->Flags & (1 << 3)
- _isDirectory = fileHeader->Flags & RHDF_DIRECTORY;
+ _isDirectory = (fileHeader->Flags & RHDF_DIRECTORY) ? YES : NO;
}
return self;
diff --git a/Carthage/Checkouts/UnrarKit/Classes/UnrarKit.h b/Carthage/Checkouts/UnrarKit/Classes/UnrarKit.h
index 78db3b3..d2e390e 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/UnrarKit.h
+++ b/Carthage/Checkouts/UnrarKit/Classes/UnrarKit.h
@@ -15,5 +15,5 @@ FOUNDATION_EXPORT double UnrarKitVersionNumber;
FOUNDATION_EXPORT const unsigned char UnrarKitVersionString[];
-#import "URKArchive.h"
-#import "URKFileInfo.h"
+#import
+#import
diff --git a/Carthage/Checkouts/UnrarKit/Classes/UnrarKitMacros.h b/Carthage/Checkouts/UnrarKit/Classes/UnrarKitMacros.h
index aea9343..38e466f 100644
--- a/Carthage/Checkouts/UnrarKit/Classes/UnrarKitMacros.h
+++ b/Carthage/Checkouts/UnrarKit/Classes/UnrarKitMacros.h
@@ -60,7 +60,7 @@ __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000 \
#import
// Called from +[UnrarKit initialize] and +[URKArchiveTestCase setUp]
-extern os_log_t unrarkit_log; // Declared in URKArchive.m
+extern os_log_t unrarkit_log; // Declared in URKArchive.mm
extern BOOL unrarkitIsAtLeast10_13SDK; // Declared in URKArchive.m
#define URKLogInit() \
unrarkit_log = os_log_create("com.abbey-code.UnrarKit", "General"); \
diff --git a/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/project.pbxproj b/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/project.pbxproj
index 2d57e06..415b200 100644
--- a/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/project.pbxproj
+++ b/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/project.pbxproj
@@ -143,17 +143,15 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0930;
+ LastUpgradeCheck = 1200;
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "UnrarExample" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 1;
knownRegions = (
- English,
- Japanese,
- French,
- German,
+ en,
+ Base,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
@@ -257,6 +255,7 @@
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -272,14 +271,13 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"-lc++",
"-all_load",
);
- PREBINDING = NO;
SDKROOT = iphoneos;
};
name = Debug;
@@ -301,6 +299,7 @@
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -316,13 +315,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
OTHER_LDFLAGS = (
"-lc++",
"-all_load",
);
- PREBINDING = NO;
SDKROOT = iphoneos;
WARNING_CFLAGS = "-Wno-error=unused-command-line-argument";
};
diff --git a/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/xcshareddata/xcschemes/UnrarExample.xcscheme b/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/xcshareddata/xcschemes/UnrarExample.xcscheme
index 10829dc..1c9263a 100644
--- a/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/xcshareddata/xcschemes/UnrarExample.xcscheme
+++ b/Carthage/Checkouts/UnrarKit/Example/UnrarExample.xcodeproj/xcshareddata/xcschemes/UnrarExample.xcscheme
@@ -1,6 +1,6 @@
-
-
-
-
+
+
-
-
*CmtData)
{
if (!MainComment)
return false;
- SaveFilePos SavePos(*this);
+ int64 SavePos=Tell();
+ bool Success=DoGetComment(CmtData);
+ Seek(SavePos,SEEK_SET);
+ return Success;
+}
+
+bool Archive::DoGetComment(Array *CmtData)
+{
#ifndef SFX_MODULE
uint CmtLength;
if (Format==RARFMT14)
@@ -34,7 +41,7 @@ bool Archive::GetComment(Array *CmtData)
#ifndef SFX_MODULE
// Old style (RAR 2.9) comment header embedded into the main
// archive header.
- if (BrokenHeader)
+ if (BrokenHeader || CommHead.HeadSize *CmtData)
#else
UnpCmtLength=GetByte();
UnpCmtLength+=(GetByte()<<8);
+ if (CmtLength<2)
+ return false;
CmtLength-=2;
DataIO.SetCmt13Encryption();
CommHead.UnpVer=15;
@@ -85,15 +94,18 @@ bool Archive::GetComment(Array *CmtData)
byte *UnpData;
size_t UnpDataSize;
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
+ if (UnpDataSize>0)
+ {
#ifdef _WIN_ALL
- // If we ever decide to extend it to Android, we'll need to alloc
- // 4x memory for OEM to UTF-8 output here.
- OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
+ // If we ever decide to extend it to Android, we'll need to alloc
+ // 4x memory for OEM to UTF-8 output here.
+ OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
#endif
- CmtData->Alloc(UnpDataSize+1);
- memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
- CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
- CmtData->Alloc(wcslen(CmtData->Addr(0)));
+ CmtData->Alloc(UnpDataSize+1);
+ memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
+ CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
+ CmtData->Alloc(wcslen(CmtData->Addr(0)));
+ }
}
}
else
@@ -131,7 +143,7 @@ bool Archive::GetComment(Array *CmtData)
bool Archive::ReadCommentData(Array *CmtData)
{
Array CmtRaw;
- if (!ReadSubData(&CmtRaw,NULL))
+ if (!ReadSubData(&CmtRaw,NULL,false))
return false;
size_t CmtSize=CmtRaw.Size();
CmtRaw.Push(0);
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.cpp
index 6532869..8c5a1da 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.cpp
@@ -208,15 +208,16 @@ bool Archive::IsArchive(bool EnableBroken)
break;
}
- // This check allows to make RS based recovery even if password is incorrect.
- // But we should not do it for EnableBroken or we'll get 'not RAR archive'
+
+ // We should not do it for EnableBroken or we'll get 'not RAR archive'
// messages when extracting encrypted archives with wrong password.
if (FailedHeaderDecryption && !EnableBroken)
return false;
if (BrokenHeader || !StartFound) // Main archive header is corrupt or missing.
{
- uiMsg(UIERROR_MHEADERBROKEN,FileName);
+ if (!FailedHeaderDecryption) // If not reported a wrong password already.
+ uiMsg(UIERROR_MHEADERBROKEN,FileName);
if (!EnableBroken)
return false;
}
@@ -232,7 +233,7 @@ bool Archive::IsArchive(bool EnableBroken)
// immediately after IsArchive call.
if (HeadersLeft && (!SilentOpen || !Encrypted))
{
- SaveFilePos SavePos(*this);
+ int64 SavePos=Tell();
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
HEADER_TYPE SaveCurHeaderType=CurHeaderType;
@@ -261,6 +262,7 @@ bool Archive::IsArchive(bool EnableBroken)
CurBlockPos=SaveCurBlockPos;
NextBlockPos=SaveNextBlockPos;
CurHeaderType=SaveCurHeaderType;
+ Seek(SavePos,SEEK_SET);
}
if (!Volume || FirstVolume)
wcsncpyz(FirstVolumeName,FileName,ASIZE(FirstVolumeName));
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.hpp
index da59973..d9518f1 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/archive.hpp
@@ -20,13 +20,15 @@ enum ADDSUBDATA_FLAGS
ASDF_CRYPTIFHEADERS = 8 // Encrypt data after subheader only in -hp mode.
};
+// RAR5 headers must not exceed 2 MB.
+#define MAX_HEADER_SIZE_RAR5 0x200000
+
class Archive:public File
{
private:
void UpdateLatestTime(FileHeader *CurBlock);
void ConvertNameCase(wchar *Name);
void ConvertFileHeader(FileHeader *hd);
- void WriteBlock50(HEADER_TYPE HeaderType,BaseBlock *wb,bool OnlySetSize,bool NonFinalWrite);
size_t ReadHeader14();
size_t ReadHeader15();
size_t ReadHeader50();
@@ -34,8 +36,8 @@ class Archive:public File
void RequestArcPassword();
void UnexpEndArcMsg();
void BrokenHeaderMsg();
- void UnkEncVerMsg(const wchar *Name);
- void UnkEncVerMsg();
+ void UnkEncVerMsg(const wchar *Name,const wchar *Info);
+ bool DoGetComment(Array *CmtData);
bool ReadCommentData(Array *CmtData);
#if !defined(RAR_NOCRYPT)
@@ -63,8 +65,6 @@ class Archive:public File
size_t SearchBlock(HEADER_TYPE HeaderType);
size_t SearchSubBlock(const wchar *Type);
size_t SearchRR();
- void WriteBlock(HEADER_TYPE HeaderType,BaseBlock *wb=NULL,bool OnlySetSize=false,bool NonFinalWrite=false);
- void SetBlockSize(HEADER_TYPE HeaderType,BaseBlock *wb=NULL) {WriteBlock(HeaderType,wb,true);}
size_t ReadHeader();
void CheckArc(bool EnableBroken);
void CheckOpen(const wchar *Name);
@@ -81,8 +81,8 @@ class Archive:public File
int64 GetStartPos();
void AddSubData(byte *SrcData,uint64 DataSize,File *SrcFile,
const wchar *Name,uint Flags);
- bool ReadSubData(Array *UnpData,File *DestFile);
- HEADER_TYPE GetHeaderType() {return CurHeaderType;};
+ bool ReadSubData(Array *UnpData,File *DestFile,bool TestMode);
+ HEADER_TYPE GetHeaderType() {return CurHeaderType;}
RAROptions* GetRAROptions() {return Cmd;}
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
#if 0
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/arcread.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/arcread.cpp
index 4045b5e..b0cf39f 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/arcread.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/arcread.cpp
@@ -10,7 +10,10 @@ size_t Archive::ReadHeader()
CurBlockPos=Tell();
- size_t ReadSize;
+ // Other developers asked us to initialize it to suppress "may be used
+ // uninitialized" warning in code below in some compilers.
+ size_t ReadSize=0;
+
switch(Format)
{
#ifndef SFX_MODULE
@@ -113,9 +116,9 @@ void Archive::BrokenHeaderMsg()
}
-void Archive::UnkEncVerMsg(const wchar *Name)
+void Archive::UnkEncVerMsg(const wchar *Name,const wchar *Info)
{
- uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name);
+ uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name,Info);
ErrHandler.SetErrorCode(RARX_WARNING);
}
@@ -201,7 +204,7 @@ size_t Archive::ReadHeader15()
if (ShortBlock.HeaderType==HEAD_MAIN && (ShortBlock.Flags & MHD_COMMENT)!=0)
{
// Old style (up to RAR 2.9) main archive comment embedded into
- // the main archive header found. While we can read the entire
+ // the main archive header found. While we can read the entire
// ShortBlock.HeadSize here and remove this part of "if", it would be
// waste of memory, because we'll read and process this comment data
// in other function anyway and we do not need them here now.
@@ -227,7 +230,7 @@ size_t Archive::ReadHeader15()
Encrypted=(MainHead.Flags & MHD_PASSWORD)!=0;
Signed=MainHead.PosAV!=0 || MainHead.HighPosAV!=0;
MainHead.CommentInHeader=(MainHead.Flags & MHD_COMMENT)!=0;
-
+
// Only for encrypted 3.0+ archives. 2.x archives did not have this
// flag, so for non-encrypted archives, we'll set it later based on
// file attributes.
@@ -254,7 +257,7 @@ size_t Archive::ReadHeader15()
hd->WinSize=hd->Dir ? 0:0x10000<<((hd->Flags & LHD_WINDOWMASK)>>5);
hd->CommentInHeader=(hd->Flags & LHD_COMMENT)!=0;
hd->Version=(hd->Flags & LHD_VERSION)!=0;
-
+
hd->DataSize=Raw.Get4();
uint LowUnpSize=Raw.Get4();
hd->HostOS=Raw.Get1();
@@ -265,21 +268,21 @@ size_t Archive::ReadHeader15()
uint FileTime=Raw.Get4();
hd->UnpVer=Raw.Get1();
- // RAR15 did not use the special dictionary size to mark dirs.
- if (hd->UnpVer<20 && (hd->FileAttr & 0x10)!=0)
- hd->Dir=true;
-
hd->Method=Raw.Get1()-0x30;
size_t NameSize=Raw.Get2();
hd->FileAttr=Raw.Get4();
+ // RAR15 did not use the special dictionary size to mark dirs.
+ if (hd->UnpVer<20 && (hd->FileAttr & 0x10)!=0)
+ hd->Dir=true;
+
hd->CryptMethod=CRYPT_NONE;
if (hd->Encrypted)
switch(hd->UnpVer)
{
case 13: hd->CryptMethod=CRYPT_RAR13; break;
case 15: hd->CryptMethod=CRYPT_RAR15; break;
- case 20:
+ case 20:
case 26: hd->CryptMethod=CRYPT_RAR20; break;
default: hd->CryptMethod=CRYPT_RAR30; break;
}
@@ -301,7 +304,7 @@ size_t Archive::ReadHeader15()
}
hd->Inherited=!FileBlock && (hd->SubFlags & SUBHEAD_FLAGS_INHERITED)!=0;
-
+
hd->LargeFile=(hd->Flags & LHD_LARGE)!=0;
uint HighPackSize,HighUnpSize;
@@ -311,7 +314,7 @@ size_t Archive::ReadHeader15()
HighUnpSize=Raw.Get4();
hd->UnknownUnpSize=(LowUnpSize==0xffffffff && HighUnpSize==0xffffffff);
}
- else
+ else
{
HighPackSize=HighUnpSize=0;
// UnpSize equal to 0xffffffff without LHD_LARGE flag indicates
@@ -399,8 +402,8 @@ size_t Archive::ReadHeader15()
if (rmode & 4)
rlt.Second++;
rlt.Reminder=0;
- int count=rmode&3;
- for (int J=0;J. Wrong password can be intentionally provided
+ // in -p to not stop batch processing for encrypted archives.
+ bool GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
+
while (true) // Repeat the password prompt for wrong passwords.
{
RequestArcPassword();
@@ -572,11 +579,23 @@ size_t Archive::ReadHeader50()
// Verify password validity.
if (CryptHead.UsePswCheck && memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
{
- // This message is used by Android GUI and Windows GUI and SFX to
- // reset cached passwords. Update appropriate code if changed.
- uiMsg(UIWAIT_BADPSW,FileName);
+ if (GlobalPassword) // For -p or Ctrl+P.
+ {
+ // This message is used by Android GUI to reset cached passwords.
+ // Update appropriate code if changed.
+ uiMsg(UIERROR_BADPSW,FileName,FileName);
+ FailedHeaderDecryption=true;
+ ErrHandler.SetErrorCode(RARX_BADPWD);
+ return 0;
+ }
+ else // For passwords entered manually.
+ {
+ // This message is used by Android GUI and Windows GUI and SFX to
+ // reset cached passwords. Update appropriate code if changed.
+ uiMsg(UIWAIT_BADPSW,FileName,FileName);
+ Cmd->Password.Clean();
+ }
- Cmd->Password.Clean();
#ifdef RARDLL
// Avoid new requests for unrar.dll to prevent the infinite loop
// if app always returns the same password.
@@ -595,8 +614,8 @@ size_t Archive::ReadHeader50()
}
// Header size must not occupy more than 3 variable length integer bytes
- // resulting in 2 MB maximum header size, so here we read 4 byte CRC32
- // followed by 3 bytes or less of header size.
+ // resulting in 2 MB maximum header size (MAX_HEADER_SIZE_RAR5),
+ // so here we read 4 byte CRC32 followed by 3 bytes or less of header size.
const size_t FirstReadSize=7; // Smallest possible block size.
if (Raw.Read(FirstReadSize)CRYPT_VERSION)
{
- UnkEncVerMsg(FileName);
+ wchar Info[20];
+ swprintf(Info,ASIZE(Info),L"h%u",CryptVersion);
+ UnkEncVerMsg(FileName,Info);
return 0;
}
uint EncFlags=(uint)Raw.GetV();
@@ -693,9 +714,12 @@ size_t Archive::ReadHeader50()
CryptHead.Lg2Count=Raw.Get1();
if (CryptHead.Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX)
{
- UnkEncVerMsg(FileName);
+ wchar Info[20];
+ swprintf(Info,ASIZE(Info),L"hc%u",CryptHead.Lg2Count);
+ UnkEncVerMsg(FileName,Info);
return 0;
}
+
Raw.GetB(CryptHead.Salt,SIZE_SALT50);
if (CryptHead.UsePswCheck)
{
@@ -746,7 +770,7 @@ size_t Archive::ReadHeader50()
// to not break normal archive processing by calling function.
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
HEADER_TYPE SaveCurHeaderType=CurHeaderType;
-
+
QOpen.Init(this,false);
QOpen.Load(MainHead.QOpenOffset);
@@ -771,7 +795,7 @@ size_t Archive::ReadHeader50()
hd->PackSize=DataSize;
hd->FileFlags=(uint)Raw.GetV();
hd->UnpSize=Raw.GetV();
-
+
hd->UnknownUnpSize=(hd->FileFlags & FHFL_UNPUNKNOWN)!=0;
if (hd->UnknownUnpSize)
hd->UnpSize=INT64NDF;
@@ -798,6 +822,8 @@ size_t Archive::ReadHeader50()
// but it was already used in RAR 1.5 and Unpack needs to distinguish
// them.
hd->UnpVer=(CompInfo & 0x3f) + 50;
+ if (hd->UnpVer!=50) // Only 5.0 compression is known now.
+ hd->UnpVer=VER_UNKNOWN;
hd->HostOS=(byte)Raw.GetV();
size_t NameSize=(size_t)Raw.GetV();
@@ -856,7 +882,7 @@ size_t Archive::ReadHeader50()
RecoverySize=Header.RecSectionSize*Header.RecCount;
}
#endif
-
+
if (BadCRC) // Add the file name to broken header message displayed above.
uiMsg(UIERROR_FHEADERBROKEN,Archive::FileName,hd->FileName);
}
@@ -972,8 +998,12 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
{
FileHeader *hd=(FileHeader *)bb;
uint EncVersion=(uint)Raw->GetV();
- if (EncVersion > CRYPT_VERSION)
- UnkEncVerMsg(hd->FileName);
+ if (EncVersion>CRYPT_VERSION)
+ {
+ wchar Info[20];
+ swprintf(Info,ASIZE(Info),L"x%u",EncVersion);
+ UnkEncVerMsg(hd->FileName,Info);
+ }
else
{
uint Flags=(uint)Raw->GetV();
@@ -981,7 +1011,11 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
hd->UseHashKey=(Flags & FHEXTRA_CRYPT_HASHMAC)!=0;
hd->Lg2Count=Raw->Get1();
if (hd->Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX)
- UnkEncVerMsg(hd->FileName);
+ {
+ wchar Info[20];
+ swprintf(Info,ASIZE(Info),L"xc%u",hd->Lg2Count);
+ UnkEncVerMsg(hd->FileName,Info);
+ }
Raw->GetB(hd->Salt,SIZE_SALT50);
Raw->GetB(hd->InitV,SIZE_INITV);
if (hd->UsePswCheck)
@@ -1222,11 +1256,13 @@ size_t Archive::ReadHeader14()
Raw.Read(NameSize);
char FileName[NM];
- Raw.GetB((byte *)FileName,Min(NameSize,ASIZE(FileName)));
- FileName[NameSize]=0;
+ size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
+ Raw.GetB((byte *)FileName,ReadNameSize);
+ FileName[ReadNameSize]=0;
IntToExt(FileName,FileName,ASIZE(FileName));
CharToWide(FileName,FileHead.FileName,ASIZE(FileHead.FileName));
ConvertNameCase(FileHead.FileName);
+ ConvertFileHeader(&FileHead);
if (Raw.Size()!=0)
NextBlockPos=CurBlockPos+FileHead.HeadSize+FileHead.PackSize;
@@ -1273,7 +1309,7 @@ void Archive::ConvertAttributes()
if (mask == (mode_t) -1)
{
- // umask call returns the current umask value. Argument (022) is not
+ // umask call returns the current umask value. Argument (022) is not
// really important here.
mask = umask(022);
@@ -1350,8 +1386,8 @@ void Archive::ConvertFileHeader(FileHeader *hd)
// ':' in file names is allowed in Unix, but not in Windows.
// Even worse, file data will be written to NTFS stream on NTFS,
- // so automatic name correction on file create error in extraction
- // routine does not work. In Windows and DOS versions we better
+ // so automatic name correction on file create error in extraction
+ // routine does not work. In Windows and DOS versions we better
// replace ':' now.
if (*s==':')
*s='_';
@@ -1380,7 +1416,7 @@ int64 Archive::GetStartPos()
}
-bool Archive::ReadSubData(Array *UnpData,File *DestFile)
+bool Archive::ReadSubData(Array *UnpData,File *DestFile,bool TestMode)
{
if (BrokenHeader)
{
@@ -1428,6 +1464,7 @@ bool Archive::ReadSubData(Array *UnpData,File *DestFile)
SubDataIO.SetPackedSizeToRead(SubHead.PackSize);
SubDataIO.EnableShowProgress(false);
SubDataIO.SetFiles(this,DestFile);
+ SubDataIO.SetTestMode(TestMode);
SubDataIO.UnpVolume=SubHead.SplitAfter;
SubDataIO.SetSubHeader(&SubHead,NULL);
Unpack.SetDestSize(SubHead.UnpSize);
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/blake2s.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/blake2s.hpp
index 7dd7157..f88ef37 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/blake2s.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/blake2s.hpp
@@ -3,6 +3,7 @@
#define _RAR_BLAKE2_
#define BLAKE2_DIGEST_SIZE 32
+#define BLAKE2_THREADS_NUMBER 8
enum blake2s_constant
{
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.cpp
index 32b8412..74e565a 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.cpp
@@ -1,5 +1,8 @@
#include "rar.hpp"
+#include "cmdfilter.cpp"
+#include "cmdmix.cpp"
+
CommandData::CommandData()
{
Init();
@@ -120,6 +123,7 @@ void CommandData::ParseArg(wchar *Arg)
wchar CmdChar=toupperw(*Command);
bool Add=wcschr(L"AFUM",CmdChar)!=NULL;
bool Extract=CmdChar=='X' || CmdChar=='E';
+ bool Repair=CmdChar=='R' && Command[1]==0;
if (EndSeparator && !Add)
wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
else
@@ -130,15 +134,15 @@ void CommandData::ParseArg(wchar *Arg)
FindData FileData;
bool Found=FindFile::FastFind(Arg,&FileData);
if ((!Found || ListMode==RCLM_ACCEPT_LISTS) &&
- ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg))
+ ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg+1))
{
FileLists=true;
ReadTextFile(Arg+1,&FileArgs,false,true,FilelistCharset,true,true,true);
}
- else
- if (Found && FileData.IsDir && Extract && *ExtrPath==0)
+ else // We use 'destpath\' when extracting and reparing.
+ if (Found && FileData.IsDir && (Extract || Repair) && *ExtrPath==0)
{
wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
AddEndSlash(ExtrPath,ASIZE(ExtrPath));
@@ -280,17 +284,24 @@ void CommandData::ProcessSwitch(const wchar *Switch)
ClearArc=true;
break;
case 'D':
- AppendArcNameToPath=true;
+ if (Switch[2]==0)
+ AppendArcNameToPath=APPENDARCNAME_DESTPATH;
+ else
+ if (Switch[2]=='1')
+ AppendArcNameToPath=APPENDARCNAME_OWNDIR;
break;
#ifndef SFX_MODULE
case 'G':
if (Switch[2]=='-' && Switch[3]==0)
GenerateArcName=0;
else
- {
- GenerateArcName=true;
- wcsncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask));
- }
+ if (toupperw(Switch[2])=='F')
+ wcsncpyz(DefGenerateMask,Switch+3,ASIZE(DefGenerateMask));
+ else
+ {
+ GenerateArcName=true;
+ wcsncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask));
+ }
break;
#endif
case 'I':
@@ -302,7 +313,7 @@ void CommandData::ProcessSwitch(const wchar *Switch)
AddArcOnly=true;
break;
case 'P':
- wcscpy(ArcPath,Switch+2);
+ wcsncpyz(ArcPath,Switch+2,ASIZE(ArcPath));
break;
case 'S':
SyncFiles=true;
@@ -365,11 +376,11 @@ void CommandData::ProcessSwitch(const wchar *Switch)
default:
if (Switch[1]=='+')
{
- InclFileAttr|=GetExclAttr(Switch+2);
+ InclFileAttr|=GetExclAttr(Switch+2,InclDir);
InclAttrSet=true;
}
else
- ExclFileAttr|=GetExclAttr(Switch+1);
+ ExclFileAttr|=GetExclAttr(Switch+1,ExclDir);
break;
}
break;
@@ -407,9 +418,9 @@ void CommandData::ProcessSwitch(const wchar *Switch)
wcsncpyz(LogName,Switch[4]!=0 ? Switch+4:DefLogName,ASIZE(LogName));
break;
}
- if (wcsicomp(Switch+1,L"SND")==0)
+ if (wcsnicomp(Switch+1,L"SND",3)==0)
{
- Sound=true;
+ Sound=Switch[4]=='-' ? SOUND_NOTIFY_OFF : SOUND_NOTIFY_ON;
break;
}
if (wcsicomp(Switch+1,L"ERR")==0)
@@ -805,51 +816,19 @@ void CommandData::ProcessSwitch(const wchar *Switch)
ArcTime=ARCTIME_LATEST;
break;
case 'O':
- FileTimeBefore.SetAgeText(Switch+2);
+ SetTimeFilters(Switch+2,true,true);
break;
case 'N':
- FileTimeAfter.SetAgeText(Switch+2);
+ SetTimeFilters(Switch+2,false,true);
break;
case 'B':
- FileTimeBefore.SetIsoText(Switch+2);
+ SetTimeFilters(Switch+2,true,false);
break;
case 'A':
- FileTimeAfter.SetIsoText(Switch+2);
+ SetTimeFilters(Switch+2,false,false);
break;
case 'S':
- {
- EXTTIME_MODE Mode=EXTTIME_HIGH3;
- bool CommonMode=Switch[2]>='0' && Switch[2]<='4';
- if (CommonMode)
- Mode=(EXTTIME_MODE)(Switch[2]-'0');
- if (Mode==EXTTIME_HIGH1 || Mode==EXTTIME_HIGH2) // '2' and '3' not supported anymore.
- Mode=EXTTIME_HIGH3;
- if (Switch[2]=='-')
- Mode=EXTTIME_NONE;
- if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0)
- xmtime=xctime=xatime=Mode;
- else
- {
- if (Switch[3]>='0' && Switch[3]<='4')
- Mode=(EXTTIME_MODE)(Switch[3]-'0');
- if (Mode==EXTTIME_HIGH1 || Mode==EXTTIME_HIGH2) // '2' and '3' not supported anymore.
- Mode=EXTTIME_HIGH3;
- if (Switch[3]=='-')
- Mode=EXTTIME_NONE;
- switch(toupperw(Switch[2]))
- {
- case 'M':
- xmtime=Mode;
- break;
- case 'C':
- xctime=Mode;
- break;
- case 'A':
- xatime=Mode;
- break;
- }
- }
- }
+ SetStoreTimeMode(Switch+2);
break;
case '-':
Test=false;
@@ -897,7 +876,7 @@ void CommandData::ProcessSwitch(const wchar *Switch)
if (Switch[1]==0)
{
// If comment file is not specified, we read data from stdin.
- wcscpy(CommentFile,L"stdin");
+ wcsncpyz(CommentFile,L"stdin",ASIZE(CommentFile));
}
else
wcsncpyz(CommentFile,Switch+1,ASIZE(CommentFile));
@@ -922,309 +901,6 @@ void CommandData::BadSwitch(const wchar *Switch)
#endif
-void CommandData::OutTitle()
-{
- if (BareOutput || DisableCopyright)
- return;
-#if defined(__GNUC__) && defined(SFX_MODULE)
- mprintf(St(MCopyrightS));
-#else
-#ifndef SILENT
- static bool TitleShown=false;
- if (TitleShown)
- return;
- TitleShown=true;
-
- wchar Version[80];
- if (RARVER_BETA!=0)
- swprintf(Version,ASIZE(Version),L"%d.%02d %ls %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA);
- else
- swprintf(Version,ASIZE(Version),L"%d.%02d",RARVER_MAJOR,RARVER_MINOR);
-#if defined(_WIN_32) || defined(_WIN_64)
- wcsncatz(Version,L" ",ASIZE(Version));
-#endif
-#ifdef _WIN_32
- wcsncatz(Version,St(Mx86),ASIZE(Version));
-#endif
-#ifdef _WIN_64
- wcsncatz(Version,St(Mx64),ASIZE(Version));
-#endif
- if (PrintVersion)
- {
- mprintf(L"%s",Version);
- exit(0);
- }
- mprintf(St(MUCopyright),Version,RARVER_YEAR);
-#endif
-#endif
-}
-
-
-inline bool CmpMSGID(MSGID i1,MSGID i2)
-{
-#ifdef MSGID_INT
- return i1==i2;
-#else
- // If MSGID is const char*, we cannot compare pointers only.
- // Pointers to different instances of same string can differ,
- // so we need to compare complete strings.
- return wcscmp(i1,i2)==0;
-#endif
-}
-
-void CommandData::OutHelp(RAR_EXIT ExitCode)
-{
-#if !defined(SILENT)
- OutTitle();
- static MSGID Help[]={
-#ifdef SFX_MODULE
- // Console SFX switches definition.
- MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV
-#else
- // UnRAR switches definition.
- MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL,
- MCHelpCmdP,MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm,
- MCHelpSwAT,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,MCHelpSwAI,MCHelpSwAP,
- MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,
- MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
- MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
- MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
- MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSL,MCHelpSwSM,
- MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,
- MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,
- MCHelpSwY
-#endif
- };
-
- for (uint I=0;IRewind();
- while (Args->GetString(CurMask,ASIZE(CurMask)))
- {
- wchar *LastMaskChar=PointToLastChar(CurMask);
- bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only.
-
- if (Dir)
- {
- // CheckName is a directory.
- if (DirMask)
- {
- // We process the directory and have the directory exclusion mask.
- // So let's convert "mask\" to "mask" and process it normally.
-
- *LastMaskChar=0;
- }
- else
- {
- // REMOVED, we want -npath\* to match empty folders too.
- // If mask has wildcards in name part and does not have the trailing
- // '\' character, we cannot use it for directories.
-
- // if (IsWildcard(PointToName(CurMask)))
- // continue;
- }
- }
- else
- {
- // If we process a file inside of directory excluded by "dirmask\".
- // we want to exclude such file too. So we convert "dirmask\" to
- // "dirmask\*". It is important for operations other than archiving
- // with -x. When archiving with -x, directory matched by "dirmask\"
- // is excluded from further scanning.
-
- if (DirMask)
- wcsncatz(CurMask,L"*",ASIZE(CurMask));
- }
-
-#ifndef SFX_MODULE
- if (CheckFullPath && IsFullPath(CurMask))
- {
- // We do not need to do the special "*\" processing here, because
- // unlike the "else" part of this "if", now we convert names to full
- // format, so they all include the path, which is matched by "*\"
- // correctly. Moreover, removing "*\" from mask would break
- // the comparison, because now all names have the path.
-
- if (*FullName==0)
- ConvertNameToFull(CheckName,FullName,ASIZE(FullName));
- if (CmpName(CurMask,FullName,MatchMode))
- return true;
- }
- else
-#endif
- {
- wchar NewName[NM+2],*CurName=Name;
-
- // Important to convert before "*\" check below, so masks like
- // d:*\something are processed properly.
- wchar *CmpMask=ConvertPath(CurMask,NULL);
-
- if (CmpMask[0]=='*' && IsPathDiv(CmpMask[1]))
- {
- // We want "*\name" to match 'name' not only in subdirectories,
- // but also in the current directory. We convert the name
- // from 'name' to '.\name' to be matched by "*\" part even if it is
- // in current directory.
- NewName[0]='.';
- NewName[1]=CPATHDIVIDER;
- wcsncpyz(NewName+2,Name,ASIZE(NewName)-2);
- CurName=NewName;
- }
-
- if (CmpName(CmpMask,CurName,MatchMode))
- return true;
- }
- }
- return false;
-}
-
-
-#ifndef SFX_MODULE
-// Now this function performs only one task and only in Windows version:
-// it skips symlinks to directories if -e1024 switch is specified.
-// Symlinks are skipped in ScanTree class, so their entire contents
-// is skipped too. Without this function we would check the attribute
-// only directly before archiving, so we would skip the symlink record,
-// but not the contents of symlinked directory.
-bool CommandData::ExclDirByAttr(uint FileAttr)
-{
-#ifdef _WIN_ALL
- if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0 &&
- (ExclFileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0)
- return true;
-#endif
- return false;
-}
-#endif
-
-
-
-
-#ifndef SFX_MODULE
-// Return 'true' if we need to exclude the file from processing.
-bool CommandData::TimeCheck(RarTime &ft)
-{
- if (FileTimeBefore.IsSet() && ft>=FileTimeBefore)
- return true;
- if (FileTimeAfter.IsSet() && ft<=FileTimeAfter)
- return true;
- return false;
-}
-#endif
-
-
-#ifndef SFX_MODULE
-// Return 'true' if we need to exclude the file from processing.
-bool CommandData::SizeCheck(int64 Size)
-{
- if (FileSizeLess!=INT64NDF && Size>=FileSizeLess)
- return(true);
- if (FileSizeMore!=INT64NDF && Size<=FileSizeMore)
- return(true);
- return(false);
-}
-#endif
-
-
-
-
-int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
- wchar *MatchedArg,uint MatchedArgSize)
-{
- if (MatchedArg!=NULL && MatchedArgSize>0)
- *MatchedArg=0;
-// if (wcslen(FileHead.FileName)>=NM)
-// return 0;
- bool Dir=FileHead.Dir;
- if (ExclCheck(FileHead.FileName,Dir,false,true))
- return 0;
-#ifndef SFX_MODULE
- if (TimeCheck(FileHead.mtime))
- return 0;
- if ((FileHead.FileAttr & ExclFileAttr)!=0 || InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0)
- return 0;
- if (!Dir && SizeCheck(FileHead.UnpSize))
- return 0;
-#endif
- wchar *ArgName;
- FileArgs.Rewind();
- for (int StringCount=1;(ArgName=FileArgs.GetString())!=NULL;StringCount++)
- if (CmpName(ArgName,FileHead.FileName,MatchType))
- {
- if (ExactMatch!=NULL)
- *ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
- if (MatchedArg!=NULL)
- wcsncpyz(MatchedArg,ArgName,MatchedArgSize);
- return StringCount;
- }
- return 0;
-}
-
-
void CommandData::ProcessCommand()
{
#ifndef SFX_MODULE
@@ -1255,7 +931,10 @@ void CommandData::ProcessCommand()
if (wcschr(L"AFUMD",*Command)==NULL)
{
if (GenerateArcName)
- GenerateArchiveName(ArcName,ASIZE(ArcName),GenerateMask,false);
+ {
+ const wchar *Mask=*GenerateMask!=0 ? GenerateMask:DefGenerateMask;
+ GenerateArchiveName(ArcName,ASIZE(ArcName),Mask,false);
+ }
StringList ArcMasks;
ArcMasks.AddString(ArcName);
@@ -1274,7 +953,6 @@ void CommandData::ProcessCommand()
case 'X':
case 'E':
case 'T':
- case 'I':
{
CmdExtract Extract(this);
Extract.DoExtract();
@@ -1317,7 +995,7 @@ bool CommandData::IsSwitch(int Ch)
#ifndef SFX_MODULE
-uint CommandData::GetExclAttr(const wchar *Str)
+uint CommandData::GetExclAttr(const wchar *Str,bool &Dir)
{
if (IsDigit(*Str))
return wcstol(Str,NULL,0);
@@ -1327,10 +1005,10 @@ uint CommandData::GetExclAttr(const wchar *Str)
{
switch(toupperw(*Str))
{
-#ifdef _UNIX
case 'D':
- Attr|=S_IFDIR;
+ Dir=true;
break;
+#ifdef _UNIX
case 'V':
Attr|=S_IFCHR;
break;
@@ -1344,9 +1022,6 @@ uint CommandData::GetExclAttr(const wchar *Str)
case 'S':
Attr|=0x4;
break;
- case 'D':
- Attr|=0x10;
- break;
case 'A':
Attr|=0x20;
break;
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.hpp
index e12d4fb..0c6d148 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/cmddata.hpp
@@ -6,13 +6,19 @@
enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS};
+enum IS_PROCESS_FILE_FLAGS {IPFF_EXCLUDE_PARENT=1};
+
class CommandData:public RAROptions
{
private:
void ProcessSwitchesString(const wchar *Str);
void ProcessSwitch(const wchar *Switch);
void BadSwitch(const wchar *Switch);
- uint GetExclAttr(const wchar *Str);
+ uint GetExclAttr(const wchar *Str,bool &Dir);
+#if !defined(SFX_MODULE)
+ void SetTimeFilters(const wchar *Mod,bool Before,bool Age);
+ void SetStoreTimeMode(const wchar *S);
+#endif
bool FileLists;
bool NoMoreSwitches;
@@ -34,11 +40,11 @@ class CommandData:public RAROptions
bool ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList);
static bool CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode);
bool ExclDirByAttr(uint FileAttr);
- bool TimeCheck(RarTime &ft);
+ bool TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta);
bool SizeCheck(int64 Size);
bool AnyFiltersActive();
- int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH,
- wchar *MatchedArg=NULL,uint MatchedArgSize=0);
+ int IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
+ bool Flags,wchar *MatchedArg,uint MatchedArgSize);
void ProcessCommand();
void AddArcName(const wchar *Name);
bool GetArcName(wchar *Name,int MaxSize);
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/crc.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/crc.cpp
index 1097f4c..cf23bbf 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/crc.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/crc.cpp
@@ -73,7 +73,7 @@ uint CRC32(uint StartCRC,const void *Addr,size_t Size)
crc_tables[5][(byte)(StartCRC >> 16)] ^
crc_tables[4][(byte)(StartCRC >> 24)] ^
crc_tables[3][(byte) NextData ] ^
- crc_tables[2][(byte)(NextData >>8 ) ] ^
+ crc_tables[2][(byte)(NextData >> 8) ] ^
crc_tables[1][(byte)(NextData >> 16)] ^
crc_tables[0][(byte)(NextData >> 24)];
}
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/crypt3.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/crypt3.cpp
index 4840648..fe3bf97 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/crypt3.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/crypt3.cpp
@@ -28,8 +28,8 @@ void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,co
sha1_context c;
sha1_init(&c);
- const int HashRounds=0x40000;
- for (int I=0;I>(J*8));
KDF3Cache[KDF3CachePos].Pwd=*Password;
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.cpp
index b5eada5..61a68b4 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.cpp
@@ -42,6 +42,7 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
Data->Cmd.DllError=0;
Data->OpenMode=r->OpenMode;
Data->Cmd.FileArgs.AddString(L"*");
+ Data->Cmd.KeepBroken=(r->OpFlags&ROADOF_KEEPBROKEN)!=0;
char AnsiArcName[NM];
*AnsiArcName=0;
@@ -94,36 +95,50 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
r->Flags=0;
if (Data->Arc.Volume)
- r->Flags|=0x01;
+ r->Flags|=ROADF_VOLUME;
+ if (Data->Arc.MainComment)
+ r->Flags|=ROADF_COMMENT;
if (Data->Arc.Locked)
- r->Flags|=0x04;
+ r->Flags|=ROADF_LOCK;
if (Data->Arc.Solid)
- r->Flags|=0x08;
+ r->Flags|=ROADF_SOLID;
if (Data->Arc.NewNumbering)
- r->Flags|=0x10;
+ r->Flags|=ROADF_NEWNUMBERING;
if (Data->Arc.Signed)
- r->Flags|=0x20;
+ r->Flags|=ROADF_SIGNED;
if (Data->Arc.Protected)
- r->Flags|=0x40;
+ r->Flags|=ROADF_RECOVERY;
if (Data->Arc.Encrypted)
- r->Flags|=0x80;
+ r->Flags|=ROADF_ENCHEADERS;
if (Data->Arc.FirstVolume)
- r->Flags|=0x100;
+ r->Flags|=ROADF_FIRSTVOLUME;
Array CmtDataW;
if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtDataW))
{
- Array CmtData(CmtDataW.Size()*4+1);
- memset(&CmtData[0],0,CmtData.Size());
- WideToChar(&CmtDataW[0],&CmtData[0],CmtData.Size()-1);
- size_t Size=strlen(&CmtData[0])+1;
+ if (r->CmtBufW!=NULL)
+ {
+ CmtDataW.Push(0);
+ size_t Size=wcslen(&CmtDataW[0])+1;
- r->Flags|=2;
- r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
- r->CmtSize=(uint)Min(Size,r->CmtBufSize);
- memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
- if (Size<=r->CmtBufSize)
- r->CmtBuf[r->CmtSize-1]=0;
+ r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
+ r->CmtSize=(uint)Min(Size,r->CmtBufSize);
+ memcpy(r->CmtBufW,&CmtDataW[0],(r->CmtSize-1)*sizeof(*r->CmtBufW));
+ r->CmtBufW[r->CmtSize-1]=0;
+ }
+ else
+ if (r->CmtBuf!=NULL)
+ {
+ Array CmtData(CmtDataW.Size()*4+1);
+ memset(&CmtData[0],0,CmtData.Size());
+ WideToChar(&CmtDataW[0],&CmtData[0],CmtData.Size()-1);
+ size_t Size=strlen(&CmtData[0])+1;
+
+ r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
+ r->CmtSize=(uint)Min(Size,r->CmtBufSize);
+ memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
+ r->CmtBuf[r->CmtSize-1]=0;
+ }
}
else
r->CmtState=r->CmtSize=0;
@@ -253,10 +268,7 @@ int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
D->UnpSize=uint(hd->UnpSize & 0xffffffff);
D->UnpSizeHigh=uint(hd->UnpSize>>32);
D->HostOS=hd->HSType==HSYS_WINDOWS ? HOST_WIN32:HOST_UNIX;
- if (Data->Arc.Format==RARFMT50)
- D->UnpVer=Data->Arc.FileHead.UnpVer==0 ? 50 : 200; // If it is not 0, just set it to something big.
- else
- D->UnpVer=Data->Arc.FileHead.UnpVer;
+ D->UnpVer=Data->Arc.FileHead.UnpVer;
D->FileCRC=hd->FileHash.CRC32;
D->FileTime=hd->mtime.GetDos();
@@ -372,7 +384,7 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa
if (DestNameW!=NULL)
wcsncpyz(Data->Cmd.DllDestName,DestNameW,ASIZE(Data->Cmd.DllDestName));
- wcscpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T");
+ wcsncpyz(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T",ASIZE(Data->Cmd.Command));
Data->Cmd.Test=Operation!=RAR_EXTRACT;
bool Repeat=false;
Data->Extract.ExtractCurrentFile(Data->Arc,Data->HeaderSize,Repeat);
@@ -439,16 +451,16 @@ void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataPro
}
-#ifndef RAR_NOCRYPT
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
{
+#ifndef RAR_NOCRYPT
DataSet *Data=(DataSet *)hArcData;
wchar PasswordW[MAXPASSWORD];
GetWideName(Password,NULL,PasswordW,ASIZE(PasswordW));
Data->Cmd.Password.Set(PasswordW);
cleandata(PasswordW,sizeof(PasswordW));
-}
#endif
+}
int PASCAL RARGetDllVersion()
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.def b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.def
index 660f69b..3c9a2c8 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.def
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.def
@@ -5,6 +5,7 @@ EXPORTS
RARReadHeader
RARReadHeaderEx
RARProcessFile
+ RARProcessFileW
RARSetCallback
RARSetChangeVolProc
RARSetProcessDataProc
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.hpp
index 7f82906..c785ff1 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.hpp
@@ -1,7 +1,7 @@
#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_
-#pragma pack(1)
+#pragma pack(push, 1)
#define ERAR_SUCCESS 0
#define ERAR_END_ARCHIVE 10
@@ -135,6 +135,8 @@ typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM
#define ROADF_ENCHEADERS 0x0080
#define ROADF_FIRSTVOLUME 0x0100
+#define ROADOF_KEEPBROKEN 0x0001
+
struct RAROpenArchiveDataEx
{
char *ArcName;
@@ -148,7 +150,9 @@ struct RAROpenArchiveDataEx
unsigned int Flags;
UNRARCALLBACK Callback;
LPARAM UserData;
- unsigned int Reserved[28];
+ unsigned int OpFlags;
+ wchar_t *CmtBufW;
+ unsigned int Reserved[25];
};
enum UNRARCALLBACK_MESSAGES {
@@ -180,6 +184,6 @@ int PASCAL RARGetDllVersion();
}
#endif
-#pragma pack()
+#pragma pack(pop)
#endif
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.rc b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.rc
index c28ecfb..7ff2021 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.rc
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/dll.rc
@@ -2,8 +2,8 @@
#include
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 5, 60, 3, 2672
-PRODUCTVERSION 5, 60, 3, 2672
+FILEVERSION 5, 91, 100, 3470
+PRODUCTVERSION 5, 91, 100, 3470
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@@ -14,9 +14,9 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
- VALUE "FileVersion", "5.60.3\0"
- VALUE "ProductVersion", "5.60.3\0"
- VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2018\0"
+ VALUE "FileVersion", "5.91.0\0"
+ VALUE "ProductVersion", "5.91.0\0"
+ VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2020\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
}
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.cpp
index b2f76a8..c86d176 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.cpp
@@ -158,6 +158,7 @@ void ErrorHandler::OpenErrorMsg(const wchar *FileName)
void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
{
+ Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
SysErrMsg();
SetErrorCode(RARX_OPEN);
@@ -270,6 +271,7 @@ void _stdfunction ProcessSignal(int SigType)
#endif
ErrHandler.UserBreak=true;
+ ErrHandler.SetDisableShutdown();
mprintf(St(MBreak));
#ifdef _WIN_ALL
@@ -293,7 +295,7 @@ void _stdfunction ProcessSignal(int SigType)
#endif
#if defined(_WIN_ALL) && !defined(_MSC_VER)
- // never reached, just to avoid a compiler warning
+ // Never reached, just to avoid a compiler warning
return TRUE;
#endif
}
@@ -327,7 +329,7 @@ void ErrorHandler::Throw(RAR_EXIT Code)
bool ErrorHandler::GetSysErrMsg(wchar *Msg,size_t Size)
{
-#if !defined(SFX_MODULE) && !defined(SILENT)
+#ifndef SILENT
#ifdef _WIN_ALL
int ErrType=GetLastError();
if (ErrType!=0)
@@ -360,7 +362,7 @@ void ErrorHandler::SysErrMsg()
return;
#ifdef _WIN_ALL
wchar *CurMsg=Msg;
- while (CurMsg!=NULL)
+ while (CurMsg!=NULL) // Print string with \r\n as several strings to multiple lines.
{
while (*CurMsg=='\r' || *CurMsg=='\n')
CurMsg++;
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.hpp
index c360c6c..3455dac 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/errhnd.hpp
@@ -56,11 +56,12 @@ class ErrorHandler
uint GetErrorCount() {return ErrCount;}
void SetSignalHandlers(bool Enable);
void Throw(RAR_EXIT Code);
- void SetSilent(bool Mode) {Silent=Mode;};
+ void SetSilent(bool Mode) {Silent=Mode;}
bool GetSysErrMsg(wchar *Msg,size_t Size);
void SysErrMsg();
int GetSystemErrorCode();
void SetSystemErrorCode(int Code);
+ void SetDisableShutdown() {DisableShutdown=true;}
bool IsShutdownEnabled() {return !DisableShutdown;}
bool UserBreak; // Ctrl+Break is pressed.
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.cpp
index 99cca62..76ee2d4 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.cpp
@@ -40,6 +40,8 @@ void CmdExtract::DoExtract()
{
if (Cmd->ManualPassword)
Cmd->Password.Clean(); // Clean user entered password before processing next archive.
+
+ ReconstructDone=false; // Must be reset here, not in ExtractArchiveInit().
while (true)
{
EXTRACT_ARC_CODE Code=ExtractArchive();
@@ -59,7 +61,11 @@ void CmdExtract::DoExtract()
{
if (!PasswordCancelled)
uiMsg(UIERROR_NOFILESTOEXTRACT,ArcName);
- ErrHandler.SetErrorCode(RARX_NOFILES);
+
+ // Other error codes may explain a reason of "no files extracted" clearer,
+ // so set it only if no other errors found (wrong mask set by user).
+ if (ErrHandler.GetErrorCode()==RARX_SUCCESS)
+ ErrHandler.SetErrorCode(RARX_NOFILES);
}
else
if (!Cmd->DisableDone)
@@ -83,13 +89,12 @@ void CmdExtract::ExtractArchiveInit(Archive &Arc)
FirstFile=true;
#endif
- PasswordAll=(Cmd->Password.IsSet());
+ GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
DataIO.UnpVolume=false;
PrevProcessed=false;
AllMatchesExact=true;
- ReconstructDone=false;
AnySolidDataUnpackedWell=false;
StartTime.SetCurrentTime();
@@ -157,7 +162,7 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive()
// This size is necessary to display the correct total progress indicator.
wchar NextName[NM];
- wcscpy(NextName,Arc.FileName);
+ wcsncpyz(NextName,Arc.FileName,ASIZE(NextName));
while (true)
{
@@ -257,15 +262,17 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
if (HeaderType==HEAD_ENDARC)
if (Arc.EndArcHead.NextVolume)
{
-#ifndef NOVOLUME
+#ifdef NOVOLUME
+ return false;
+#else
if (!MergeArchive(Arc,&DataIO,false,Command))
{
ErrHandler.SetErrorCode(RARX_WARNING);
return false;
}
-#endif
Arc.Seek(Arc.CurBlockPos,SEEK_SET);
return true;
+#endif
}
else
return false;
@@ -294,7 +301,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
bool EqualNames=false;
wchar MatchedArg[NM];
- int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,MatchedArg,ASIZE(MatchedArg));
+ int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,0,MatchedArg,ASIZE(MatchedArg));
bool MatchFound=MatchNumber!=0;
#ifndef SFX_MODULE
if (Cmd->ExclPath==EXCL_BASEPATH)
@@ -319,6 +326,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
if (wcsicomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
{
+ wcsncpyz(Cmd->ArcName,ArcName,ASIZE(ArcName)); // For GUI "Delete archive after extraction".
// If first volume name does not match the current name and if such
// volume name really exists, let's unpack from this first volume.
Repeat=true;
@@ -340,7 +348,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
#endif
wchar ArcFileName[NM];
- ConvertPath(Arc.FileHead.FileName,ArcFileName);
+ ConvertPath(Arc.FileHead.FileName,ArcFileName,ASIZE(ArcFileName));
if (Arc.FileHead.Version)
{
@@ -468,17 +476,17 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
memcmp(Arc.FileHead.PswCheck,PswCheck,SIZE_PSWCHECK)!=0 &&
!Arc.BrokenHeader)
{
- if (PasswordAll) // For -p or Ctrl+P.
+ if (GlobalPassword) // For -p or Ctrl+P to avoid the infinite loop.
{
// This message is used by Android GUI to reset cached passwords.
// Update appropriate code if changed.
- uiMsg(UIERROR_BADPSW,ArcFileName);
+ uiMsg(UIERROR_BADPSW,Arc.FileName,ArcFileName);
}
else // For passwords entered manually.
{
// This message is used by Android GUI and Windows GUI and SFX to
// reset cached passwords. Update appropriate code if changed.
- uiMsg(UIWAIT_BADPSW,ArcFileName);
+ uiMsg(UIWAIT_BADPSW,Arc.FileName,ArcFileName);
Cmd->Password.Clean();
// Avoid new requests for unrar.dll to prevent the infinite loop
@@ -609,11 +617,14 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
}
#endif
- if (!TestMode && !Arc.BrokenHeader &&
- (Arc.FileHead.PackSize<<11)>Arc.FileHead.UnpSize &&
+ uint64 Preallocated=0;
+ if (!TestMode && !Arc.BrokenHeader && Arc.FileHead.UnpSize>1000000 &&
+ Arc.FileHead.PackSize*1024>Arc.FileHead.UnpSize &&
(Arc.FileHead.UnpSize<100000000 || Arc.FileLength()>Arc.FileHead.PackSize))
+ {
CurFile.Prealloc(Arc.FileHead.UnpSize);
-
+ Preallocated=Arc.FileHead.UnpSize;
+ }
CurFile.SetAllowDelete(!Cmd->KeepBroken);
bool FileCreateMode=!TestMode && !SkipSolid && Command!='P';
@@ -725,37 +736,52 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
else
mprintf(L"\b\b\b\b\b ");
+ // If we successfully unpacked a hard link, we wish to set its file
+ // attributes. Hard link shares file metadata with link target,
+ // so we do not need to set link time or owner. But when we overwrite
+ // an existing link, we can call PrepareToDelete(), which affects
+ // link target attributes as well. So we set link attributes to restore
+ // both target and link attributes if PrepareToDelete() changed them.
+ bool SetAttrOnly=LinkEntry && Arc.FileHead.RedirType==FSREDIR_HARDLINK && LinkSuccess;
+
if (!TestMode && (Command=='X' || Command=='E') &&
- (!LinkEntry || Arc.FileHead.RedirType==FSREDIR_FILECOPY && LinkSuccess) &&
+ (!LinkEntry || SetAttrOnly || Arc.FileHead.RedirType==FSREDIR_FILECOPY && LinkSuccess) &&
(!BrokenFile || Cmd->KeepBroken))
{
- // We could preallocate more space that really written to broken file.
- if (BrokenFile)
- CurFile.Truncate();
+ // Below we use DestFileName instead of CurFile.FileName,
+ // so we can set file attributes also for hard links, which do not
+ // have the open CurFile. These strings are the same for other items.
-#if defined(_WIN_ALL) || defined(_EMX)
- if (Cmd->ClearArc)
- Arc.FileHead.FileAttr&=~FILE_ATTRIBUTE_ARCHIVE;
-#endif
+ if (!SetAttrOnly)
+ {
+ // We could preallocate more space that really written to broken file
+ // or file with crafted header.
+ if (Preallocated>0 && (BrokenFile || DataIO.CurUnpWrite!=Preallocated))
+ CurFile.Truncate();
- CurFile.SetOpenFileTime(
- Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
- Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.FileHead.ctime,
- Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
- CurFile.Close();
+ CurFile.SetOpenFileTime(
+ Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
+ Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.FileHead.ctime,
+ Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
+ CurFile.Close();
+
+ SetFileHeaderExtra(Cmd,Arc,DestFileName);
+
+ CurFile.SetCloseFileTime(
+ Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
+ Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
+ }
+
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
if (Cmd->SetCompressedAttr &&
(Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0)
- SetFileCompression(CurFile.FileName,true);
+ SetFileCompression(DestFileName,true);
+ if (Cmd->ClearArc)
+ Arc.FileHead.FileAttr&=~FILE_ATTRIBUTE_ARCHIVE;
#endif
- SetFileHeaderExtra(Cmd,Arc,CurFile.FileName);
-
- CurFile.SetCloseFileTime(
- Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.FileHead.mtime,
- Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.FileHead.atime);
- if (!Cmd->IgnoreGeneralAttr && !SetFileAttr(CurFile.FileName,Arc.FileHead.FileAttr))
- uiMsg(UIERROR_FILEATTR,Arc.FileName,CurFile.FileName);
+ if (!Cmd->IgnoreGeneralAttr && !SetFileAttr(DestFileName,Arc.FileHead.FileAttr))
+ uiMsg(UIERROR_FILEATTR,Arc.FileName,DestFileName);
PrevProcessed=true;
}
@@ -846,9 +872,12 @@ void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *De
}
#ifndef SFX_MODULE
- if (Cmd->AppendArcNameToPath)
+ if (Cmd->AppendArcNameToPath!=APPENDARCNAME_NONE)
{
- wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
+ if (Cmd->AppendArcNameToPath==APPENDARCNAME_DESTPATH)
+ wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
+ else
+ wcsncpyz(DestName,Arc.FirstVolumeName,DestSize); // To archive own dir.
SetExt(DestName,NULL,DestSize);
AddEndSlash(DestName,DestSize);
}
@@ -961,14 +990,18 @@ bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password)/* || !Cmd->Password.IsSet()*/)
{
// Suppress "test is ok" message if user cancelled the password prompt.
- uiMsg(UIERROR_INCERRCOUNT);
+// 2019.03.23: If some archives are tested ok and prompt is cancelled for others,
+// do we really need to suppress "test is ok"? Also if we set an empty password
+// and "Use for all archives" in WinRAR Ctrl+P and skip some encrypted archives.
+// We commented out this UIERROR_INCERRCOUNT for now.
+// uiMsg(UIERROR_INCERRCOUNT);
return false;
}
Cmd->ManualPassword=true;
}
#if !defined(SILENT)
else
- if (!PasswordAll && !Arc.FileHead.Solid)
+ if (!GlobalPassword && !Arc.FileHead.Solid)
{
eprintf(St(MUseCurPsw),ArcFileName);
switch(Cmd->AllYes ? 1 : Ask(St(MYesNoAll)))
@@ -980,7 +1013,7 @@ bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
return false;
break;
case 3:
- PasswordAll=true;
+ GlobalPassword=true;
break;
}
}
@@ -1077,7 +1110,7 @@ void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName)
{
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
if (Cmd->SetCompressedAttr &&
- (Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
+ (Arc.FileHead.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()!=WNT_NONE)
SetFileCompression(DestFileName,true);
#endif
SetFileHeaderExtra(Cmd,Arc,DestFileName);
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.hpp
index 85a21f5..325928d 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/extract.hpp
@@ -43,7 +43,7 @@ class CmdExtract
wchar ArcName[NM];
- bool PasswordAll;
+ bool GlobalPassword;
bool PrevProcessed; // If previous file was successfully extracted or tested.
wchar DestFileName[NM];
bool PasswordCancelled;
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.cpp
index e2bb42a..e506fde 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.cpp
@@ -13,6 +13,7 @@ File::File()
OpenShared=false;
AllowDelete=true;
AllowExceptions=true;
+ PreserveAtime=false;
#ifdef _WIN_ALL
NoSequentialRead=false;
CreateMode=FMF_UNDEFINED;
@@ -56,6 +57,9 @@ bool File::Open(const wchar *Name,uint Mode)
if (OpenShared)
ShareMode|=FILE_SHARE_WRITE;
uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
+ FindData FD;
+ if (PreserveAtime)
+ Access|=FILE_WRITE_ATTRIBUTES; // Needed to preserve atime.
hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
DWORD LastError;
@@ -86,6 +90,11 @@ bool File::Open(const wchar *Name,uint Mode)
}
if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND)
ErrorType=FILE_NOTFOUND;
+ if (PreserveAtime && hNewFile!=FILE_BAD_HANDLE)
+ {
+ FILETIME ft={0xffffffff,0xffffffff}; // This value prevents atime modification.
+ SetFileTime(hNewFile,NULL,&ft,NULL);
+ }
#else
int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY);
@@ -94,6 +103,11 @@ bool File::Open(const wchar *Name,uint Mode)
#if defined(_AIX) && defined(_LARGE_FILE_API)
flags|=O_LARGEFILE;
#endif
+#endif
+ // NDK r20 has O_NOATIME, but fails to create files with it in Android 7+.
+#if defined(O_NOATIME)
+ if (PreserveAtime)
+ flags|=O_NOATIME;
#endif
char NameA[NM];
WideToChar(Name,NameA,ASIZE(NameA));
@@ -230,7 +244,7 @@ bool File::Close()
{
#ifdef _WIN_ALL
// We use the standard system handle for stdout in Windows
- // and it must not be closed here.
+ // and it must not be closed here.
if (HandleType==FILE_HANDLENORMAL)
Success=CloseHandle(hFile)==TRUE;
#else
@@ -271,7 +285,7 @@ bool File::Rename(const wchar *NewName)
Success=RenameFile(FileName,NewName);
if (Success)
- wcscpy(FileName,NewName);
+ wcsncpyz(FileName,NewName,ASIZE(FileName));
return Success;
}
@@ -387,7 +401,7 @@ int File::Read(void *Data,size_t Size)
}
break;
}
- return ReadSize;
+ return ReadSize; // It can return -1 only if AllowExceptions is disabled.
}
@@ -670,9 +684,11 @@ void File::GetOpenFileTime(RarTime *ft)
int64 File::FileLength()
{
- SaveFilePos SavePos(*this);
+ int64 SavePos=Tell();
Seek(0,SEEK_END);
- return Tell();
+ int64 Length=Tell();
+ Seek(SavePos,SEEK_SET);
+ return Length;
}
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.hpp
index f99336a..a343ce6 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/file.hpp
@@ -62,6 +62,7 @@ class File
bool NoSequentialRead;
uint CreateMode;
#endif
+ bool PreserveAtime;
protected:
bool OpenShared; // Set by 'Archive' class.
public:
@@ -99,7 +100,7 @@ class File
void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
static void SetCloseFileTimeByName(const wchar *Name,RarTime *ftm,RarTime *fta);
void GetOpenFileTime(RarTime *ft);
- virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;}; // 'virtual' for MultiFile class.
+ virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;} // 'virtual' for MultiFile class.
int64 FileLength();
void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
FILE_HANDLETYPE GetHandleType() {return HandleType;}
@@ -114,6 +115,7 @@ class File
#ifdef _WIN_ALL
void RemoveSequentialFlag() {NoSequentialRead=true;}
#endif
+ void SetPreserveAtime(bool Preserve) {PreserveAtime=Preserve;}
#ifdef _UNIX
int GetFD()
{
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/filefn.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/filefn.cpp
index 4eb7b9b..57a334d 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/filefn.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/filefn.cpp
@@ -348,7 +348,7 @@ wchar *MkTemp(wchar *Name,size_t MaxSize)
swprintf(RndText,ASIZE(RndText),L"%u.%03u",PID,Ext);
if (Length+wcslen(RndText)>=MaxSize || Attempt==1000)
return NULL;
- wcscpy(Name+Length,RndText);
+ wcsncpyz(Name+Length,RndText,MaxSize-Length);
if (!FileExist(Name))
break;
}
@@ -360,7 +360,7 @@ wchar *MkTemp(wchar *Name,size_t MaxSize)
#if !defined(SFX_MODULE)
void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size,uint Flags)
{
- SaveFilePos SavePos(*SrcFile);
+ int64 SavePos=SrcFile->Tell();
#ifndef SILENT
int64 FileLength=Size==INT64NDF ? SrcFile->FileLength() : Size;
#endif
@@ -415,6 +415,8 @@ void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size,
if (Size!=INT64NDF)
Size-=ReadSize;
}
+ SrcFile->Seek(SavePos,SEEK_SET);
+
if ((Flags & CALCFSUM_SHOWPERCENT)!=0)
uiMsg(UIEVENT_FILESUMEND);
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/find.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/find.cpp
index 812af6b..b22f82d 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/find.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/find.cpp
@@ -26,7 +26,7 @@ FindFile::~FindFile()
void FindFile::SetMask(const wchar *Mask)
{
- wcscpy(FindMask,Mask);
+ wcsncpyz(FindMask,Mask,ASIZE(FindMask));
FirstCall=true;
}
@@ -52,7 +52,7 @@ bool FindFile::Next(FindData *fd,bool GetSymLink)
wcsncpyz(DirName,FindMask,ASIZE(DirName));
RemoveNameFromPath(DirName);
if (*DirName==0)
- wcscpy(DirName,L".");
+ wcsncpyz(DirName,L".",ASIZE(DirName));
char DirNameA[NM];
WideToChar(DirName,DirNameA,ASIZE(DirNameA));
if ((dirp=opendir(DirNameA))==NULL)
@@ -63,32 +63,32 @@ bool FindFile::Next(FindData *fd,bool GetSymLink)
}
while (1)
{
+ wchar Name[NM];
struct dirent *ent=readdir(dirp);
if (ent==NULL)
return false;
if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
continue;
- wchar Name[NM];
if (!CharToWide(ent->d_name,Name,ASIZE(Name)))
uiMsg(UIERROR_INVALIDNAME,UINULL,Name);
if (CmpName(FindMask,Name,MATCH_NAMES))
{
wchar FullName[NM];
- wcscpy(FullName,FindMask);
+ wcsncpyz(FullName,FindMask,ASIZE(FullName));
*PointToName(FullName)=0;
if (wcslen(FullName)+wcslen(Name)>=ASIZE(FullName)-1)
{
uiMsg(UIERROR_PATHTOOLONG,FullName,L"",Name);
return false;
}
- wcscat(FullName,Name);
+ wcsncatz(FullName,Name,ASIZE(FullName));
if (!FastFind(FullName,fd,GetSymLink))
{
ErrHandler.OpenErrorMsg(FullName);
continue;
}
- wcscpy(fd->Name,FullName);
+ wcsncpyz(fd->Name,FullName,ASIZE(fd->Name));
break;
}
}
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/hardlinks.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/hardlinks.cpp
index cf0b25a..946a395 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/hardlinks.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/hardlinks.cpp
@@ -3,7 +3,12 @@ bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
if (!FileExist(NameExisting))
+ {
+ uiMsg(UIERROR_HLINKCREATE,NameNew);
+ uiMsg(UIERROR_NOLINKTARGET);
+ ErrHandler.SetErrorCode(RARX_CREATE);
return false;
+ }
CreatePath(NameNew,true);
#ifdef _WIN_ALL
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/hash.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/hash.cpp
index 42791f4..a4559e0 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/hash.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/hash.cpp
@@ -53,7 +53,7 @@ DataHash::DataHash()
DataHash::~DataHash()
{
#ifdef RAR_SMP
- DestroyThreadPool(ThPool);
+ delete ThPool;
#endif
cleandata(&CurCRC32, sizeof(CurCRC32));
if (blake2ctx!=NULL)
@@ -94,7 +94,7 @@ void DataHash::Update(const void *Data,size_t DataSize)
{
#ifdef RAR_SMP
if (MaxThreads>1 && ThPool==NULL)
- ThPool=CreateThreadPool();
+ ThPool=new ThreadPool(BLAKE2_THREADS_NUMBER);
blake2ctx->ThPool=ThPool;
blake2ctx->MaxThreads=MaxThreads;
#endif
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/headers.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/headers.hpp
index 488960a..6af453a 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/headers.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/headers.hpp
@@ -14,10 +14,11 @@
#define SIZEOF_UOHEAD 18
#define SIZEOF_STREAMHEAD 26
-#define VER_PACK 29
-#define VER_PACK5 50 // It is stored as 0, but we subtract 50 when saving an archive.
-#define VER_UNPACK 29
-#define VER_UNPACK5 50 // It is stored as 0, but we add 50 when reading an archive.
+#define VER_PACK 29U
+#define VER_PACK5 50U // It is stored as 0, but we subtract 50 when saving an archive.
+#define VER_UNPACK 29U
+#define VER_UNPACK5 50U // It is stored as 0, but we add 50 when reading an archive.
+#define VER_UNKNOWN 9999U // Just some large value.
#define MHD_VOLUME 0x0001U
@@ -174,7 +175,7 @@ struct MainHeader:BaseBlock
struct FileHeader:BlockHeader
{
byte HostOS;
- byte UnpVer;
+ uint UnpVer; // It is 1 byte in RAR29 and bit field in RAR5.
byte Method;
union {
uint FileAttr;
@@ -190,7 +191,7 @@ struct FileHeader:BlockHeader
int64 PackSize;
int64 UnpSize;
- int64 MaxSize; // Reserve size bytes for vint of this size.
+ int64 MaxSize; // Reserve packed and unpacked size bytes for vint of this size.
HashValue FileHash;
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/list.cpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/list.cpp
index 561122b..77c1041 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/list.cpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/list.cpp
@@ -71,6 +71,7 @@ void ListArchive(CommandData *Cmd)
*VolNumText=0;
while(Arc.ReadHeader()>0)
{
+ Wait(); // Allow quit listing with Ctrl+C.
HEADER_TYPE HeaderType=Arc.GetHeaderType();
if (HeaderType==HEAD_ENDARC)
{
@@ -91,7 +92,7 @@ void ListArchive(CommandData *Cmd)
switch(HeaderType)
{
case HEAD_FILE:
- FileMatched=Cmd->IsProcessFile(Arc.FileHead)!=0;
+ FileMatched=Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0;
if (FileMatched)
{
ListFileHeader(Arc,Arc.FileHead,TitleShown,Verbose,Technical,Bare);
@@ -215,7 +216,7 @@ void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bo
wchar UnpSizeText[30],PackSizeText[30];
if (hd.UnpSize==INT64NDF)
- wcscpy(UnpSizeText,L"?");
+ wcsncpyz(UnpSizeText,L"?",ASIZE(UnpSizeText));
else
itoa(hd.UnpSize,UnpSizeText,ASIZE(UnpSizeText));
itoa(hd.PackSize,PackSizeText,ASIZE(PackSizeText));
@@ -229,13 +230,13 @@ void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bo
wchar RatioStr[10];
if (hd.SplitBefore && hd.SplitAfter)
- wcscpy(RatioStr,L"<->");
+ wcsncpyz(RatioStr,L"<->",ASIZE(RatioStr));
else
if (hd.SplitBefore)
- wcscpy(RatioStr,L"<--");
+ wcsncpyz(RatioStr,L"<--",ASIZE(RatioStr));
else
if (hd.SplitAfter)
- wcscpy(RatioStr,L"-->");
+ wcsncpyz(RatioStr,L"-->",ASIZE(RatioStr));
else
swprintf(RatioStr,ASIZE(RatioStr),L"%d%%",ToPercentUnlim(hd.PackSize,hd.UnpSize));
@@ -344,7 +345,8 @@ void ListFileHeader(Archive &Arc,FileHeader &hd,bool &TitleShown,bool Verbose,bo
mprintf(L"\n%12ls: %ls",St(MListHostOS),HostOS);
mprintf(L"\n%12ls: RAR %ls(v%d) -m%d -md=%d%s",St(MListCompInfo),
- Format==RARFMT15 ? L"3.0":L"5.0",hd.UnpVer,hd.Method,
+ Format==RARFMT15 ? L"1.5":L"5.0",
+ hd.UnpVer==VER_UNKNOWN ? 0 : hd.UnpVer,hd.Method,
hd.WinSize>=0x100000 ? hd.WinSize/0x100000:hd.WinSize/0x400,
hd.WinSize>=0x100000 ? L"M":L"K");
@@ -466,7 +468,7 @@ void ListFileAttr(uint A,HOST_SYSTEM_TYPE HostType,wchar *AttrStr,size_t AttrSiz
(A & 0x0001) ? ((A & 0x200)!=0 ? 't' : 'x') : '-');
break;
case HSYS_UNKNOWN:
- wcscpy(AttrStr,L"?");
+ wcsncpyz(AttrStr,L"?",AttrSize);
break;
}
}
diff --git a/Carthage/Checkouts/UnrarKit/Libraries/unrar/loclang.hpp b/Carthage/Checkouts/UnrarKit/Libraries/unrar/loclang.hpp
index 87499bb..a82aca5 100644
--- a/Carthage/Checkouts/UnrarKit/Libraries/unrar/loclang.hpp
+++ b/Carthage/Checkouts/UnrarKit/Libraries/unrar/loclang.hpp
@@ -85,7 +85,7 @@
#define MCHelpSwILOG L"\n ilog[name] Log errors to file"
#define MCHelpSwINUL L"\n inul Disable all messages"
#define MCHelpSwIOFF L"\n ioff[n] Turn PC off after completing an operation"
-#define MCHelpSwISND L"\n isnd Enable sound"
+#define MCHelpSwISND L"\n isnd[-] Control notification sounds"
#define MCHelpSwIVER L"\n iver Display the version number"
#define MCHelpSwK L"\n k Lock archive"
#define MCHelpSwKB L"\n kb Keep broken extracted files"
@@ -127,11 +127,11 @@
#define MCHelpSwT L"\n t Test files after archiving"
#define MCHelpSwTK L"\n tk Keep original archive time"
#define MCHelpSwTL L"\n tl Set archive time to latest file"
-#define MCHelpSwTN L"\n tn