unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ulinks.cpp
Go to the documentation of this file.
1
2
3static bool UnixSymlink(CommandData *Cmd,const char *Target,const wchar *LinkName,RarTime *ftm,RarTime *fta)
4{
5 CreatePath(LinkName,true,Cmd->DisableNames);
6
7 // Overwrite prompt was already issued and confirmed earlier, so we can
8 // remove existing symlink or regular file here. PrepareToDelete was also
9 // called earlier inside of uiAskReplaceEx.
10 DelFile(LinkName);
11
12 char LinkNameA[NM];
13 WideToChar(LinkName,LinkNameA,ASIZE(LinkNameA));
14 if (symlink(Target,LinkNameA)==-1) // Error.
15 {
16 if (errno==EEXIST)
17 uiMsg(UIERROR_ULINKEXIST,LinkName);
18 else
19 {
22 }
23 return false;
24 }
25#ifdef USE_LUTIMES
26#ifdef UNIX_TIME_NS
27 timespec times[2];
28 times[0].tv_sec=fta->GetUnix();
29 times[0].tv_nsec=fta->IsSet() ? long(fta->GetUnixNS()%1000000000) : UTIME_NOW;
30 times[1].tv_sec=ftm->GetUnix();
31 times[1].tv_nsec=ftm->IsSet() ? long(ftm->GetUnixNS()%1000000000) : UTIME_NOW;
32 utimensat(AT_FDCWD,LinkNameA,times,AT_SYMLINK_NOFOLLOW);
33#else
34 struct timeval tv[2];
35 tv[0].tv_sec=fta->GetUnix();
36 tv[0].tv_usec=long(fta->GetUnixNS()%1000000000/1000);
37 tv[1].tv_sec=ftm->GetUnix();
38 tv[1].tv_usec=long(ftm->GetUnixNS()%1000000000/1000);
39 lutimes(LinkNameA,tv);
40#endif
41#endif
42
43 return true;
44}
45
46
47static bool IsFullPath(const char *PathA) // Unix ASCII version.
48{
49 return *PathA==CPATHDIVIDER;
50}
51
52
53// For security purpose we prefer to be sure that CharToWide completed
54// successfully and even if it truncated a string for some reason,
55// it didn't affect the number of path related characters we analyze
56// in IsRelativeSymlinkSafe later.
57// This check is likely to be excessive, but let's keep it anyway.
58static bool SafeCharToWide(const char *Src,wchar *Dest,size_t DestSize)
59{
60 if (!CharToWide(Src,Dest,DestSize) || *Dest==0)
61 return false;
62 uint SrcChars=0,DestChars=0;
63 for (uint I=0;Src[I]!=0;I++)
64 if (Src[I]=='/' || Src[I]=='.')
65 SrcChars++;
66 for (uint I=0;Dest[I]!=0;I++)
67 if (Dest[I]=='/' || Dest[I]=='.')
68 DestChars++;
69 return SrcChars==DestChars;
70}
71
72
73bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
74{
75 char Target[NM];
76 if (IsLink(Arc.FileHead.FileAttr))
77 {
78 size_t DataSize=(size_t)Arc.FileHead.PackSize;
79 if (DataSize>ASIZE(Target)-1)
80 return false;
81 if ((size_t)DataIO.UnpRead((byte *)Target,DataSize)!=DataSize)
82 return false;
83 Target[DataSize]=0;
84
85 DataIO.UnpHash.Init(Arc.FileHead.FileHash.Type,1);
86 DataIO.UnpHash.Update(Target,strlen(Target));
87 DataIO.UnpHash.Result(&Arc.FileHead.FileHash);
88
89 // Return true in case of bad checksum, so link will be processed further
90 // and extraction routine will report the checksum error.
91 if (!DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL))
92 return true;
93
94 wchar TargetW[NM];
95 if (!SafeCharToWide(Target,TargetW,ASIZE(TargetW)))
96 return false;
97 // Use Arc.FileHead.FileName instead of LinkName, since LinkName
98 // can include the destination path as a prefix, which can
99 // confuse IsRelativeSymlinkSafe algorithm.
100 if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
101 !IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))
102 return false;
103 return UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
104 }
105 return false;
106}
107
108
110{
111 char Target[NM];
112 WideToChar(hd->RedirName,Target,ASIZE(Target));
114 {
115 // Cannot create Windows absolute path symlinks in Unix. Only relative path
116 // Windows symlinks can be created here. RAR 5.0 used \??\ prefix
117 // for Windows absolute symlinks, since RAR 5.1 /??/ is used.
118 // We escape ? as \? to avoid "trigraph" warning
119 if (strncmp(Target,"\\??\\",4)==0 || strncmp(Target,"/\?\?/",4)==0)
120 return false;
121 DosSlashToUnix(Target,Target,ASIZE(Target));
122 }
123
124 wchar TargetW[NM];
125 if (!SafeCharToWide(Target,TargetW,ASIZE(TargetW)))
126 return false;
127 // Use hd->FileName instead of LinkName, since LinkName can include
128 // the destination path as a prefix, which can confuse
129 // IsRelativeSymlinkSafe algorithm.
130 // 2022.05.04: Use TargetW instead of previously used hd->RedirName
131 // for security reason.
132 if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
133 !IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,TargetW)))
134 return false;
135 return UnixSymlink(Cmd,Target,Name,&hd->mtime,&hd->atime);
136}
ErrorHandler ErrHandler
FileHeader FileHead
Definition: archive.hpp:104
DataHash UnpHash
Definition: rdwrfn.hpp:99
int UnpRead(byte *Addr, size_t Count)
Definition: rdwrfn.cpp:56
void Init(HASH_TYPE Type, uint MaxThreads)
Definition: hash.cpp:67
void Update(const void *Data, size_t DataSize)
Definition: hash.cpp:84
void Result(HashValue *Result)
Definition: hash.cpp:106
bool Cmp(HashValue *CmpValue, byte *Key)
Definition: hash.cpp:128
void SetErrorCode(RAR_EXIT Code)
Definition: errhnd.cpp:243
bool AbsoluteLinks
Definition: options.hpp:160
bool DisableNames
Definition: options.hpp:138
time_t GetUnix()
Definition: timefn.cpp:164
bool IsSet()
Definition: timefn.hpp:58
uint64 GetUnixNS()
Definition: timefn.cpp:184
@ RARX_WARNING
Definition: errhnd.hpp:7
bool IsRelativeSymlinkSafe(CommandData *Cmd, const wchar *SrcName, const wchar *PrepSrcName, const wchar *TargetName)
Definition: extinfo.cpp:115
bool DelFile(const wchar *Name)
Definition: filefn.cpp:461
bool IsLink(uint Attr)
Definition: filefn.cpp:238
bool CreatePath(const wchar *Path, bool SkipLastName, bool Silent)
Definition: filefn.cpp:41
@ FSREDIR_WINSYMLINK
Definition: headers.hpp:109
@ FSREDIR_JUNCTION
Definition: headers.hpp:109
void DosSlashToUnix(const char *SrcName, char *DestName, size_t MaxLength)
Definition: pathfn.cpp:500
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
unsigned int uint
Definition: rartypes.hpp:8
RarTime atime
Definition: headers.hpp:190
HashValue FileHash
Definition: headers.hpp:196
bool UseHashKey
Definition: headers.hpp:214
wchar FileName[NM]
Definition: headers.hpp:184
byte HashKey[SHA256_DIGEST_SIZE]
Definition: headers.hpp:218
int64 PackSize
Definition: headers.hpp:192
wchar RedirName[NM]
Definition: headers.hpp:239
RarTime mtime
Definition: headers.hpp:188
FILE_SYSTEM_REDIRECT RedirType
Definition: headers.hpp:238
uint FileAttr
Definition: headers.hpp:181
HASH_TYPE Type
Definition: hash.hpp:12
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
#define UINULL
Definition: ui.hpp:146
@ UIERROR_ULINKEXIST
Definition: ui.hpp:40
@ UIERROR_SLINKCREATE
Definition: ui.hpp:16
bool WideToChar(const wchar *Src, char *Dest, size_t DestSize)
Definition: unicode.cpp:20
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85