mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: Test zip archive with ZipDataDescriptor
This commit is contained in:
parent
4dcc6f4d93
commit
b6d251f32c
3 changed files with 143 additions and 22 deletions
|
|
@ -1169,6 +1169,7 @@ var
|
|||
LFH : TAbZipLocalFileHeader;
|
||||
Zip64Field : PZip64LocalHeaderRec;
|
||||
ZipArchive : TAbZipArchive;
|
||||
DD : TAbZipDataDescriptor = nil;
|
||||
begin
|
||||
ZipArchive := TAbZipArchive(Sender);
|
||||
|
||||
|
|
@ -1190,6 +1191,12 @@ begin
|
|||
{get the item's local file header}
|
||||
ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);
|
||||
LFH.LoadFromStream(ZipArchive.FStream);
|
||||
if LFH.HasDataDescriptor then
|
||||
begin
|
||||
DD := TAbZipDataDescriptor.Create;
|
||||
ZipArchive.FStream.Seek(Item.CompressedSize, soCurrent);
|
||||
DD.LoadFromStream(ZipArchive.FStream);
|
||||
end;
|
||||
ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);
|
||||
|
||||
{currently a single exception is raised for any LFH error}
|
||||
|
|
@ -1201,14 +1208,28 @@ begin
|
|||
raise EAbZipInvalidLFH.Create;
|
||||
if (LFH.LastModFileDate <> Item.LastModFileDate) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
if (LFH.CRC32 <> Item.CRC32) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
if Assigned(DD) then
|
||||
begin
|
||||
if (DD.CRC32 <> Item.CRC32) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
end
|
||||
else begin
|
||||
if (LFH.CRC32 <> Item.CRC32) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
end;
|
||||
if LFH.ExtraField.Get(Ab_Zip64SubfieldID, Pointer(Zip64Field), FieldSize) then begin
|
||||
if (Zip64Field.CompressedSize <> Item.CompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
if (Zip64Field.UncompressedSize <> Item.UncompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
end
|
||||
else if Assigned(DD) then
|
||||
begin
|
||||
if (DD.CompressedSize <> Item.CompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
if (DD.UncompressedSize <> Item.UncompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
end
|
||||
else begin
|
||||
if (LFH.CompressedSize <> Item.CompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
|
|
@ -1223,6 +1244,7 @@ begin
|
|||
finally
|
||||
BitBucket.Free;
|
||||
LFH.Free;
|
||||
DD.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ type
|
|||
FCompressedSize : Int64;
|
||||
FUncompressedSize : Int64;
|
||||
public {methods}
|
||||
procedure LoadFromStream( Stream : TStream );
|
||||
procedure SaveToStream( Stream : TStream );
|
||||
public {properties}
|
||||
property CRC32 : Longint
|
||||
|
|
@ -911,6 +912,17 @@ begin
|
|||
end;
|
||||
{============================================================================}
|
||||
{ TAbZipDataDescriptor implementation ====================================== }
|
||||
procedure TAbZipDataDescriptor.LoadFromStream(Stream: TStream);
|
||||
var
|
||||
Signature: LongInt = 0;
|
||||
begin
|
||||
Stream.Read(Signature, SizeOf(Ab_ZipDataDescriptorSignature));
|
||||
if (Signature <> Ab_ZipDataDescriptorSignature) then Exit;
|
||||
Stream.Read(FCRC32, SizeOf(FCRC32));
|
||||
Stream.Read(FCompressedSize, SizeOf(LongWord));
|
||||
Stream.Read(FUncompressedSize, SizeOf(LongWord));
|
||||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
procedure TAbZipDataDescriptor.SaveToStream( Stream : TStream );
|
||||
begin
|
||||
Stream.Write( Ab_ZipDataDescriptorSignature, sizeof( Ab_ZipDataDescriptorSignature ) );
|
||||
|
|
|
|||
|
|
@ -1716,6 +1716,67 @@ Index: AbUnzPrc.pas
|
|||
try
|
||||
try {OutStream}
|
||||
DoExtract(ZipArchive, Item, InStream, OutStream);
|
||||
@@ -1141,6 +1169,7 @@
|
||||
LFH : TAbZipLocalFileHeader;
|
||||
Zip64Field : PZip64LocalHeaderRec;
|
||||
ZipArchive : TAbZipArchive;
|
||||
+ DD : TAbZipDataDescriptor = nil;
|
||||
begin
|
||||
ZipArchive := TAbZipArchive(Sender);
|
||||
|
||||
@@ -1162,6 +1191,12 @@
|
||||
{get the item's local file header}
|
||||
ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);
|
||||
LFH.LoadFromStream(ZipArchive.FStream);
|
||||
+ if LFH.HasDataDescriptor then
|
||||
+ begin
|
||||
+ DD := TAbZipDataDescriptor.Create;
|
||||
+ ZipArchive.FStream.Seek(Item.CompressedSize, soCurrent);
|
||||
+ DD.LoadFromStream(ZipArchive.FStream);
|
||||
+ end;
|
||||
ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);
|
||||
|
||||
{currently a single exception is raised for any LFH error}
|
||||
@@ -1173,8 +1208,15 @@
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
if (LFH.LastModFileDate <> Item.LastModFileDate) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
- if (LFH.CRC32 <> Item.CRC32) then
|
||||
- raise EAbZipInvalidLFH.Create;
|
||||
+ if Assigned(DD) then
|
||||
+ begin
|
||||
+ if (DD.CRC32 <> Item.CRC32) then
|
||||
+ raise EAbZipInvalidLFH.Create;
|
||||
+ end
|
||||
+ else begin
|
||||
+ if (LFH.CRC32 <> Item.CRC32) then
|
||||
+ raise EAbZipInvalidLFH.Create;
|
||||
+ end;
|
||||
if LFH.ExtraField.Get(Ab_Zip64SubfieldID, Pointer(Zip64Field), FieldSize) then begin
|
||||
if (Zip64Field.CompressedSize <> Item.CompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
@@ -1181,6 +1223,13 @@
|
||||
if (Zip64Field.UncompressedSize <> Item.UncompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
end
|
||||
+ else if Assigned(DD) then
|
||||
+ begin
|
||||
+ if (DD.CompressedSize <> Item.CompressedSize) then
|
||||
+ raise EAbZipInvalidLFH.Create;
|
||||
+ if (DD.UncompressedSize <> Item.UncompressedSize) then
|
||||
+ raise EAbZipInvalidLFH.Create;
|
||||
+ end
|
||||
else begin
|
||||
if (LFH.CompressedSize <> Item.CompressedSize) then
|
||||
raise EAbZipInvalidLFH.Create;
|
||||
@@ -1195,6 +1244,7 @@
|
||||
finally
|
||||
BitBucket.Free;
|
||||
LFH.Free;
|
||||
+ DD.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
Index: AbUtils.pas
|
||||
===================================================================
|
||||
--- AbUtils.pas (revision 512)
|
||||
|
|
@ -2409,7 +2470,15 @@ Index: AbZipTyp.pas
|
|||
|
||||
TAbZipSupportedMethod =
|
||||
(smStored, smDeflated, smBestMethod);
|
||||
@@ -407,6 +407,7 @@
|
||||
@@ -206,6 +206,7 @@
|
||||
FCompressedSize : Int64;
|
||||
FUncompressedSize : Int64;
|
||||
public {methods}
|
||||
+ procedure LoadFromStream( Stream : TStream );
|
||||
procedure SaveToStream( Stream : TStream );
|
||||
public {properties}
|
||||
property CRC32 : Longint
|
||||
@@ -407,6 +408,7 @@
|
||||
function GetLastModFileDate : Word; override;
|
||||
function GetLastModFileTime : Word; override;
|
||||
function GetNativeFileAttributes : LongInt; override;
|
||||
|
|
@ -2417,7 +2486,7 @@ Index: AbZipTyp.pas
|
|||
procedure SetCompressedSize( const Value : Int64 ); override;
|
||||
procedure SetCRC32( const Value : Longint ); override;
|
||||
procedure SetExternalFileAttributes( Value : LongWord ); override;
|
||||
@@ -530,8 +531,8 @@
|
||||
@@ -530,8 +532,8 @@
|
||||
override;
|
||||
destructor Destroy;
|
||||
override;
|
||||
|
|
@ -2428,7 +2497,7 @@ Index: AbZipTyp.pas
|
|||
|
||||
public {properties}
|
||||
property CompressionMethodToUse : TAbZipSupportedMethod
|
||||
@@ -620,11 +621,14 @@
|
||||
@@ -620,11 +622,14 @@
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
Math,
|
||||
|
|
@ -2445,7 +2514,7 @@ Index: AbZipTyp.pas
|
|||
|
||||
function VerifyZip(Strm : TStream) : TAbArchiveType;
|
||||
{ determine if stream appears to be in PkZip format }
|
||||
@@ -638,20 +642,31 @@
|
||||
@@ -638,20 +643,31 @@
|
||||
Result := atUnknown;
|
||||
try
|
||||
Strm.Position := 0;
|
||||
|
|
@ -2491,7 +2560,7 @@ Index: AbZipTyp.pas
|
|||
end;
|
||||
end;
|
||||
except
|
||||
@@ -733,8 +748,7 @@
|
||||
@@ -733,8 +749,7 @@
|
||||
leaves stream positioned at start of structure or at original
|
||||
position if not found }
|
||||
const
|
||||
|
|
@ -2501,7 +2570,7 @@ Index: AbZipTyp.pas
|
|||
var
|
||||
StartPos : Int64;
|
||||
TailRec : TAbZipEndOfCentralDirectoryRecord;
|
||||
@@ -741,7 +755,6 @@
|
||||
@@ -741,7 +756,6 @@
|
||||
Buffer : PAnsiChar;
|
||||
Offset : Int64;
|
||||
TestPos : PAnsiChar;
|
||||
|
|
@ -2509,7 +2578,7 @@ Index: AbZipTyp.pas
|
|||
BytesRead : Int64;
|
||||
BufSize : Int64;
|
||||
CommentLen: integer;
|
||||
@@ -767,7 +780,7 @@
|
||||
@@ -767,7 +781,7 @@
|
||||
stream; we need to search for the tail signature}
|
||||
|
||||
{get a buffer}
|
||||
|
|
@ -2518,7 +2587,7 @@ Index: AbZipTyp.pas
|
|||
GetMem(Buffer, BufSize);
|
||||
try
|
||||
|
||||
@@ -774,57 +787,41 @@
|
||||
@@ -774,57 +788,41 @@
|
||||
{start out searching backwards}
|
||||
Offset := -BufSize;
|
||||
|
||||
|
|
@ -2603,7 +2672,25 @@ Index: AbZipTyp.pas
|
|||
end;
|
||||
|
||||
{if we reach this point, the CD tail is not present}
|
||||
@@ -1195,12 +1192,13 @@
|
||||
@@ -914,6 +912,17 @@
|
||||
end;
|
||||
{============================================================================}
|
||||
{ TAbZipDataDescriptor implementation ====================================== }
|
||||
+procedure TAbZipDataDescriptor.LoadFromStream(Stream: TStream);
|
||||
+var
|
||||
+ Signature: LongInt = 0;
|
||||
+begin
|
||||
+ Stream.Read(Signature, SizeOf(Ab_ZipDataDescriptorSignature));
|
||||
+ if (Signature <> Ab_ZipDataDescriptorSignature) then Exit;
|
||||
+ Stream.Read(FCRC32, SizeOf(FCRC32));
|
||||
+ Stream.Read(FCompressedSize, SizeOf(LongWord));
|
||||
+ Stream.Read(FUncompressedSize, SizeOf(LongWord));
|
||||
+end;
|
||||
+{ -------------------------------------------------------------------------- }
|
||||
procedure TAbZipDataDescriptor.SaveToStream( Stream : TStream );
|
||||
begin
|
||||
Stream.Write( Ab_ZipDataDescriptorSignature, sizeof( Ab_ZipDataDescriptorSignature ) );
|
||||
@@ -1195,12 +1204,13 @@
|
||||
{ TAbZipDirectoryFileFooter implementation ================================= }
|
||||
function TAbZipDirectoryFileFooter.GetIsZip64: Boolean;
|
||||
begin
|
||||
|
|
@ -2623,7 +2710,7 @@ Index: AbZipTyp.pas
|
|||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
procedure TAbZipDirectoryFileFooter.LoadFromStream( Stream : TStream );
|
||||
@@ -1407,6 +1405,22 @@
|
||||
@@ -1407,6 +1417,22 @@
|
||||
Result := FItemInfo.FileName;
|
||||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
|
|
@ -2646,7 +2733,7 @@ Index: AbZipTyp.pas
|
|||
function TAbZipItem.GetShannonFanoTreeCount : Byte;
|
||||
begin
|
||||
Result := FItemInfo.ShannonFanoTreeCount;
|
||||
@@ -1430,12 +1444,13 @@
|
||||
@@ -1430,12 +1456,13 @@
|
||||
UnicodeName: UnicodeString;
|
||||
UTF8Name: AnsiString;
|
||||
XceedField: PXceedUnicodePathRec;
|
||||
|
|
@ -2662,7 +2749,7 @@ Index: AbZipTyp.pas
|
|||
else if FItemInfo.ExtraField.Get(Ab_InfoZipUnicodePathSubfieldID, Pointer(InfoZipField), FieldSize) and
|
||||
(FieldSize > SizeOf(TInfoZipUnicodePathRec)) and
|
||||
(InfoZipField.Version = 1) and
|
||||
@@ -1442,7 +1457,7 @@
|
||||
@@ -1442,7 +1469,7 @@
|
||||
(InfoZipField.NameCRC32 = AbCRC32Of(FItemInfo.FileName)) then begin
|
||||
SetString(UTF8Name, InfoZipField.UnicodeName,
|
||||
FieldSize - SizeOf(TInfoZipUnicodePathRec) + 1);
|
||||
|
|
@ -2671,7 +2758,7 @@ Index: AbZipTyp.pas
|
|||
end
|
||||
else if FItemInfo.ExtraField.Get(Ab_XceedUnicodePathSubfieldID, Pointer(XceedField), FieldSize) and
|
||||
(FieldSize > SizeOf(TXceedUnicodePathRec)) and
|
||||
@@ -1449,16 +1464,28 @@
|
||||
@@ -1449,16 +1476,28 @@
|
||||
(XceedField.Signature = Ab_XceedUnicodePathSignature) and
|
||||
(XceedField.Length * SizeOf(WideChar) = FieldSize - SizeOf(TXceedUnicodePathRec) + SizeOf(WideChar)) then begin
|
||||
SetString(UnicodeName, XceedField.UnicodeName, XceedField.Length);
|
||||
|
|
@ -2708,7 +2795,7 @@ Index: AbZipTyp.pas
|
|||
|
||||
{ read ZIP64 extended header }
|
||||
FUncompressedSize := FItemInfo.UncompressedSize;
|
||||
@@ -1596,24 +1623,20 @@
|
||||
@@ -1596,24 +1635,20 @@
|
||||
{$IFDEF MSWINDOWS}
|
||||
FItemInfo.IsUTF8 := False;
|
||||
HostOS := hosDOS;
|
||||
|
|
@ -2738,7 +2825,7 @@ Index: AbZipTyp.pas
|
|||
{$ENDIF}
|
||||
|
||||
UseExtraField := False;
|
||||
@@ -1626,7 +1649,7 @@
|
||||
@@ -1626,7 +1661,7 @@
|
||||
end;
|
||||
|
||||
if UseExtraField then begin
|
||||
|
|
@ -2747,7 +2834,7 @@ Index: AbZipTyp.pas
|
|||
FieldSize := SizeOf(TInfoZipUnicodePathRec) + Length(UTF8Name) - 1;
|
||||
GetMem(InfoZipField, FieldSize);
|
||||
try
|
||||
@@ -1762,11 +1785,11 @@
|
||||
@@ -1762,11 +1797,11 @@
|
||||
inherited Destroy;
|
||||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
|
|
@ -2762,7 +2849,7 @@ Index: AbZipTyp.pas
|
|||
Result := TAbZipItem.Create;
|
||||
with TAbZipItem( Result ) do begin
|
||||
CompressionMethod := cmDeflated;
|
||||
@@ -1773,9 +1796,17 @@
|
||||
@@ -1773,9 +1808,17 @@
|
||||
GeneralPurposeBitFlag := 0;
|
||||
CompressedSize := 0;
|
||||
CRC32 := 0;
|
||||
|
|
@ -2782,7 +2869,7 @@ Index: AbZipTyp.pas
|
|||
end;
|
||||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
@@ -1930,8 +1961,8 @@
|
||||
@@ -1930,8 +1973,8 @@
|
||||
AbStripDots( lValue );
|
||||
|
||||
for i := 1 to Length( lValue ) do
|
||||
|
|
@ -2793,7 +2880,7 @@ Index: AbZipTyp.pas
|
|||
Result := lValue;
|
||||
end;
|
||||
{ -------------------------------------------------------------------------- }
|
||||
@@ -1983,7 +2014,7 @@
|
||||
@@ -1983,7 +2026,7 @@
|
||||
FStatus := asInvalid; //TODO: Status updates are extremely inconsistent
|
||||
raise EAbUserAbort.Create;
|
||||
end;
|
||||
|
|
@ -2802,7 +2889,7 @@ Index: AbZipTyp.pas
|
|||
TailPosition := FindCentralDirectoryTail( FStream );
|
||||
end;
|
||||
end;
|
||||
@@ -2302,7 +2333,7 @@
|
||||
@@ -2302,7 +2345,7 @@
|
||||
if FOwnsStream then begin
|
||||
{need new stream to write}
|
||||
FreeAndNil(FStream);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue