Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@gmail.com>2015-02-02 19:20:50 +0300
committerXhmikosR <xhmikosr@gmail.com>2015-02-17 00:30:36 +0300
commitb42b48edf2dfa3767a80d56ac1e9e9255ab78151 (patch)
tree607cc60a08c54fd54170d3520f863452965023ee /src/thirdparty/unrar
parent98c02856528b848b5c286176585c2599910ded58 (diff)
Update Unrar to v5.2.6.
Diffstat (limited to 'src/thirdparty/unrar')
-rw-r--r--src/thirdparty/unrar/arcread.cpp3
-rw-r--r--src/thirdparty/unrar/cmddata.cpp11
-rw-r--r--src/thirdparty/unrar/cmddata.hpp3
-rw-r--r--src/thirdparty/unrar/dll.rc8
-rw-r--r--src/thirdparty/unrar/extinfo.cpp35
-rw-r--r--src/thirdparty/unrar/extinfo.hpp1
-rw-r--r--src/thirdparty/unrar/extract.cpp42
-rw-r--r--src/thirdparty/unrar/file.cpp8
-rw-r--r--src/thirdparty/unrar/file.hpp2
-rw-r--r--src/thirdparty/unrar/loclang.hpp2
-rw-r--r--src/thirdparty/unrar/options.hpp1
-rw-r--r--src/thirdparty/unrar/pathfn.cpp8
-rw-r--r--src/thirdparty/unrar/pathfn.hpp1
-rw-r--r--src/thirdparty/unrar/ulinks.cpp16
-rw-r--r--src/thirdparty/unrar/version.hpp6
-rw-r--r--src/thirdparty/unrar/win32lnk.cpp37
16 files changed, 124 insertions, 60 deletions
diff --git a/src/thirdparty/unrar/arcread.cpp b/src/thirdparty/unrar/arcread.cpp
index e8e5991da..047289b7a 100644
--- a/src/thirdparty/unrar/arcread.cpp
+++ b/src/thirdparty/unrar/arcread.cpp
@@ -886,7 +886,8 @@ void Archive::RequestArcPassword()
ErrHandler.Exit(RARX_USERBREAK);
}
#else
- if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password))
+ if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password) ||
+ !Cmd->Password.IsSet())
{
Close();
uiMsg(UIERROR_INCERRCOUNT);
diff --git a/src/thirdparty/unrar/cmddata.cpp b/src/thirdparty/unrar/cmddata.cpp
index b56410ae9..3f84cc373 100644
--- a/src/thirdparty/unrar/cmddata.cpp
+++ b/src/thirdparty/unrar/cmddata.cpp
@@ -616,6 +616,8 @@ void CommandData::ProcessSwitch(const wchar *Switch)
#ifdef SAVE_LINKS
case 'L':
SaveSymLinks=true;
+ if (toupperw(Switch[2])=='A')
+ AbsoluteLinks=true;
break;
#endif
case 'R':
@@ -958,7 +960,7 @@ void CommandData::OutHelp(RAR_EXIT ExitCode)
MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,
MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
- MCHelpSwO,MCHelpSwOC,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
+ MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSL,MCHelpSwSM,
MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,
MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,
@@ -1157,8 +1159,11 @@ bool CommandData::SizeCheck(int64 Size)
-int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType)
+int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
+ wchar *MatchedArg,uint MatchedArgSize)
{
+ if (MatchedArg!=NULL && MatchedArgSize>0)
+ *MatchedArg=0;
if (wcslen(FileHead.FileName)>=NM)
return 0;
bool Dir=FileHead.Dir;
@@ -1179,6 +1184,8 @@ int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchTy
{
if (ExactMatch!=NULL)
*ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
+ if (MatchedArg!=NULL)
+ wcsncpyz(MatchedArg,ArgName,MatchedArgSize);
return StringCount;
}
return 0;
diff --git a/src/thirdparty/unrar/cmddata.hpp b/src/thirdparty/unrar/cmddata.hpp
index 3ed4ef1d8..d2cdbb94d 100644
--- a/src/thirdparty/unrar/cmddata.hpp
+++ b/src/thirdparty/unrar/cmddata.hpp
@@ -37,7 +37,8 @@ class CommandData:public RAROptions
bool TimeCheck(RarTime &ft);
bool SizeCheck(int64 Size);
bool AnyFiltersActive();
- int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH);
+ int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH,
+ wchar *MatchedArg=NULL,uint MatchedArgSize=0);
void ProcessCommand();
void AddArcName(const wchar *Name);
bool GetArcName(wchar *Name,int MaxSize);
diff --git a/src/thirdparty/unrar/dll.rc b/src/thirdparty/unrar/dll.rc
index 3c90c69cb..7de848921 100644
--- a/src/thirdparty/unrar/dll.rc
+++ b/src/thirdparty/unrar/dll.rc
@@ -2,8 +2,8 @@
#include <commctrl.h>
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 5, 21, 1, 1472
-PRODUCTVERSION 5, 21, 1, 1472
+FILEVERSION 5, 21, 100, 1509
+PRODUCTVERSION 5, 21, 100, 1509
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@@ -14,8 +14,8 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
- VALUE "FileVersion", "5.21.1\0"
- VALUE "ProductVersion", "5.21.1\0"
+ VALUE "FileVersion", "5.21.0\0"
+ VALUE "ProductVersion", "5.21.0\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2015\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
diff --git a/src/thirdparty/unrar/extinfo.cpp b/src/thirdparty/unrar/extinfo.cpp
index 141967f2a..01827eba0 100644
--- a/src/thirdparty/unrar/extinfo.cpp
+++ b/src/thirdparty/unrar/extinfo.cpp
@@ -60,14 +60,45 @@ void SetExtraInfo(CommandData *Cmd,Archive &Arc,wchar *Name)
+bool IsRelativeSymlinkSafe(const wchar *SrcName,const wchar *TargetName)
+{
+ if (IsFullRootPath(SrcName))
+ return false;
+ int AllowedDepth=0;
+ while (*SrcName!=0)
+ {
+ if (IsPathDiv(SrcName[0]) && SrcName[1]!=0 && !IsPathDiv(SrcName[1]))
+ {
+ bool Dot=SrcName[1]=='.' && (IsPathDiv(SrcName[2]) || SrcName[2]==0);
+ bool Dot2=SrcName[1]=='.' && SrcName[2]=='.' && (IsPathDiv(SrcName[3]) || SrcName[3]==0);
+ if (!Dot && !Dot2)
+ AllowedDepth++;
+ }
+ SrcName++;
+ }
+ if (IsFullRootPath(TargetName)) // Catch root dir based /path/file paths.
+ return false;
+ for (int Pos=0;*TargetName!=0;Pos++)
+ {
+ bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
+ (IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
+ (Pos==0 || IsPathDiv(*(TargetName-1)));
+ if (Dot2)
+ AllowedDepth--;
+ TargetName++;
+ }
+ return AllowedDepth>=0;
+}
+
+
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
{
#if defined(SAVE_LINKS) && defined(_UNIX)
// For RAR 3.x archives we process links even in test mode to skip link data.
if (Arc.Format==RARFMT15)
- return ExtractUnixLink30(DataIO,Arc,LinkName);
+ return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName);
if (Arc.Format==RARFMT50)
- return ExtractUnixLink50(LinkName,&Arc.FileHead);
+ return ExtractUnixLink50(Cmd,LinkName,&Arc.FileHead);
#elif defined _WIN_ALL
// RAR 5.0 archives store link information in file header, so there is
// no need to additionally test it if we do not create a file.
diff --git a/src/thirdparty/unrar/extinfo.hpp b/src/thirdparty/unrar/extinfo.hpp
index 224564da8..b974bf489 100644
--- a/src/thirdparty/unrar/extinfo.hpp
+++ b/src/thirdparty/unrar/extinfo.hpp
@@ -1,6 +1,7 @@
#ifndef _RAR_EXTINFO_
#define _RAR_EXTINFO_
+bool IsRelativeSymlinkSafe(const wchar *SrcName,const wchar *TargetName);
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName);
#ifdef _UNIX
void SetUnixOwner(Archive &Arc,const wchar *FileName);
diff --git a/src/thirdparty/unrar/extract.cpp b/src/thirdparty/unrar/extract.cpp
index fb5a39d5b..26be36ac2 100644
--- a/src/thirdparty/unrar/extract.cpp
+++ b/src/thirdparty/unrar/extract.cpp
@@ -259,17 +259,19 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
int MatchType=MATCH_WILDSUBPATH;
bool EqualNames=false;
- int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType);
- bool ExactMatch=MatchNumber!=0;
+ wchar MatchedArg[NM];
+ int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType,MatchedArg,ASIZE(MatchedArg));
+ bool MatchFound=MatchNumber!=0;
#ifndef SFX_MODULE
- if (*Cmd->ArcPath==0 && Cmd->ExclPath==EXCL_BASEPATH && ExactMatch)
+ if (Cmd->ExclPath==EXCL_BASEPATH)
{
- Cmd->FileArgs.Rewind();
- if (Cmd->FileArgs.GetString(Cmd->ArcPath,ASIZE(Cmd->ArcPath),MatchNumber-1))
- *PointToName(Cmd->ArcPath)=0;
+ wcsncpyz(Cmd->ArcPath,MatchedArg,ASIZE(Cmd->ArcPath));
+ *PointToName(Cmd->ArcPath)=0;
+ if (IsWildcard(Cmd->ArcPath)) // Cannot correctly process path*\* masks here.
+ *Cmd->ArcPath=0;
}
#endif
- if (ExactMatch && !EqualNames)
+ if (MatchFound && !EqualNames)
AllMatchesExact=false;
Arc.ConvertAttributes();
@@ -311,17 +313,17 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
if (Cmd->VersionControl!=1 && !EqualNames)
{
if (Cmd->VersionControl==0)
- ExactMatch=false;
+ MatchFound=false;
int Version=ParseVersionFileName(ArcFileName,false);
if (Cmd->VersionControl-1==Version)
ParseVersionFileName(ArcFileName,true);
else
- ExactMatch=false;
+ MatchFound=false;
}
}
else
if (!Arc.IsArcDir() && Cmd->VersionControl>1)
- ExactMatch=false;
+ MatchFound=false;
DataIO.UnpVolume=Arc.FileHead.SplitAfter;
DataIO.NextVolumeMissing=false;
@@ -332,9 +334,9 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
bool SkipSolid=false;
#ifndef SFX_MODULE
- if (FirstFile && (ExactMatch || Arc.Solid) && Arc.FileHead.SplitBefore)
+ if (FirstFile && (MatchFound || Arc.Solid) && Arc.FileHead.SplitBefore)
{
- if (ExactMatch)
+ if (MatchFound)
{
uiMsg(UIERROR_NEEDPREVVOL,Arc.FileName,ArcFileName);
#ifdef RARDLL
@@ -342,13 +344,13 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
#endif
ErrHandler.SetErrorCode(RARX_OPEN);
}
- ExactMatch=false;
+ MatchFound=false;
}
FirstFile=false;
#endif
- if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
+ if (MatchFound || (SkipSolid=Arc.Solid)!=0)
{
// First common call of uiStartFileExtract. It is done before overwrite
// prompts, so if SkipSolid state is changed below, we'll need to make
@@ -408,13 +410,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
#ifdef RARDLL
if (*Cmd->DllDestName!=0)
- {
wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
-
-// Do we need this code?
-// if (Cmd->DllOpMode!=RAR_EXTRACT)
-// ExtrFile=false;
- }
#endif
if (!CheckUnpVer(Arc,ArcFileName))
@@ -713,7 +709,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
}
}
}
- if (ExactMatch)
+ if (MatchFound)
MatchedArgs++;
if (DataIO.NextVolumeMissing)
return false;
@@ -884,8 +880,10 @@ bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
{
if (!Cmd->Password.IsSet())
{
- if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
+ if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password) || !Cmd->Password.IsSet())
{
+ // Suppress "test is ok" message in GUI if user entered
+ // an empty password or cancelled a password prompt.
uiMsg(UIERROR_INCERRCOUNT);
return false;
diff --git a/src/thirdparty/unrar/file.cpp b/src/thirdparty/unrar/file.cpp
index 8fba34adb..185474c25 100644
--- a/src/thirdparty/unrar/file.cpp
+++ b/src/thirdparty/unrar/file.cpp
@@ -281,10 +281,10 @@ bool File::Rename(const wchar *NewName)
}
-void File::Write(const void *Data,size_t Size)
+bool File::Write(const void *Data,size_t Size)
{
if (Size==0)
- return;
+ return true;
if (HandleType==FILE_HANDLESTD)
{
#ifdef _WIN_ALL
@@ -301,9 +301,10 @@ void File::Write(const void *Data,size_t Size)
}
#endif
}
+ bool Success;
while (1)
{
- bool Success=false;
+ Success=false;
#ifdef _WIN_ALL
DWORD Written=0;
if (HandleType!=FILE_HANDLENORMAL)
@@ -352,6 +353,7 @@ void File::Write(const void *Data,size_t Size)
break;
}
LastWrite=true;
+ return Success; // It can return false only if AllowExceptions is disabled.
}
diff --git a/src/thirdparty/unrar/file.hpp b/src/thirdparty/unrar/file.hpp
index 93aac89f3..0d6534ff7 100644
--- a/src/thirdparty/unrar/file.hpp
+++ b/src/thirdparty/unrar/file.hpp
@@ -80,7 +80,7 @@ class File
bool Close();
bool Delete();
bool Rename(const wchar *NewName);
- void Write(const void *Data,size_t Size);
+ bool Write(const void *Data,size_t Size);
virtual int Read(void *Data,size_t Size);
int DirectRead(void *Data,size_t Size);
virtual void Seek(int64 Offset,int Method);
diff --git a/src/thirdparty/unrar/loclang.hpp b/src/thirdparty/unrar/loclang.hpp
index fb560713a..52bcafe92 100644
--- a/src/thirdparty/unrar/loclang.hpp
+++ b/src/thirdparty/unrar/loclang.hpp
@@ -99,7 +99,7 @@
#define MCHelpSwOC L"\n oc Set NTFS Compressed attribute"
#define MCHelpSwOH L"\n oh Save hard links as the link instead of the file"
#define MCHelpSwOI L"\n oi[0-4][:min] Save identical files as references"
-#define MCHelpSwOL L"\n ol Save symbolic links as the link instead of the file"
+#define MCHelpSwOL L"\n ol[a] Process symbolic links as the link [absolute paths]"
#define MCHelpSwOR L"\n or Rename files automatically"
#define MCHelpSwOS L"\n os Save NTFS streams"
#define MCHelpSwOW L"\n ow Save or restore file owner and group"
diff --git a/src/thirdparty/unrar/options.hpp b/src/thirdparty/unrar/options.hpp
index ba9c0ca82..a6ec227f0 100644
--- a/src/thirdparty/unrar/options.hpp
+++ b/src/thirdparty/unrar/options.hpp
@@ -132,6 +132,7 @@ class RAROptions
bool ProcessOwners;
bool SaveSymLinks;
bool SaveHardLinks;
+ bool AbsoluteLinks;
int Priority;
int SleepTime;
bool KeepBroken;
diff --git a/src/thirdparty/unrar/pathfn.cpp b/src/thirdparty/unrar/pathfn.cpp
index bfd3b588e..b6e220eee 100644
--- a/src/thirdparty/unrar/pathfn.cpp
+++ b/src/thirdparty/unrar/pathfn.cpp
@@ -29,7 +29,7 @@ wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
while (*DestPtr!=0)
{
const wchar *s=DestPtr;
- if (s[0] && IsDriveDiv(s[1]))
+ if (s[0]!=0 && IsDriveDiv(s[1]))
s+=2;
if (s[0]=='\\' && s[1]=='\\')
{
@@ -541,6 +541,12 @@ bool IsFullPath(const wchar *Path)
}
+bool IsFullRootPath(const wchar *Path)
+{
+ return IsFullPath(Path) || IsPathDiv(Path[0]);
+}
+
+
bool IsDiskLetter(const wchar *Path)
{
wchar Letter=etoupperw(Path[0]);
diff --git a/src/thirdparty/unrar/pathfn.hpp b/src/thirdparty/unrar/pathfn.hpp
index fabb29340..ae1f8c2e8 100644
--- a/src/thirdparty/unrar/pathfn.hpp
+++ b/src/thirdparty/unrar/pathfn.hpp
@@ -56,6 +56,7 @@ inline void SlashToNative(const wchar *SrcName,wchar *DestName,size_t MaxLength)
void ConvertNameToFull(const wchar *Src,wchar *Dest,size_t MaxSize);
bool IsFullPath(const wchar *Path);
+bool IsFullRootPath(const wchar *Path);
bool IsDiskLetter(const wchar *Path);
void GetPathRoot(const wchar *Path,wchar *Root,size_t MaxSize);
int ParseVersionFileName(wchar *Name,bool Truncate);
diff --git a/src/thirdparty/unrar/ulinks.cpp b/src/thirdparty/unrar/ulinks.cpp
index b51ff6282..f3e51b52e 100644
--- a/src/thirdparty/unrar/ulinks.cpp
+++ b/src/thirdparty/unrar/ulinks.cpp
@@ -30,7 +30,13 @@ static bool UnixSymlink(const char *Target,const wchar *LinkName,RarTime *ftm,Ra
}
-bool ExtractUnixLink30(ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
+static bool IsFullPath(const char *PathA) // Unix ASCII version.
+{
+ return *PathA==CPATHDIVIDER;
+}
+
+
+bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
{
char Target[NM];
if (IsLink(Arc.FileHead.FileAttr))
@@ -48,13 +54,16 @@ bool ExtractUnixLink30(ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
if (!DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL))
return true;
+ if (!Cmd->AbsoluteLinks && (IsFullPath(Target) ||
+ !IsRelativeSymlinkSafe(Arc.FileHead.FileName,Arc.FileHead.RedirName)))
+
return UnixSymlink(Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
}
return false;
}
-bool ExtractUnixLink50(const wchar *Name,FileHeader *hd)
+bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)
{
char Target[NM];
WideToChar(hd->RedirName,Target,ASIZE(Target));
@@ -68,5 +77,8 @@ bool ExtractUnixLink50(const wchar *Name,FileHeader *hd)
return false;
DosSlashToUnix(Target,Target,ASIZE(Target));
}
+ if (!Cmd->AbsoluteLinks && (IsFullPath(Target) ||
+ !IsRelativeSymlinkSafe(hd->FileName,hd->RedirName)))
+ return false;
return UnixSymlink(Target,Name,&hd->mtime,&hd->atime);
}
diff --git a/src/thirdparty/unrar/version.hpp b/src/thirdparty/unrar/version.hpp
index b2844b691..8518b5516 100644
--- a/src/thirdparty/unrar/version.hpp
+++ b/src/thirdparty/unrar/version.hpp
@@ -1,6 +1,6 @@
#define RARVER_MAJOR 5
#define RARVER_MINOR 21
-#define RARVER_BETA 1
-#define RARVER_DAY 9
-#define RARVER_MONTH 1
+#define RARVER_BETA 0
+#define RARVER_DAY 15
+#define RARVER_MONTH 2
#define RARVER_YEAR 2015
diff --git a/src/thirdparty/unrar/win32lnk.cpp b/src/thirdparty/unrar/win32lnk.cpp
index f911be98e..b291056f0 100644
--- a/src/thirdparty/unrar/win32lnk.cpp
+++ b/src/thirdparty/unrar/win32lnk.cpp
@@ -40,23 +40,6 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd)
PrivSet=true;
}
- CreatePath(Name,true);
-
- // 'DirTarget' check is important for Unix symlinks to directories.
- // Unix symlinks do not have their own 'directory' attribute.
- if (hd->Dir || hd->DirTarget)
- {
- if (!CreateDirectory(Name,NULL))
- return false;
- }
- else
- {
- HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- return false;
- CloseHandle(hFile);
- }
-
const DWORD BufSize=sizeof(REPARSE_DATA_BUFFER)+2*NM+1024;
Array<byte> Buf(BufSize);
REPARSE_DATA_BUFFER *rdb=(REPARSE_DATA_BUFFER *)&Buf[0];
@@ -79,6 +62,26 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd)
size_t PrintLength=wcslen(PrintName);
bool AbsPath=WinPrefix;
+ if (!Cmd->AbsoluteLinks && (AbsPath || !IsRelativeSymlinkSafe(hd->FileName,hd->RedirName)))
+ return false;
+
+ CreatePath(Name,true);
+
+ // 'DirTarget' check is important for Unix symlinks to directories.
+ // Unix symlinks do not have their own 'directory' attribute.
+ if (hd->Dir || hd->DirTarget)
+ {
+ if (!CreateDirectory(Name,NULL))
+ return false;
+ }
+ else
+ {
+ HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return false;
+ CloseHandle(hFile);
+ }
+
if (hd->RedirType==FSREDIR_JUNCTION)
{