MCPcopy Create free account
hub / github.com/abbeycode/UnrarKit / IsRelativeSymlinkSafe

Function IsRelativeSymlinkSafe

Libraries/unrar/extinfo.cpp:115–160  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

113
114
115bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName)
116{
117 // Catch root dir based /path/file paths also as stuff like \\?\.
118 // Do not check PrepSrcName here, it can be root based if destination path
119 // is a root based.
120 if (IsFullRootPath(SrcName) || IsFullRootPath(TargetName))
121 return false;
122
123 // Number of ".." in link target.
124 int UpLevels=0;
125 for (int Pos=0;*TargetName!=0;Pos++)
126 {
127 bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
128 (IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
129 (Pos==0 || IsPathDiv(*(TargetName-1)));
130 if (Dot2)
131 UpLevels++;
132 TargetName++;
133 }
134 // If link target includes "..", it must not have another links
135 // in the path, because they can bypass our safety check. For example,
136 // suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
137 // or "dir/lnk1" -> ".." first and "dir/lnk1/lnk2" -> ".." next.
138 if (UpLevels>0 && LinkInPath(PrepSrcName))
139 return false;
140
141 // We could check just prepared src name, but for extra safety
142 // we check both original (as from archive header) and prepared
143 // (after applying the destination path and -ep switches) names.
144
145 int AllowedDepth=CalcAllowedDepth(SrcName); // Original name depth.
146
147 // Remove the destination path from prepared name if any. We should not
148 // count the destination path depth, because the link target must point
149 // inside of this path, not outside of it.
150 size_t ExtrPathLength=wcslen(Cmd->ExtrPath);
151 if (ExtrPathLength>0 && wcsncmp(PrepSrcName,Cmd->ExtrPath,ExtrPathLength)==0)
152 {
153 PrepSrcName+=ExtrPathLength;
154 while (IsPathDiv(*PrepSrcName))
155 PrepSrcName++;
156 }
157 int PrepAllowedDepth=CalcAllowedDepth(PrepSrcName);
158
159 return AllowedDepth>=UpLevels && PrepAllowedDepth>=UpLevels;
160}
161
162
163bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)

Callers 3

CreateReparsePointFunction · 0.85
ExtractUnixLink30Function · 0.85
ExtractUnixLink50Function · 0.85

Calls 4

IsFullRootPathFunction · 0.85
IsPathDivFunction · 0.85
LinkInPathFunction · 0.85
CalcAllowedDepthFunction · 0.85

Tested by

no test coverage detected