mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: [Zip plugin] Handling errors when detecting archive type.
This commit is contained in:
parent
d3fbe7ec41
commit
278b9880d8
5 changed files with 154 additions and 120 deletions
|
|
@ -139,24 +139,29 @@ begin
|
|||
CurPos := Strm.Position;
|
||||
Strm.Seek(0, soFromBeginning);
|
||||
|
||||
if (Strm.Read(Hdr, SizeOf(Hdr)) = SizeOf(Hdr)) and VerifyHeader(Hdr) then begin
|
||||
Result := atBzip2;
|
||||
{ Check for embedded TAR }
|
||||
Strm.Seek(0, soFromBeginning);
|
||||
DecompStream := TBZDecompressionStream.Create(Strm);
|
||||
try
|
||||
TarStream := TMemoryStream.Create;
|
||||
try
|
||||
if (Strm.Read(Hdr, SizeOf(Hdr)) = SizeOf(Hdr)) and VerifyHeader(Hdr) then begin
|
||||
Result := atBzip2;
|
||||
{ Check for embedded TAR }
|
||||
Strm.Seek(0, soFromBeginning);
|
||||
DecompStream := TBZDecompressionStream.Create(Strm);
|
||||
try
|
||||
TarStream.CopyFrom(DecompStream, 512 * 2);
|
||||
TarStream.Seek(0, soFromBeginning);
|
||||
if VerifyTar(TarStream) = atTar then
|
||||
Result := atBzippedTar;
|
||||
TarStream := TMemoryStream.Create;
|
||||
try
|
||||
TarStream.CopyFrom(DecompStream, 512 * 2);
|
||||
TarStream.Seek(0, soFromBeginning);
|
||||
if VerifyTar(TarStream) = atTar then
|
||||
Result := atBzippedTar;
|
||||
finally
|
||||
TarStream.Free;
|
||||
end;
|
||||
finally
|
||||
TarStream.Free;
|
||||
DecompStream.Free;
|
||||
end;
|
||||
finally
|
||||
DecompStream.Free;
|
||||
end;
|
||||
except
|
||||
on EFilerError do
|
||||
Result := atUnknown;
|
||||
end;
|
||||
Strm.Position := CurPos; { Return to original position. }
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -369,50 +369,55 @@ end;
|
|||
|
||||
function VerifyGZip(Strm : TStream) : TAbArchiveType;
|
||||
var
|
||||
GHlp : TAbGzipStreamHelper;
|
||||
GHlp : TAbGzipStreamHelper = nil;
|
||||
Hlpr : TAbDeflateHelper;
|
||||
PartialTarData : TMemoryStream;
|
||||
CurPos : LongInt;
|
||||
CurPos : Int64;
|
||||
begin
|
||||
Result := atUnknown;
|
||||
|
||||
CurPos := Strm.Position;
|
||||
Strm.Seek(0, soFromBeginning);
|
||||
|
||||
{prepare for the try..finally}
|
||||
Hlpr := nil;
|
||||
PartialTarData := nil;
|
||||
|
||||
GHlp := TAbGzipStreamHelper.Create(Strm);
|
||||
try
|
||||
{create the stream helper and read the item header}
|
||||
GHlp.ReadHeader;
|
||||
{prepare for the try..finally}
|
||||
Hlpr := nil;
|
||||
PartialTarData := nil;
|
||||
|
||||
{ check id fields and if deflated (only handle deflate anyway)}
|
||||
if VerifyHeader(GHlp.FItem.FGZHeader) then begin
|
||||
Result := atGZip; { provisional }
|
||||
try
|
||||
Strm.Seek(0, soFromBeginning);
|
||||
GHlp := TAbGzipStreamHelper.Create(Strm);
|
||||
|
||||
{ check if is actually a Gzipped Tar }
|
||||
{ partial extract contents, verify vs. Tar }
|
||||
PartialTarData := TMemoryStream.Create;
|
||||
GHlp.SeekToItemData;
|
||||
Hlpr := TAbDeflateHelper.Create;
|
||||
Hlpr.PartialSize := 512;
|
||||
PartialTarData.SetSize(512 * 2);
|
||||
Inflate(Strm, PartialTarData, Hlpr);
|
||||
{create the stream helper and read the item header}
|
||||
GHlp.ReadHeader;
|
||||
|
||||
{set to beginning of extracted data}
|
||||
PartialTarData.Position := 0;
|
||||
{ check id fields and if deflated (only handle deflate anyway)}
|
||||
if VerifyHeader(GHlp.FItem.FGZHeader) then begin
|
||||
Result := atGZip; { provisional }
|
||||
|
||||
if (VerifyTar(PartialTarData) = atTar) then
|
||||
Result := atGZippedTar;
|
||||
{ check if is actually a Gzipped Tar }
|
||||
{ partial extract contents, verify vs. Tar }
|
||||
PartialTarData := TMemoryStream.Create;
|
||||
GHlp.SeekToItemData;
|
||||
Hlpr := TAbDeflateHelper.Create;
|
||||
Hlpr.PartialSize := 512;
|
||||
PartialTarData.SetSize(512 * 2);
|
||||
Inflate(Strm, PartialTarData, Hlpr);
|
||||
|
||||
{set to beginning of extracted data}
|
||||
PartialTarData.Position := 0;
|
||||
|
||||
if (VerifyTar(PartialTarData) = atTar) then
|
||||
Result := atGZippedTar;
|
||||
end;
|
||||
finally
|
||||
GHlp.Free;
|
||||
Hlpr.Free;
|
||||
PartialTarData.Free;
|
||||
|
||||
Strm.Position := CurPos;
|
||||
end;
|
||||
finally
|
||||
GHlp.Free;
|
||||
Hlpr.Free;
|
||||
PartialTarData.Free;
|
||||
|
||||
Strm.Position := CurPos;
|
||||
except
|
||||
on EFilerError do
|
||||
Result := atUnknown;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -548,23 +548,31 @@ end;
|
|||
function VerifyTar(Strm : TStream) : TAbArchiveType;
|
||||
{ assumes Tar positioned correctly for test of item }
|
||||
var
|
||||
TarItem : TAbTarItem;
|
||||
TarItem : TAbTarItem;
|
||||
StartPos : Int64;
|
||||
begin
|
||||
{ Verifies that the header checksum is valid, and Item type is understood.
|
||||
This does not mean that extraction is supported. }
|
||||
TarItem := TAbTarItem.Create;
|
||||
StartPos := Strm.Position;
|
||||
try
|
||||
{ get current Tar Header }
|
||||
TarItem.LoadTarHeaderFromStream(Strm);
|
||||
if TarItem.CheckSumGood //or (TarItem.ItemType in [UNKNOWN_ITEM])
|
||||
or TarItem.TestEmpty // Empty Tar file
|
||||
then
|
||||
Result := atTar
|
||||
else
|
||||
result := atUnknown;
|
||||
finally
|
||||
TarItem.Free;
|
||||
{ Verifies that the header checksum is valid, and Item type is understood.
|
||||
This does not mean that extraction is supported. }
|
||||
TarItem := TAbTarItem.Create;
|
||||
try
|
||||
{ get current Tar Header }
|
||||
TarItem.LoadTarHeaderFromStream(Strm);
|
||||
if TarItem.CheckSumGood //or (TarItem.ItemType in [UNKNOWN_ITEM])
|
||||
or TarItem.TestEmpty // Empty Tar file
|
||||
then
|
||||
Result := atTar
|
||||
else
|
||||
Result := atUnknown;
|
||||
finally
|
||||
TarItem.Free;
|
||||
end;
|
||||
except
|
||||
on EFilerError do
|
||||
Result := atUnknown;
|
||||
end;
|
||||
Strm.Position := StartPos;
|
||||
end;
|
||||
|
||||
function PadString(const S : AnsiString; Places : Integer) : AnsiString;
|
||||
|
|
|
|||
|
|
@ -653,36 +653,40 @@ var
|
|||
begin
|
||||
StartPos := Strm.Position;
|
||||
Result := atUnknown;
|
||||
try
|
||||
Strm.Position := 0; {!!.02}
|
||||
Strm.Read(Sig, SizeOf(LongInt)); {!!.02}
|
||||
if (Sig = Ab_ZipSpannedSetSignature) then {!!.02}
|
||||
Result := atSpannedZip {!!.02}
|
||||
else begin {!!.02}
|
||||
|
||||
Strm.Position := 0; {!!.02}
|
||||
Strm.Read(Sig, SizeOf(LongInt)); {!!.02}
|
||||
if (Sig = Ab_ZipSpannedSetSignature) then {!!.02}
|
||||
Result := atSpannedZip {!!.02}
|
||||
else begin {!!.02}
|
||||
|
||||
{ attempt to find Central Directory Tail }
|
||||
TailPosition := FindCentralDirectoryTail( Strm );
|
||||
if TailPosition <> -1 then begin
|
||||
{ check Central Directory Signature }
|
||||
Footer := TAbZipDirectoryFileFooter.Create;
|
||||
try
|
||||
Footer.LoadFromStream(Strm);
|
||||
if Footer.FSignature = AB_ZipCentralDirectoryTailSignature then
|
||||
Result := atZip;
|
||||
finally
|
||||
Footer.Free;
|
||||
end;
|
||||
end
|
||||
(* {!!.02}
|
||||
else begin { may be a span } {!!.01}
|
||||
Strm.Seek(0, soBeginning); {!!.01}
|
||||
Strm.Read(Sig, SizeOf(LongInt)); {!!.01}
|
||||
if (Sig = Ab_ZipSpannedSetSignature) {!!.01}
|
||||
or (Sig = Ab_ZipPossiblySpannedSignature) {!!.01}
|
||||
then {!!.01}
|
||||
Result := atSpannedZip; {!!.01}
|
||||
*) {!!.02}
|
||||
end; {!!.01}
|
||||
{ attempt to find Central Directory Tail }
|
||||
TailPosition := FindCentralDirectoryTail( Strm );
|
||||
if TailPosition <> -1 then begin
|
||||
{ check Central Directory Signature }
|
||||
Footer := TAbZipDirectoryFileFooter.Create;
|
||||
try
|
||||
Footer.LoadFromStream(Strm);
|
||||
if Footer.FSignature = AB_ZipCentralDirectoryTailSignature then
|
||||
Result := atZip;
|
||||
finally
|
||||
Footer.Free;
|
||||
end;
|
||||
end
|
||||
(* {!!.02}
|
||||
else begin { may be a span } {!!.01}
|
||||
Strm.Seek(0, soBeginning); {!!.01}
|
||||
Strm.Read(Sig, SizeOf(LongInt)); {!!.01}
|
||||
if (Sig = Ab_ZipSpannedSetSignature) {!!.01}
|
||||
or (Sig = Ab_ZipPossiblySpannedSignature) {!!.01}
|
||||
then {!!.01}
|
||||
Result := atSpannedZip; {!!.01}
|
||||
*) {!!.02}
|
||||
end; {!!.01}
|
||||
except
|
||||
on EFilerError do
|
||||
Result := atUnknown;
|
||||
end;
|
||||
Strm.Position := StartPos;
|
||||
end;
|
||||
|
||||
|
|
@ -694,32 +698,36 @@ var
|
|||
IsWinExe, IsLinuxExe : Boolean; {!!.01}
|
||||
begin
|
||||
StartPos := Strm.Position;
|
||||
{ verify presence of executable stub }
|
||||
{check file type of stub stream}
|
||||
Strm.Position := 0;
|
||||
Strm.Read( FileSignature, sizeof( FileSignature ) );
|
||||
try
|
||||
{ verify presence of executable stub }
|
||||
{check file type of stub stream}
|
||||
Strm.Position := 0;
|
||||
Strm.Read( FileSignature, sizeof( FileSignature ) );
|
||||
|
||||
Result := atSelfExtZip;
|
||||
Result := atSelfExtZip;
|
||||
|
||||
{!!.01 -- re-written Executable Type Detection to allow use of non-native stubs }
|
||||
IsLinuxExe := False;
|
||||
IsWinExe := LongRec(FileSignature).Lo = Ab_WindowsExeSignature; {!!.02}
|
||||
if not IsWinExe then begin
|
||||
IsLinuxExe := FileSignature = Ab_LinuxExeSigWord1; { check 1st sig }
|
||||
if IsLinuxExe then begin
|
||||
Strm.Read(FileSignature, SizeOf(FileSignature)); { check 2nd sig }
|
||||
IsLinuxExe := FileSignature = Ab_LinuxExeSigWord2;
|
||||
{!!.01 -- re-written Executable Type Detection to allow use of non-native stubs }
|
||||
IsLinuxExe := False;
|
||||
IsWinExe := LongRec(FileSignature).Lo = Ab_WindowsExeSignature; {!!.02}
|
||||
if not IsWinExe then begin
|
||||
IsLinuxExe := FileSignature = Ab_LinuxExeSigWord1; { check 1st sig }
|
||||
if IsLinuxExe then begin
|
||||
Strm.Read(FileSignature, SizeOf(FileSignature)); { check 2nd sig }
|
||||
IsLinuxExe := FileSignature = Ab_LinuxExeSigWord2;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not (IsWinExe or IsLinuxExe) then
|
||||
Result := atUnknown;
|
||||
|
||||
{!!.01 -- end re-written }
|
||||
{ Check for central directory tail }
|
||||
if VerifyZip(Strm) <> atZip then
|
||||
Result := atUnknown;
|
||||
except
|
||||
on EFilerError do
|
||||
Result := atUnknown;
|
||||
end;
|
||||
|
||||
if not (IsWinExe or IsLinuxExe) then
|
||||
Result := atUnknown;
|
||||
|
||||
{!!.01 -- end re-written }
|
||||
{ Check for central directory tail }
|
||||
if VerifyZip(Strm) <> atZip then
|
||||
Result := atUnknown;
|
||||
|
||||
Strm.Position := StartPos;
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -793,12 +793,20 @@ end;
|
|||
|
||||
function CanYouHandleThisFile(FileName: PAnsiChar): Boolean; stdcall;
|
||||
begin
|
||||
Result:= (AbDetermineArcType(SysToUtf8(StrPas(FileName)), atUnknown) <> atUnknown);
|
||||
try
|
||||
Result:= (AbDetermineArcType(SysToUtf8(StrPas(FileName)), atUnknown) <> atUnknown);
|
||||
except
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CanYouHandleThisFileW(FileName: PWideChar): Boolean; stdcall;
|
||||
begin
|
||||
Result:= (AbDetermineArcType(UTF8Encode(WideString(FileName)), atUnknown) <> atUnknown);
|
||||
try
|
||||
Result:= (AbDetermineArcType(UTF8Encode(WideString(FileName)), atUnknown) <> atUnknown);
|
||||
except
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetDlgProc(var SetDlgProcInfo: TSetDlgProcInfo);stdcall;
|
||||
|
|
@ -900,4 +908,4 @@ begin
|
|||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue