max
New Member
Posts: 3
|
Post by max on Jun 11, 2007 6:00:07 GMT -5
Hi,
After upgrading from 2.23 to 3.06 we experience some problems:
1) An access violation while unzipping, this does not happen very often 1 out of 100 or so.
The problem looks like in unit kpZipObj line 1449: j := j - SizeOf(zip64_end_of_central_locator); zip64Locator := zip64_end_of_central_locatorPtr(@tmpbuff[j]); if (zip64Locator^.ID = ZIP64EOCL) then begin ... there is a case when j is zero at the beginning, so the if statement goes to av.
2) Directory left open. For now did not manage to locate where it is happening. If there is already an update for it please advice.
thanks
max
|
|
max
New Member
Posts: 3
|
Post by max on Jul 13, 2007 9:27:01 GMT -5
Problem 1
Happens when CheckArchive is called for an empty zip
suggested fix:
j := j - SizeOf(zip64_end_of_central_locator); if j>=0 then // fixes the problem begin zip64Locator := zip64_end_of_central_locatorPtr(@tmpbuff[j]); if (zip64Locator^.ID = ZIP64EOCL) then
Problem 2
Happens in multi threaded environment in functions DirExists(Dir: string): Boolean
KpLib.pas function DirExists(Dir: string): Boolean; begin Result := kpSmall.DirExists(Dir); end;
KpSmall.pas function DirExists(Dir: String): Boolean; var OldDir: String; begin {$I-} GetDir(0, OldDir); ChDir(Dir); Result:= IOResult = 0; ChDir(OldDir); {$I+} end;
Here GetDir, ChDir and IOResult are not multi threaded, so if we have a threads collision there the current directory of the Process can become a temporary directory of the ZIP-ing or UNZIP-ing, so this temporary directory will remain in use and cannot be deleted.
suggested fix:
revert it all to previous code
function DirExists(Dir: string): Boolean; begin {$IFDEF WIN32} {$IFDEF KPSMALL} Result := kpSmall.DirExists(Dir); {$ELSE} Result := DirectoryExists(Dir); {$ENDIF} {$ELSE} {$IFNDEF NOLONGNAMES} if OSVersion > 3 then Result := LFN_FileExists(Dir) else {$ENDIF} begin Dir := LFN_WIN31LongPathToShort(Dir); {$IFDEF KPSMALL} Result := kpSmall.DirExists(Dir); {$ELSE} Result := DirectoryExists(Dir); {$ENDIF} end; {$ENDIF} end;
or even better for {$IFDEF KPSMALL} just map to apis or Sysutils and never use oldish System.pas functions
By the way ForceDirs, GetDirectory and ChDirectory have the same problem, even though it does not affect my code
Thanks Max
|
|
max
New Member
Posts: 3
|
Post by max on Jul 13, 2007 9:42:37 GMT -5
Sorry forgot to mention
A call to DirExists('') in unit VCLZip.pas becomes useless and can be removed for good.
thanks Max
|
|