FIX: [Zip plugin] Handling errors when detecting archive type.

This commit is contained in:
cobines 2010-04-29 11:30:28 +00:00
commit 278b9880d8
5 changed files with 154 additions and 120 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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.