FIX: Zip - extract Unix symbolic links under Windows (fixes #2659)

This commit is contained in:
Alexander Koblov 2026-01-17 16:55:28 +03:00
commit 0524bcd4e8
3 changed files with 26 additions and 4 deletions

View file

@ -2294,7 +2294,7 @@ begin
FSuspiciousLinks.Add(NormalizePathDelimiters(CurItem.FileName));
end;
if not CreateSymLink(LinkTarget, UseName) then
if not AbCreateSymLinkUnix(LinkTarget, UseName) then
raise EOSError.Create(mbSysErrorMessage(GetLastOSError));
end;
end;

View file

@ -1252,8 +1252,15 @@ begin
ZipArchive.SuspiciousLinks.Add(NormalizePathDelimiters(Item.FileName));
end;
if not CreateSymLink(LinkTarget, UseName, UInt32(Item.NativeFileAttributes)) then
RaiseLastOSError;
if (Item.HostOS = hosUnix) then
begin
if not AbCreateSymLinkUnix(LinkTarget, UseName) then
RaiseLastOSError;
end
else begin
if not CreateSymLink(LinkTarget, UseName, UInt32(Item.NativeFileAttributes)) then
RaiseLastOSError;
end;
except
if ExceptObject is EAbUserAbort then
ZipArchive.FStatus := asInvalid;

View file

@ -39,6 +39,7 @@ uses
{$IFDEF MSWINDOWS}
Windows,
DCWindows,
DCNtfsLinks,
DCConvertEncoding,
{$ENDIF}
{$IFDEF LibcAPI}
@ -64,6 +65,7 @@ uses
DCClassesUtf8,
{$ENDIF}
DCBasicTypes,
DCOSUtils,
DateUtils,
SysUtils,
Classes;
@ -209,6 +211,9 @@ type
because if you have a path x:\dir, and request x:\dir\sub1\sub2,
(/dir and /dir/sub1/sub2 on Unix) it fails.}
function AbCreateSymLinkUnix(const Path, LinkName: string;
Attr: UInt32 = faInvalidAttributes): Boolean;
function AbCreateTempFile(const Dir : string) : string;
function AbGetTempDirectory : string;
@ -377,7 +382,6 @@ uses
LazUTF8,
AbConst,
AbExcept,
DCOSUtils,
DCStrUtils,
DCDateTimeUtils;
@ -487,6 +491,17 @@ begin
until ( Length( TempPath ) = Length( Path ) );
end;
{ -------------------------------------------------------------------------- }
function AbCreateSymLinkUnix(const Path, LinkName: string; Attr: UInt32): Boolean;
{$IF DEFINED(UNIX)}
begin
Result:= CreateSymLink(Path, LinkName, Attr);
end;
{$ELSE}
begin
Result:= CreateSymLinkUnix(Path, UTF16LongName(LinkName));
end;
{$ENDIF}
{ -------------------------------------------------------------------------- }
function AbCreateTempFile(const Dir : string) : string;
begin
Result := AbGetTempFile(Dir, True);