Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
unar.15597
unar-1.10.1-self-extracting_rar.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File unar-1.10.1-self-extracting_rar.patch of Package unar.15597
Index: unar-1.10.1/XADMaster/XADRAR5Parser.h =================================================================== --- unar-1.10.1.orig/XADMaster/XADRAR5Parser.h +++ unar-1.10.1/XADMaster/XADRAR5Parser.h @@ -9,6 +9,29 @@ typedef struct RAR5Block CSHandle *fh; } RAR5Block; +typedef enum { + RAR5ArchiveFlagsNone = 0, + RAR5ArchiveFlagsVolume = 0x0001, // Volume. Archive is a part of multivolume set. + RAR5ArchiveFlagsVolumeNumberPresent = 0x0002, // Volume number field is present. + // This flag is present in all volumes except first. + RAR5ArchiveFlagsSolid = 0x0004, // Solid archive. + RAR5ArchiveFlagsRecoveryRecordPresent = 0x0008, // Recovery record is present. + RAR5ArchiveFlagsLocked = 0x0010, // Locked archive. +} RAR5ArchiveFlags; + typedef enum { + RAR5HeaderTypeUnknown = 0, + RAR5HeaderTypeMain = 1, // Main archive header. + RAR5HeaderTypeFile = 2, // File header. + RAR5HeaderTypeService = 3, // Service header. + RAR5HeaderTypeEncryption = 4, // Archive encryption header. + RAR5HeaderTypeEnd = 5, // End of archive header. +} RAR5HeaderType; + typedef struct RAR5HeaderBlock +{ + RAR5Block block; + RAR5ArchiveFlags archiveFlags; +} RAR5HeaderBlock; + @interface XADRAR5Parser:XADArchiveParser { NSData *headerkey; Index: unar-1.10.1/XADMaster/XADRAR5Parser.m =================================================================== --- unar-1.10.1.orig/XADMaster/XADRAR5Parser.m +++ unar-1.10.1/XADMaster/XADRAR5Parser.m @@ -4,10 +4,16 @@ #import "XADRARAESHandle.h" #import "XADCRCHandle.h" #import "NSDateXAD.h" +#import "CSFileHandle.h" #import "Crypto/hmac_sha256.h" #import "Crypto/pbkdf2_hmac_sha256.h" #define ZeroBlock ((RAR5Block){0}) +#define ZeroHeaderBlock ((RAR5HeaderBlock){0}) + +NSString *RAR5SignatureCannotBeFound=@"RAR5SignatureCannotBeFound"; +const off_t RAR5MaximumSFXHeader = 1 << 20; // 1 MB +const off_t RAR5SignatureNotFound = -1; static uint32_t EncryptRAR5CRC32(uint32_t crc,id context); @@ -34,9 +40,11 @@ static uint64_t ReadRAR5VInt(CSHandle *h } static inline BOOL IsZeroBlock(RAR5Block block) { return block.start==0; } +static inline BOOL IsZeroHeaderBlock(RAR5HeaderBlock block) { return IsZeroBlock(block.block); } - - + @interface XADRAR5Parser (Multipart) + +(BOOL)isPartOfMultiVolume:(CSHandle *)handle; +@end @implementation XADRAR5Parser @@ -47,24 +55,43 @@ static inline BOOL IsZeroBlock(RAR5Block +(BOOL)recognizeFileWithHandle:(CSHandle *)handle firstBytes:(NSData *)data name:(NSString *)name { - const uint8_t *bytes=[data bytes]; - int length=[data length]; - - if(length<8) return NO; // TODO: fix to use correct min size - - if(IsRAR5Signature(bytes)) return YES; + off_t signatureLocation = [self signatureLocationInData:data]; + return signatureLocation != RAR5SignatureNotFound; +} - return NO; ++ (off_t)signatureLocationInData:(NSData *)data { + const uint8_t *bytes=[data bytes]; + int length=[data length]; + + if(length<8) return RAR5SignatureNotFound; // TODO: fix to use correct min size + + // for SFXX, RAR Signature can be found not at start, but anywhere in the data + int maxxSearch = MIN(length, RAR5MaximumSFXHeader) - 8; + + const uint8_t *sign = bytes; + for (int i =0 ; i < maxxSearch; i++, sign++) { + if(IsRAR5Signature(sign)) { + return i; + } + } + return RAR5SignatureNotFound; } +(NSArray *)volumesForHandle:(CSHandle *)handle firstBytes:(NSData *)data name:(NSString *)name { + // Check if multipart + CSFileHandle *filehandle=[CSFileHandle fileHandleForReadingAtPath:name]; + if (![self isPartOfMultiVolume:filehandle]) { + return nil; + } + + // New naming scheme. Find the last number in the name, and look for other files // with the same number of digits in the same location. NSArray *matches; - if((matches=[name substringsCapturedByPattern:@"^(.*[^0-9])([0-9]+)(.*)\\.rar$" options:REG_ICASE])) + if((matches=[name substringsCapturedByPattern:@"^(.*[^0-9])([0-9]+)(.*)\\.(rar|sfx|exe)$" options:REG_ICASE])) return [self scanForVolumesWithFilename:name - regex:[XADRegex regexWithPattern:[NSString stringWithFormat:@"^%@[0-9]{%ld}%@.rar$", + regex:[XADRegex regexWithPattern:[NSString stringWithFormat:@"^%@[0-9]{%ld}%@.(rar|sfx|exe)$", [[matches objectAtIndex:1] escapedPattern], (long)[(NSString *)[matches objectAtIndex:2] length], [[matches objectAtIndex:3] escapedPattern]] options:REG_ICASE] @@ -93,6 +120,18 @@ static inline BOOL IsZeroBlock(RAR5Block [super dealloc]; } +- (void)readUntilSignature { + CSHandle * signatureSearchingHandle = [[self handle] subHandleToEndOfFileFrom:0]; + NSData * data = [signatureSearchingHandle readDataOfLengthAtMost:RAR5MaximumSFXHeader]; + off_t signatureLocation = [XADRAR5Parser signatureLocationInData:data]; + if (signatureLocation == RAR5SignatureNotFound) { + [NSException raise:RAR5SignatureCannotBeFound format:@"Signature cannot be found %@",[self class]]; + } + + [self.handle skipBytes:signatureLocation]; +} + + -(void)parse { currsolidstream=nil; @@ -101,12 +140,13 @@ static inline BOOL IsZeroBlock(RAR5Block NSMutableDictionary *currdict=nil; NSMutableArray *currparts=[NSMutableArray array]; - [[self handle] skipBytes:8]; - // TODO: Catch exceptions and emit partial files? @try { + [self readUntilSignature]; + [self.handle skipBytes:8]; + for(;;) { RAR5Block block=[self readBlockHeader]; @@ -117,11 +157,13 @@ static inline BOOL IsZeroBlock(RAR5Block switch(block.type) { - case 1: // Main archive header. + case RAR5HeaderTypeMain: // Main archive header. + [self skipBlock:block]; break; - case 2: // File header. + case RAR5HeaderTypeFile: // File header. + { NSMutableDictionary *dict=[self readFileBlockHeader:block]; @@ -176,10 +218,12 @@ static inline BOOL IsZeroBlock(RAR5Block } break; - //case 3: // Service header. + //case RAR5HeaderTypeService: // Service header. + //break; - case 4: // Archive encryption header. + case RAR5HeaderTypeEncryption: // Archive encryption header. + { uint64_t version=ReadRAR5VInt(handle); if(version!=0) [XADException raiseNotSupportedException]; @@ -202,7 +246,8 @@ static inline BOOL IsZeroBlock(RAR5Block } break; - case 5: // End of archive header. + case RAR5HeaderTypeEnd: // End of archive header. + { uint64_t flags=ReadRAR5VInt(handle); if(flags&0x0001) @@ -550,6 +595,52 @@ inputParts:(NSArray *)parts isCorrupted: return dict; } ++(RAR5HeaderBlock)readMasterHeaderFromHandle:(CSHandle *)handle +{ + + RAR5HeaderBlock header; + RAR5Block block; + block.outerstart=0; + + @try + { + CSHandle * signatureSearchingHandle = [handle subHandleToEndOfFileFrom:0]; + NSData * data = [signatureSearchingHandle readDataOfLengthAtMost:RAR5MaximumSFXHeader]; + off_t signatureLocation = [XADRAR5Parser signatureLocationInData:data]; + if (signatureLocation == RAR5SignatureNotFound) { + [NSException raise:RAR5SignatureCannotBeFound format:@"Signature cannot be found %@",[self class]]; + } + + [handle skipBytes:signatureLocation]; + [handle skipBytes:8]; + if([handle atEndOfFile]) return ZeroHeaderBlock; + block.crc=[handle readUInt32LE]; + block.headersize=ReadRAR5VInt(handle); + block.start=[handle offsetInFile]; + block.type=ReadRAR5VInt(handle); + block.flags=ReadRAR5VInt(handle); + + if(block.flags&0x0001) block.extrasize=ReadRAR5VInt(handle); + else block.extrasize=0; + + header.archiveFlags=ReadRAR5VInt(handle); + + if(block.flags&0x0002) block.datasize=ReadRAR5VInt(handle); + else block.datasize=0; + } + @catch(id e) { return ZeroHeaderBlock; } + + // If first block wasn't main + if (block.type != RAR5HeaderTypeMain) { + return ZeroHeaderBlock; + } + + block.fh=handle; + + header.block = block; + return header; +} + -(RAR5Block)readBlockHeader { CSHandle *fh=[self handle]; @@ -788,3 +879,15 @@ static uint32_t EncryptRAR5CRC32(uint32_ return newcrc^0xffffffff; } + +@implementation XADRAR5Parser (Multipart) + +(BOOL)isPartOfMultiVolume:(CSHandle *)handle +{ + RAR5HeaderBlock header = [self readMasterHeaderFromHandle:handle]; + if (IsZeroHeaderBlock(header)) { + return NO; + } + return (header.archiveFlags & RAR5ArchiveFlagsVolume); +} +@end + Index: unar-1.10.1/XADMaster/XADArchiveParser.m =================================================================== --- unar-1.10.1.orig/XADMaster/XADArchiveParser.m +++ unar-1.10.1/XADMaster/XADArchiveParser.m @@ -183,9 +183,9 @@ static int maxheader=0; // Detectors that require lots of work [XADWinZipSFXParser class], [XADZipItSEAParser class], - [XADZipSFXParser class], [XADEmbeddedRARParser class], [XADEmbeddedRAR5Parser class], + [XADZipSFXParser class], [XAD7ZipSFXParser class], [XADNSISParser class], [XADGzipSFXParser class],
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor