1370b324cSopenharmony_ci// Common/Wildcard.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "Wildcard.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ciextern 8370b324cSopenharmony_cibool g_CaseSensitive; 9370b324cSopenharmony_cibool g_CaseSensitive = 10370b324cSopenharmony_ci #ifdef _WIN32 11370b324cSopenharmony_ci false; 12370b324cSopenharmony_ci #elif defined (__APPLE__) 13370b324cSopenharmony_ci #ifdef TARGET_OS_IPHONE 14370b324cSopenharmony_ci true; 15370b324cSopenharmony_ci #else 16370b324cSopenharmony_ci false; 17370b324cSopenharmony_ci #endif 18370b324cSopenharmony_ci #else 19370b324cSopenharmony_ci true; 20370b324cSopenharmony_ci #endif 21370b324cSopenharmony_ci 22370b324cSopenharmony_ci 23370b324cSopenharmony_cibool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2) 24370b324cSopenharmony_ci{ 25370b324cSopenharmony_ci if (g_CaseSensitive) 26370b324cSopenharmony_ci return IsString1PrefixedByString2(s1, s2); 27370b324cSopenharmony_ci return IsString1PrefixedByString2_NoCase(s1, s2); 28370b324cSopenharmony_ci} 29370b324cSopenharmony_ci 30370b324cSopenharmony_ci// #include <stdio.h> 31370b324cSopenharmony_ci 32370b324cSopenharmony_ci/* 33370b324cSopenharmony_cistatic int MyStringCompare_PathLinux(const wchar_t *s1, const wchar_t *s2) throw() 34370b324cSopenharmony_ci{ 35370b324cSopenharmony_ci for (;;) 36370b324cSopenharmony_ci { 37370b324cSopenharmony_ci wchar_t c1 = *s1++; 38370b324cSopenharmony_ci wchar_t c2 = *s2++; 39370b324cSopenharmony_ci if (c1 != c2) 40370b324cSopenharmony_ci { 41370b324cSopenharmony_ci if (c1 == 0) return -1; 42370b324cSopenharmony_ci if (c2 == 0) return 1; 43370b324cSopenharmony_ci if (c1 == '/') c1 = 0; 44370b324cSopenharmony_ci if (c2 == '/') c2 = 0; 45370b324cSopenharmony_ci if (c1 < c2) return -1; 46370b324cSopenharmony_ci if (c1 > c2) return 1; 47370b324cSopenharmony_ci continue; 48370b324cSopenharmony_ci } 49370b324cSopenharmony_ci if (c1 == 0) return 0; 50370b324cSopenharmony_ci } 51370b324cSopenharmony_ci} 52370b324cSopenharmony_ci*/ 53370b324cSopenharmony_ci 54370b324cSopenharmony_cistatic int MyStringCompare_Path(const wchar_t *s1, const wchar_t *s2) throw() 55370b324cSopenharmony_ci{ 56370b324cSopenharmony_ci for (;;) 57370b324cSopenharmony_ci { 58370b324cSopenharmony_ci wchar_t c1 = *s1++; 59370b324cSopenharmony_ci wchar_t c2 = *s2++; 60370b324cSopenharmony_ci if (c1 != c2) 61370b324cSopenharmony_ci { 62370b324cSopenharmony_ci if (c1 == 0) return -1; 63370b324cSopenharmony_ci if (c2 == 0) return 1; 64370b324cSopenharmony_ci if (IS_PATH_SEPAR(c1)) c1 = 0; 65370b324cSopenharmony_ci if (IS_PATH_SEPAR(c2)) c2 = 0; 66370b324cSopenharmony_ci if (c1 < c2) return -1; 67370b324cSopenharmony_ci if (c1 > c2) return 1; 68370b324cSopenharmony_ci continue; 69370b324cSopenharmony_ci } 70370b324cSopenharmony_ci if (c1 == 0) return 0; 71370b324cSopenharmony_ci } 72370b324cSopenharmony_ci} 73370b324cSopenharmony_ci 74370b324cSopenharmony_cistatic int MyStringCompareNoCase_Path(const wchar_t *s1, const wchar_t *s2) throw() 75370b324cSopenharmony_ci{ 76370b324cSopenharmony_ci for (;;) 77370b324cSopenharmony_ci { 78370b324cSopenharmony_ci wchar_t c1 = *s1++; 79370b324cSopenharmony_ci wchar_t c2 = *s2++; 80370b324cSopenharmony_ci if (c1 != c2) 81370b324cSopenharmony_ci { 82370b324cSopenharmony_ci if (c1 == 0) return -1; 83370b324cSopenharmony_ci if (c2 == 0) return 1; 84370b324cSopenharmony_ci if (IS_PATH_SEPAR(c1)) c1 = 0; 85370b324cSopenharmony_ci if (IS_PATH_SEPAR(c2)) c2 = 0; 86370b324cSopenharmony_ci c1 = MyCharUpper(c1); 87370b324cSopenharmony_ci c2 = MyCharUpper(c2); 88370b324cSopenharmony_ci if (c1 < c2) return -1; 89370b324cSopenharmony_ci if (c1 > c2) return 1; 90370b324cSopenharmony_ci continue; 91370b324cSopenharmony_ci } 92370b324cSopenharmony_ci if (c1 == 0) return 0; 93370b324cSopenharmony_ci } 94370b324cSopenharmony_ci} 95370b324cSopenharmony_ci 96370b324cSopenharmony_ciint CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW 97370b324cSopenharmony_ci{ 98370b324cSopenharmony_ci /* 99370b324cSopenharmony_ci printf("\nCompareFileNames"); 100370b324cSopenharmony_ci printf("\n S1: %ls", s1); 101370b324cSopenharmony_ci printf("\n S2: %ls", s2); 102370b324cSopenharmony_ci printf("\n"); 103370b324cSopenharmony_ci */ 104370b324cSopenharmony_ci // 21.07 : we parse PATH_SEPARATOR so: 0 < PATH_SEPARATOR < 1 105370b324cSopenharmony_ci if (g_CaseSensitive) 106370b324cSopenharmony_ci return MyStringCompare_Path(s1, s2); 107370b324cSopenharmony_ci return MyStringCompareNoCase_Path(s1, s2); 108370b324cSopenharmony_ci} 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci#ifndef USE_UNICODE_FSTRING 111370b324cSopenharmony_ciint CompareFileNames(const char *s1, const char *s2) 112370b324cSopenharmony_ci{ 113370b324cSopenharmony_ci const UString u1 = fs2us(s1); 114370b324cSopenharmony_ci const UString u2 = fs2us(s2); 115370b324cSopenharmony_ci return CompareFileNames(u1, u2); 116370b324cSopenharmony_ci} 117370b324cSopenharmony_ci#endif 118370b324cSopenharmony_ci 119370b324cSopenharmony_ci// ----------------------------------------- 120370b324cSopenharmony_ci// this function compares name with mask 121370b324cSopenharmony_ci// ? - any char 122370b324cSopenharmony_ci// * - any char or empty 123370b324cSopenharmony_ci 124370b324cSopenharmony_cistatic bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) 125370b324cSopenharmony_ci{ 126370b324cSopenharmony_ci for (;;) 127370b324cSopenharmony_ci { 128370b324cSopenharmony_ci const wchar_t m = *mask; 129370b324cSopenharmony_ci const wchar_t c = *name; 130370b324cSopenharmony_ci if (m == 0) 131370b324cSopenharmony_ci return (c == 0); 132370b324cSopenharmony_ci if (m == '*') 133370b324cSopenharmony_ci { 134370b324cSopenharmony_ci if (EnhancedMaskTest(mask + 1, name)) 135370b324cSopenharmony_ci return true; 136370b324cSopenharmony_ci if (c == 0) 137370b324cSopenharmony_ci return false; 138370b324cSopenharmony_ci } 139370b324cSopenharmony_ci else 140370b324cSopenharmony_ci { 141370b324cSopenharmony_ci if (m == '?') 142370b324cSopenharmony_ci { 143370b324cSopenharmony_ci if (c == 0) 144370b324cSopenharmony_ci return false; 145370b324cSopenharmony_ci } 146370b324cSopenharmony_ci else if (m != c) 147370b324cSopenharmony_ci if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c)) 148370b324cSopenharmony_ci return false; 149370b324cSopenharmony_ci mask++; 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci name++; 152370b324cSopenharmony_ci } 153370b324cSopenharmony_ci} 154370b324cSopenharmony_ci 155370b324cSopenharmony_ci// -------------------------------------------------- 156370b324cSopenharmony_ci// Splits path to strings 157370b324cSopenharmony_ci 158370b324cSopenharmony_civoid SplitPathToParts(const UString &path, UStringVector &pathParts) 159370b324cSopenharmony_ci{ 160370b324cSopenharmony_ci pathParts.Clear(); 161370b324cSopenharmony_ci unsigned len = path.Len(); 162370b324cSopenharmony_ci if (len == 0) 163370b324cSopenharmony_ci return; 164370b324cSopenharmony_ci UString name; 165370b324cSopenharmony_ci unsigned prev = 0; 166370b324cSopenharmony_ci for (unsigned i = 0; i < len; i++) 167370b324cSopenharmony_ci if (IsPathSepar(path[i])) 168370b324cSopenharmony_ci { 169370b324cSopenharmony_ci name.SetFrom(path.Ptr(prev), i - prev); 170370b324cSopenharmony_ci pathParts.Add(name); 171370b324cSopenharmony_ci prev = i + 1; 172370b324cSopenharmony_ci } 173370b324cSopenharmony_ci name.SetFrom(path.Ptr(prev), len - prev); 174370b324cSopenharmony_ci pathParts.Add(name); 175370b324cSopenharmony_ci} 176370b324cSopenharmony_ci 177370b324cSopenharmony_civoid SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name) 178370b324cSopenharmony_ci{ 179370b324cSopenharmony_ci const wchar_t *start = path; 180370b324cSopenharmony_ci const wchar_t *p = start + path.Len(); 181370b324cSopenharmony_ci for (; p != start; p--) 182370b324cSopenharmony_ci if (IsPathSepar(*(p - 1))) 183370b324cSopenharmony_ci break; 184370b324cSopenharmony_ci dirPrefix.SetFrom(path, (unsigned)(p - start)); 185370b324cSopenharmony_ci name = p; 186370b324cSopenharmony_ci} 187370b324cSopenharmony_ci 188370b324cSopenharmony_civoid SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name) 189370b324cSopenharmony_ci{ 190370b324cSopenharmony_ci const wchar_t *start = path; 191370b324cSopenharmony_ci const wchar_t *p = start + path.Len(); 192370b324cSopenharmony_ci if (p != start) 193370b324cSopenharmony_ci { 194370b324cSopenharmony_ci if (IsPathSepar(*(p - 1))) 195370b324cSopenharmony_ci p--; 196370b324cSopenharmony_ci for (; p != start; p--) 197370b324cSopenharmony_ci if (IsPathSepar(*(p - 1))) 198370b324cSopenharmony_ci break; 199370b324cSopenharmony_ci } 200370b324cSopenharmony_ci dirPrefix.SetFrom(path, (unsigned)(p - start)); 201370b324cSopenharmony_ci name = p; 202370b324cSopenharmony_ci} 203370b324cSopenharmony_ci 204370b324cSopenharmony_ci/* 205370b324cSopenharmony_ciUString ExtractDirPrefixFromPath(const UString &path) 206370b324cSopenharmony_ci{ 207370b324cSopenharmony_ci return path.Left(path.ReverseFind_PathSepar() + 1)); 208370b324cSopenharmony_ci} 209370b324cSopenharmony_ci*/ 210370b324cSopenharmony_ci 211370b324cSopenharmony_ciUString ExtractFileNameFromPath(const UString &path) 212370b324cSopenharmony_ci{ 213370b324cSopenharmony_ci return UString(path.Ptr((unsigned)(path.ReverseFind_PathSepar() + 1))); 214370b324cSopenharmony_ci} 215370b324cSopenharmony_ci 216370b324cSopenharmony_ci 217370b324cSopenharmony_cibool DoesWildcardMatchName(const UString &mask, const UString &name) 218370b324cSopenharmony_ci{ 219370b324cSopenharmony_ci return EnhancedMaskTest(mask, name); 220370b324cSopenharmony_ci} 221370b324cSopenharmony_ci 222370b324cSopenharmony_cibool DoesNameContainWildcard(const UString &path) 223370b324cSopenharmony_ci{ 224370b324cSopenharmony_ci for (unsigned i = 0; i < path.Len(); i++) 225370b324cSopenharmony_ci { 226370b324cSopenharmony_ci wchar_t c = path[i]; 227370b324cSopenharmony_ci if (c == '*' || c == '?') 228370b324cSopenharmony_ci return true; 229370b324cSopenharmony_ci } 230370b324cSopenharmony_ci return false; 231370b324cSopenharmony_ci} 232370b324cSopenharmony_ci 233370b324cSopenharmony_ci 234370b324cSopenharmony_ci// ----------------------------------------------------------' 235370b324cSopenharmony_ci// NWildcard 236370b324cSopenharmony_ci 237370b324cSopenharmony_cinamespace NWildcard { 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci/* 240370b324cSopenharmony_ci 241370b324cSopenharmony_ciM = MaskParts.Size(); 242370b324cSopenharmony_ciN = TestNameParts.Size(); 243370b324cSopenharmony_ci 244370b324cSopenharmony_ci File Dir 245370b324cSopenharmony_ciForFile rec M<=N [N-M, N) - 246370b324cSopenharmony_ci!ForDir nonrec M=N [0, M) - 247370b324cSopenharmony_ci 248370b324cSopenharmony_ciForDir rec M<N [0, M) ... [N-M-1, N-1) same as ForBoth-File 249370b324cSopenharmony_ci!ForFile nonrec [0, M) same as ForBoth-File 250370b324cSopenharmony_ci 251370b324cSopenharmony_ciForFile rec m<=N [0, M) ... [N-M, N) same as ForBoth-File 252370b324cSopenharmony_ciForDir nonrec [0, M) same as ForBoth-File 253370b324cSopenharmony_ci 254370b324cSopenharmony_ci*/ 255370b324cSopenharmony_ci 256370b324cSopenharmony_cibool CItem::AreAllAllowed() const 257370b324cSopenharmony_ci{ 258370b324cSopenharmony_ci return ForFile && ForDir && WildcardMatching && PathParts.Size() == 1 && PathParts.Front() == L"*"; 259370b324cSopenharmony_ci} 260370b324cSopenharmony_ci 261370b324cSopenharmony_cibool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const 262370b324cSopenharmony_ci{ 263370b324cSopenharmony_ci if (!isFile && !ForDir) 264370b324cSopenharmony_ci return false; 265370b324cSopenharmony_ci 266370b324cSopenharmony_ci /* 267370b324cSopenharmony_ci if (PathParts.IsEmpty()) 268370b324cSopenharmony_ci { 269370b324cSopenharmony_ci // PathParts.IsEmpty() means all items (universal wildcard) 270370b324cSopenharmony_ci if (!isFile) 271370b324cSopenharmony_ci return true; 272370b324cSopenharmony_ci if (pathParts.Size() <= 1) 273370b324cSopenharmony_ci return ForFile; 274370b324cSopenharmony_ci return (ForDir || Recursive && ForFile); 275370b324cSopenharmony_ci } 276370b324cSopenharmony_ci */ 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci int delta = (int)pathParts.Size() - (int)PathParts.Size(); 279370b324cSopenharmony_ci if (delta < 0) 280370b324cSopenharmony_ci return false; 281370b324cSopenharmony_ci int start = 0; 282370b324cSopenharmony_ci int finish = 0; 283370b324cSopenharmony_ci 284370b324cSopenharmony_ci if (isFile) 285370b324cSopenharmony_ci { 286370b324cSopenharmony_ci if (!ForDir) 287370b324cSopenharmony_ci { 288370b324cSopenharmony_ci if (Recursive) 289370b324cSopenharmony_ci start = delta; 290370b324cSopenharmony_ci else if (delta !=0) 291370b324cSopenharmony_ci return false; 292370b324cSopenharmony_ci } 293370b324cSopenharmony_ci if (!ForFile && delta == 0) 294370b324cSopenharmony_ci return false; 295370b324cSopenharmony_ci } 296370b324cSopenharmony_ci 297370b324cSopenharmony_ci if (Recursive) 298370b324cSopenharmony_ci { 299370b324cSopenharmony_ci finish = delta; 300370b324cSopenharmony_ci if (isFile && !ForFile) 301370b324cSopenharmony_ci finish = delta - 1; 302370b324cSopenharmony_ci } 303370b324cSopenharmony_ci 304370b324cSopenharmony_ci for (int d = start; d <= finish; d++) 305370b324cSopenharmony_ci { 306370b324cSopenharmony_ci unsigned i; 307370b324cSopenharmony_ci for (i = 0; i < PathParts.Size(); i++) 308370b324cSopenharmony_ci { 309370b324cSopenharmony_ci if (WildcardMatching) 310370b324cSopenharmony_ci { 311370b324cSopenharmony_ci if (!DoesWildcardMatchName(PathParts[i], pathParts[i + (unsigned)d])) 312370b324cSopenharmony_ci break; 313370b324cSopenharmony_ci } 314370b324cSopenharmony_ci else 315370b324cSopenharmony_ci { 316370b324cSopenharmony_ci if (CompareFileNames(PathParts[i], pathParts[i + (unsigned)d]) != 0) 317370b324cSopenharmony_ci break; 318370b324cSopenharmony_ci } 319370b324cSopenharmony_ci } 320370b324cSopenharmony_ci if (i == PathParts.Size()) 321370b324cSopenharmony_ci return true; 322370b324cSopenharmony_ci } 323370b324cSopenharmony_ci return false; 324370b324cSopenharmony_ci} 325370b324cSopenharmony_ci 326370b324cSopenharmony_cibool CCensorNode::AreAllAllowed() const 327370b324cSopenharmony_ci{ 328370b324cSopenharmony_ci if (!Name.IsEmpty() || 329370b324cSopenharmony_ci !SubNodes.IsEmpty() || 330370b324cSopenharmony_ci !ExcludeItems.IsEmpty() || 331370b324cSopenharmony_ci IncludeItems.Size() != 1) 332370b324cSopenharmony_ci return false; 333370b324cSopenharmony_ci return IncludeItems.Front().AreAllAllowed(); 334370b324cSopenharmony_ci} 335370b324cSopenharmony_ci 336370b324cSopenharmony_ciint CCensorNode::FindSubNode(const UString &name) const 337370b324cSopenharmony_ci{ 338370b324cSopenharmony_ci FOR_VECTOR (i, SubNodes) 339370b324cSopenharmony_ci if (CompareFileNames(SubNodes[i].Name, name) == 0) 340370b324cSopenharmony_ci return (int)i; 341370b324cSopenharmony_ci return -1; 342370b324cSopenharmony_ci} 343370b324cSopenharmony_ci 344370b324cSopenharmony_civoid CCensorNode::AddItemSimple(bool include, CItem &item) 345370b324cSopenharmony_ci{ 346370b324cSopenharmony_ci CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems; 347370b324cSopenharmony_ci items.Add(item); 348370b324cSopenharmony_ci} 349370b324cSopenharmony_ci 350370b324cSopenharmony_civoid CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex) 351370b324cSopenharmony_ci{ 352370b324cSopenharmony_ci if (item.PathParts.Size() <= 1) 353370b324cSopenharmony_ci { 354370b324cSopenharmony_ci if (item.PathParts.Size() != 0 && item.WildcardMatching) 355370b324cSopenharmony_ci { 356370b324cSopenharmony_ci if (!DoesNameContainWildcard(item.PathParts.Front())) 357370b324cSopenharmony_ci item.WildcardMatching = false; 358370b324cSopenharmony_ci } 359370b324cSopenharmony_ci AddItemSimple(include, item); 360370b324cSopenharmony_ci return; 361370b324cSopenharmony_ci } 362370b324cSopenharmony_ci 363370b324cSopenharmony_ci const UString &front = item.PathParts.Front(); 364370b324cSopenharmony_ci 365370b324cSopenharmony_ci // WIN32 doesn't support wildcards in file names 366370b324cSopenharmony_ci if (item.WildcardMatching 367370b324cSopenharmony_ci && ignoreWildcardIndex != 0 368370b324cSopenharmony_ci && DoesNameContainWildcard(front)) 369370b324cSopenharmony_ci { 370370b324cSopenharmony_ci AddItemSimple(include, item); 371370b324cSopenharmony_ci return; 372370b324cSopenharmony_ci } 373370b324cSopenharmony_ci CCensorNode &subNode = Find_SubNode_Or_Add_New(front); 374370b324cSopenharmony_ci item.PathParts.Delete(0); 375370b324cSopenharmony_ci subNode.AddItem(include, item, ignoreWildcardIndex - 1); 376370b324cSopenharmony_ci} 377370b324cSopenharmony_ci 378370b324cSopenharmony_ci/* 379370b324cSopenharmony_civoid CCensorNode::AddItem(bool include, const UString &path, const CCensorPathProps &props) 380370b324cSopenharmony_ci{ 381370b324cSopenharmony_ci CItem item; 382370b324cSopenharmony_ci SplitPathToParts(path, item.PathParts); 383370b324cSopenharmony_ci item.Recursive = props.Recursive; 384370b324cSopenharmony_ci item.ForFile = props.ForFile; 385370b324cSopenharmony_ci item.ForDir = props.ForDir; 386370b324cSopenharmony_ci item.WildcardMatching = props.WildcardMatching; 387370b324cSopenharmony_ci AddItem(include, item); 388370b324cSopenharmony_ci} 389370b324cSopenharmony_ci*/ 390370b324cSopenharmony_ci 391370b324cSopenharmony_cibool CCensorNode::NeedCheckSubDirs() const 392370b324cSopenharmony_ci{ 393370b324cSopenharmony_ci FOR_VECTOR (i, IncludeItems) 394370b324cSopenharmony_ci { 395370b324cSopenharmony_ci const CItem &item = IncludeItems[i]; 396370b324cSopenharmony_ci if (item.Recursive || item.PathParts.Size() > 1) 397370b324cSopenharmony_ci return true; 398370b324cSopenharmony_ci } 399370b324cSopenharmony_ci return false; 400370b324cSopenharmony_ci} 401370b324cSopenharmony_ci 402370b324cSopenharmony_cibool CCensorNode::AreThereIncludeItems() const 403370b324cSopenharmony_ci{ 404370b324cSopenharmony_ci if (IncludeItems.Size() > 0) 405370b324cSopenharmony_ci return true; 406370b324cSopenharmony_ci FOR_VECTOR (i, SubNodes) 407370b324cSopenharmony_ci if (SubNodes[i].AreThereIncludeItems()) 408370b324cSopenharmony_ci return true; 409370b324cSopenharmony_ci return false; 410370b324cSopenharmony_ci} 411370b324cSopenharmony_ci 412370b324cSopenharmony_cibool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const 413370b324cSopenharmony_ci{ 414370b324cSopenharmony_ci const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems; 415370b324cSopenharmony_ci FOR_VECTOR (i, items) 416370b324cSopenharmony_ci if (items[i].CheckPath(pathParts, isFile)) 417370b324cSopenharmony_ci return true; 418370b324cSopenharmony_ci return false; 419370b324cSopenharmony_ci} 420370b324cSopenharmony_ci 421370b324cSopenharmony_cibool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const 422370b324cSopenharmony_ci{ 423370b324cSopenharmony_ci if (CheckPathCurrent(false, pathParts, isFile)) 424370b324cSopenharmony_ci { 425370b324cSopenharmony_ci include = false; 426370b324cSopenharmony_ci return true; 427370b324cSopenharmony_ci } 428370b324cSopenharmony_ci if (pathParts.Size() > 1) 429370b324cSopenharmony_ci { 430370b324cSopenharmony_ci int index = FindSubNode(pathParts.Front()); 431370b324cSopenharmony_ci if (index >= 0) 432370b324cSopenharmony_ci { 433370b324cSopenharmony_ci UStringVector pathParts2 = pathParts; 434370b324cSopenharmony_ci pathParts2.Delete(0); 435370b324cSopenharmony_ci if (SubNodes[(unsigned)index].CheckPathVect(pathParts2, isFile, include)) 436370b324cSopenharmony_ci return true; 437370b324cSopenharmony_ci } 438370b324cSopenharmony_ci } 439370b324cSopenharmony_ci bool finded = CheckPathCurrent(true, pathParts, isFile); 440370b324cSopenharmony_ci include = finded; // if (!finded), then (true) is allowed also 441370b324cSopenharmony_ci return finded; 442370b324cSopenharmony_ci} 443370b324cSopenharmony_ci 444370b324cSopenharmony_ci/* 445370b324cSopenharmony_cibool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const 446370b324cSopenharmony_ci{ 447370b324cSopenharmony_ci UStringVector pathParts; 448370b324cSopenharmony_ci SplitPathToParts(path, pathParts); 449370b324cSopenharmony_ci if (CheckPathVect(pathParts, isFile, include)) 450370b324cSopenharmony_ci { 451370b324cSopenharmony_ci if (!include || !isAltStream) 452370b324cSopenharmony_ci return true; 453370b324cSopenharmony_ci } 454370b324cSopenharmony_ci if (isAltStream && !pathParts.IsEmpty()) 455370b324cSopenharmony_ci { 456370b324cSopenharmony_ci UString &back = pathParts.Back(); 457370b324cSopenharmony_ci int pos = back.Find(L':'); 458370b324cSopenharmony_ci if (pos > 0) 459370b324cSopenharmony_ci { 460370b324cSopenharmony_ci back.DeleteFrom(pos); 461370b324cSopenharmony_ci return CheckPathVect(pathParts, isFile, include); 462370b324cSopenharmony_ci } 463370b324cSopenharmony_ci } 464370b324cSopenharmony_ci return false; 465370b324cSopenharmony_ci} 466370b324cSopenharmony_ci 467370b324cSopenharmony_cibool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const 468370b324cSopenharmony_ci{ 469370b324cSopenharmony_ci bool include; 470370b324cSopenharmony_ci if (CheckPath2(isAltStream, path, isFile, include)) 471370b324cSopenharmony_ci return include; 472370b324cSopenharmony_ci return false; 473370b324cSopenharmony_ci} 474370b324cSopenharmony_ci*/ 475370b324cSopenharmony_ci 476370b324cSopenharmony_cibool CCensorNode::CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const 477370b324cSopenharmony_ci{ 478370b324cSopenharmony_ci if (CheckPathCurrent(include, pathParts, isFile)) 479370b324cSopenharmony_ci return true; 480370b324cSopenharmony_ci if (!Parent) 481370b324cSopenharmony_ci return false; 482370b324cSopenharmony_ci pathParts.Insert(0, Name); 483370b324cSopenharmony_ci return Parent->CheckPathToRoot_Change(include, pathParts, isFile); 484370b324cSopenharmony_ci} 485370b324cSopenharmony_ci 486370b324cSopenharmony_cibool CCensorNode::CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const 487370b324cSopenharmony_ci{ 488370b324cSopenharmony_ci if (CheckPathCurrent(include, pathParts, isFile)) 489370b324cSopenharmony_ci return true; 490370b324cSopenharmony_ci if (!Parent) 491370b324cSopenharmony_ci return false; 492370b324cSopenharmony_ci UStringVector pathParts2; 493370b324cSopenharmony_ci pathParts2.Add(Name); 494370b324cSopenharmony_ci pathParts2 += pathParts; 495370b324cSopenharmony_ci return Parent->CheckPathToRoot_Change(include, pathParts2, isFile); 496370b324cSopenharmony_ci} 497370b324cSopenharmony_ci 498370b324cSopenharmony_ci/* 499370b324cSopenharmony_cibool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const 500370b324cSopenharmony_ci{ 501370b324cSopenharmony_ci UStringVector pathParts; 502370b324cSopenharmony_ci SplitPathToParts(path, pathParts); 503370b324cSopenharmony_ci return CheckPathToRoot(include, pathParts, isFile); 504370b324cSopenharmony_ci} 505370b324cSopenharmony_ci*/ 506370b324cSopenharmony_ci 507370b324cSopenharmony_civoid CCensorNode::ExtendExclude(const CCensorNode &fromNodes) 508370b324cSopenharmony_ci{ 509370b324cSopenharmony_ci ExcludeItems += fromNodes.ExcludeItems; 510370b324cSopenharmony_ci FOR_VECTOR (i, fromNodes.SubNodes) 511370b324cSopenharmony_ci { 512370b324cSopenharmony_ci const CCensorNode &node = fromNodes.SubNodes[i]; 513370b324cSopenharmony_ci Find_SubNode_Or_Add_New(node.Name).ExtendExclude(node); 514370b324cSopenharmony_ci } 515370b324cSopenharmony_ci} 516370b324cSopenharmony_ci 517370b324cSopenharmony_ciint CCensor::FindPairForPrefix(const UString &prefix) const 518370b324cSopenharmony_ci{ 519370b324cSopenharmony_ci FOR_VECTOR (i, Pairs) 520370b324cSopenharmony_ci if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) 521370b324cSopenharmony_ci return (int)i; 522370b324cSopenharmony_ci return -1; 523370b324cSopenharmony_ci} 524370b324cSopenharmony_ci 525370b324cSopenharmony_ci#ifdef _WIN32 526370b324cSopenharmony_ci 527370b324cSopenharmony_cibool IsDriveColonName(const wchar_t *s) 528370b324cSopenharmony_ci{ 529370b324cSopenharmony_ci unsigned c = s[0]; 530370b324cSopenharmony_ci c |= 0x20; 531370b324cSopenharmony_ci c -= 'a'; 532370b324cSopenharmony_ci return c <= (unsigned)('z' - 'a') && s[1] == ':' && s[2] == 0; 533370b324cSopenharmony_ci} 534370b324cSopenharmony_ci 535370b324cSopenharmony_ciunsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts) 536370b324cSopenharmony_ci{ 537370b324cSopenharmony_ci if (pathParts.IsEmpty()) 538370b324cSopenharmony_ci return 0; 539370b324cSopenharmony_ci 540370b324cSopenharmony_ci unsigned testIndex = 0; 541370b324cSopenharmony_ci if (pathParts[0].IsEmpty()) 542370b324cSopenharmony_ci { 543370b324cSopenharmony_ci if (pathParts.Size() < 4 544370b324cSopenharmony_ci || !pathParts[1].IsEmpty() 545370b324cSopenharmony_ci || pathParts[2] != L"?") 546370b324cSopenharmony_ci return 0; 547370b324cSopenharmony_ci testIndex = 3; 548370b324cSopenharmony_ci } 549370b324cSopenharmony_ci if (NWildcard::IsDriveColonName(pathParts[testIndex])) 550370b324cSopenharmony_ci return testIndex + 1; 551370b324cSopenharmony_ci return 0; 552370b324cSopenharmony_ci} 553370b324cSopenharmony_ci 554370b324cSopenharmony_ci#endif 555370b324cSopenharmony_ci 556370b324cSopenharmony_cistatic unsigned GetNumPrefixParts(const UStringVector &pathParts) 557370b324cSopenharmony_ci{ 558370b324cSopenharmony_ci if (pathParts.IsEmpty()) 559370b324cSopenharmony_ci return 0; 560370b324cSopenharmony_ci 561370b324cSopenharmony_ci /* empty last part could be removed already from (pathParts), 562370b324cSopenharmony_ci if there was tail path separator (slash) in original full path string. */ 563370b324cSopenharmony_ci 564370b324cSopenharmony_ci #ifdef _WIN32 565370b324cSopenharmony_ci 566370b324cSopenharmony_ci if (IsDriveColonName(pathParts[0])) 567370b324cSopenharmony_ci return 1; 568370b324cSopenharmony_ci if (!pathParts[0].IsEmpty()) 569370b324cSopenharmony_ci return 0; 570370b324cSopenharmony_ci 571370b324cSopenharmony_ci if (pathParts.Size() == 1) 572370b324cSopenharmony_ci return 1; 573370b324cSopenharmony_ci if (!pathParts[1].IsEmpty()) 574370b324cSopenharmony_ci return 1; 575370b324cSopenharmony_ci if (pathParts.Size() == 2) 576370b324cSopenharmony_ci return 2; 577370b324cSopenharmony_ci if (pathParts[2] == L".") 578370b324cSopenharmony_ci return 3; 579370b324cSopenharmony_ci 580370b324cSopenharmony_ci unsigned networkParts = 2; 581370b324cSopenharmony_ci if (pathParts[2] == L"?") 582370b324cSopenharmony_ci { 583370b324cSopenharmony_ci if (pathParts.Size() == 3) 584370b324cSopenharmony_ci return 3; 585370b324cSopenharmony_ci if (IsDriveColonName(pathParts[3])) 586370b324cSopenharmony_ci return 4; 587370b324cSopenharmony_ci if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC")) 588370b324cSopenharmony_ci return 3; 589370b324cSopenharmony_ci networkParts = 4; 590370b324cSopenharmony_ci } 591370b324cSopenharmony_ci 592370b324cSopenharmony_ci networkParts += 593370b324cSopenharmony_ci // 2; // server/share 594370b324cSopenharmony_ci 1; // server 595370b324cSopenharmony_ci if (pathParts.Size() <= networkParts) 596370b324cSopenharmony_ci return pathParts.Size(); 597370b324cSopenharmony_ci return networkParts; 598370b324cSopenharmony_ci 599370b324cSopenharmony_ci #else 600370b324cSopenharmony_ci 601370b324cSopenharmony_ci return pathParts[0].IsEmpty() ? 1 : 0; 602370b324cSopenharmony_ci 603370b324cSopenharmony_ci #endif 604370b324cSopenharmony_ci} 605370b324cSopenharmony_ci 606370b324cSopenharmony_civoid CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, 607370b324cSopenharmony_ci const CCensorPathProps &props) 608370b324cSopenharmony_ci{ 609370b324cSopenharmony_ci if (path.IsEmpty()) 610370b324cSopenharmony_ci throw "Empty file path"; 611370b324cSopenharmony_ci 612370b324cSopenharmony_ci UStringVector pathParts; 613370b324cSopenharmony_ci SplitPathToParts(path, pathParts); 614370b324cSopenharmony_ci 615370b324cSopenharmony_ci CCensorPathProps props2 = props; 616370b324cSopenharmony_ci 617370b324cSopenharmony_ci bool forFile = true; 618370b324cSopenharmony_ci bool forDir = true; 619370b324cSopenharmony_ci const UString &back = pathParts.Back(); 620370b324cSopenharmony_ci if (back.IsEmpty()) 621370b324cSopenharmony_ci { 622370b324cSopenharmony_ci // we have tail path separator. So it's directory. 623370b324cSopenharmony_ci // we delete tail path separator here even for "\" and "c:\" 624370b324cSopenharmony_ci forFile = false; 625370b324cSopenharmony_ci pathParts.DeleteBack(); 626370b324cSopenharmony_ci } 627370b324cSopenharmony_ci else 628370b324cSopenharmony_ci { 629370b324cSopenharmony_ci if (props.MarkMode == kMark_StrictFile 630370b324cSopenharmony_ci || (props.MarkMode == kMark_StrictFile_IfWildcard 631370b324cSopenharmony_ci && DoesNameContainWildcard(back))) 632370b324cSopenharmony_ci forDir = false; 633370b324cSopenharmony_ci } 634370b324cSopenharmony_ci 635370b324cSopenharmony_ci 636370b324cSopenharmony_ci UString prefix; 637370b324cSopenharmony_ci 638370b324cSopenharmony_ci int ignoreWildcardIndex = -1; 639370b324cSopenharmony_ci 640370b324cSopenharmony_ci // #ifdef _WIN32 641370b324cSopenharmony_ci // we ignore "?" wildcard in "\\?\" prefix. 642370b324cSopenharmony_ci if (pathParts.Size() >= 3 643370b324cSopenharmony_ci && pathParts[0].IsEmpty() 644370b324cSopenharmony_ci && pathParts[1].IsEmpty() 645370b324cSopenharmony_ci && pathParts[2] == L"?") 646370b324cSopenharmony_ci ignoreWildcardIndex = 2; 647370b324cSopenharmony_ci // #endif 648370b324cSopenharmony_ci 649370b324cSopenharmony_ci if (pathMode != k_AbsPath) 650370b324cSopenharmony_ci { 651370b324cSopenharmony_ci // detection of the number of Skip Parts for prefix 652370b324cSopenharmony_ci ignoreWildcardIndex = -1; 653370b324cSopenharmony_ci 654370b324cSopenharmony_ci const unsigned numPrefixParts = GetNumPrefixParts(pathParts); 655370b324cSopenharmony_ci unsigned numSkipParts = numPrefixParts; 656370b324cSopenharmony_ci 657370b324cSopenharmony_ci if (pathMode != k_FullPath) 658370b324cSopenharmony_ci { 659370b324cSopenharmony_ci // if absolute path, then all parts before last part will be in prefix 660370b324cSopenharmony_ci if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts) 661370b324cSopenharmony_ci numSkipParts = pathParts.Size() - 1; 662370b324cSopenharmony_ci } 663370b324cSopenharmony_ci { 664370b324cSopenharmony_ci int dotsIndex = -1; 665370b324cSopenharmony_ci for (unsigned i = numPrefixParts; i < pathParts.Size(); i++) 666370b324cSopenharmony_ci { 667370b324cSopenharmony_ci const UString &part = pathParts[i]; 668370b324cSopenharmony_ci if (part == L".." || part == L".") 669370b324cSopenharmony_ci dotsIndex = (int)i; 670370b324cSopenharmony_ci } 671370b324cSopenharmony_ci 672370b324cSopenharmony_ci if (dotsIndex >= 0) 673370b324cSopenharmony_ci { 674370b324cSopenharmony_ci if (dotsIndex == (int)pathParts.Size() - 1) 675370b324cSopenharmony_ci numSkipParts = pathParts.Size(); 676370b324cSopenharmony_ci else 677370b324cSopenharmony_ci numSkipParts = pathParts.Size() - 1; 678370b324cSopenharmony_ci } 679370b324cSopenharmony_ci } 680370b324cSopenharmony_ci 681370b324cSopenharmony_ci // we split (pathParts) to (prefix) and (pathParts). 682370b324cSopenharmony_ci for (unsigned i = 0; i < numSkipParts; i++) 683370b324cSopenharmony_ci { 684370b324cSopenharmony_ci { 685370b324cSopenharmony_ci const UString &front = pathParts.Front(); 686370b324cSopenharmony_ci // WIN32 doesn't support wildcards in file names 687370b324cSopenharmony_ci if (props.WildcardMatching) 688370b324cSopenharmony_ci if (i >= numPrefixParts && DoesNameContainWildcard(front)) 689370b324cSopenharmony_ci break; 690370b324cSopenharmony_ci prefix += front; 691370b324cSopenharmony_ci prefix.Add_PathSepar(); 692370b324cSopenharmony_ci } 693370b324cSopenharmony_ci pathParts.Delete(0); 694370b324cSopenharmony_ci } 695370b324cSopenharmony_ci } 696370b324cSopenharmony_ci 697370b324cSopenharmony_ci int index = FindPairForPrefix(prefix); 698370b324cSopenharmony_ci if (index < 0) 699370b324cSopenharmony_ci { 700370b324cSopenharmony_ci index = (int)Pairs.Size(); 701370b324cSopenharmony_ci Pairs.AddNew().Prefix = prefix; 702370b324cSopenharmony_ci } 703370b324cSopenharmony_ci 704370b324cSopenharmony_ci if (pathMode != k_AbsPath) 705370b324cSopenharmony_ci { 706370b324cSopenharmony_ci if (pathParts.IsEmpty() || (pathParts.Size() == 1 && pathParts[0].IsEmpty())) 707370b324cSopenharmony_ci { 708370b324cSopenharmony_ci // we create universal item, if we skip all parts as prefix (like \ or L:\ ) 709370b324cSopenharmony_ci pathParts.Clear(); 710370b324cSopenharmony_ci pathParts.Add(UString("*")); 711370b324cSopenharmony_ci forFile = true; 712370b324cSopenharmony_ci forDir = true; 713370b324cSopenharmony_ci props2.WildcardMatching = true; 714370b324cSopenharmony_ci props2.Recursive = false; 715370b324cSopenharmony_ci } 716370b324cSopenharmony_ci } 717370b324cSopenharmony_ci 718370b324cSopenharmony_ci /* 719370b324cSopenharmony_ci // not possible now 720370b324cSopenharmony_ci if (!forDir && !forFile) 721370b324cSopenharmony_ci { 722370b324cSopenharmony_ci UString s ("file path was blocked for files and directories: "); 723370b324cSopenharmony_ci s += path; 724370b324cSopenharmony_ci throw s; 725370b324cSopenharmony_ci // return; // for debug : ignore item (don't create Item) 726370b324cSopenharmony_ci } 727370b324cSopenharmony_ci */ 728370b324cSopenharmony_ci 729370b324cSopenharmony_ci CItem item; 730370b324cSopenharmony_ci item.PathParts = pathParts; 731370b324cSopenharmony_ci item.ForDir = forDir; 732370b324cSopenharmony_ci item.ForFile = forFile; 733370b324cSopenharmony_ci item.Recursive = props2.Recursive; 734370b324cSopenharmony_ci item.WildcardMatching = props2.WildcardMatching; 735370b324cSopenharmony_ci Pairs[(unsigned)index].Head.AddItem(include, item, ignoreWildcardIndex); 736370b324cSopenharmony_ci} 737370b324cSopenharmony_ci 738370b324cSopenharmony_ci/* 739370b324cSopenharmony_cibool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const 740370b324cSopenharmony_ci{ 741370b324cSopenharmony_ci bool finded = false; 742370b324cSopenharmony_ci FOR_VECTOR (i, Pairs) 743370b324cSopenharmony_ci { 744370b324cSopenharmony_ci bool include; 745370b324cSopenharmony_ci if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include)) 746370b324cSopenharmony_ci { 747370b324cSopenharmony_ci if (!include) 748370b324cSopenharmony_ci return false; 749370b324cSopenharmony_ci finded = true; 750370b324cSopenharmony_ci } 751370b324cSopenharmony_ci } 752370b324cSopenharmony_ci return finded; 753370b324cSopenharmony_ci} 754370b324cSopenharmony_ci*/ 755370b324cSopenharmony_ci 756370b324cSopenharmony_civoid CCensor::ExtendExclude() 757370b324cSopenharmony_ci{ 758370b324cSopenharmony_ci unsigned i; 759370b324cSopenharmony_ci for (i = 0; i < Pairs.Size(); i++) 760370b324cSopenharmony_ci if (Pairs[i].Prefix.IsEmpty()) 761370b324cSopenharmony_ci break; 762370b324cSopenharmony_ci if (i == Pairs.Size()) 763370b324cSopenharmony_ci return; 764370b324cSopenharmony_ci unsigned index = i; 765370b324cSopenharmony_ci for (i = 0; i < Pairs.Size(); i++) 766370b324cSopenharmony_ci if (index != i) 767370b324cSopenharmony_ci Pairs[i].Head.ExtendExclude(Pairs[index].Head); 768370b324cSopenharmony_ci} 769370b324cSopenharmony_ci 770370b324cSopenharmony_civoid CCensor::AddPathsToCensor(ECensorPathMode censorPathMode) 771370b324cSopenharmony_ci{ 772370b324cSopenharmony_ci FOR_VECTOR(i, CensorPaths) 773370b324cSopenharmony_ci { 774370b324cSopenharmony_ci const CCensorPath &cp = CensorPaths[i]; 775370b324cSopenharmony_ci AddItem(censorPathMode, cp.Include, cp.Path, cp.Props); 776370b324cSopenharmony_ci } 777370b324cSopenharmony_ci CensorPaths.Clear(); 778370b324cSopenharmony_ci} 779370b324cSopenharmony_ci 780370b324cSopenharmony_civoid CCensor::AddPreItem(bool include, const UString &path, const CCensorPathProps &props) 781370b324cSopenharmony_ci{ 782370b324cSopenharmony_ci CCensorPath &cp = CensorPaths.AddNew(); 783370b324cSopenharmony_ci cp.Path = path; 784370b324cSopenharmony_ci cp.Include = include; 785370b324cSopenharmony_ci cp.Props = props; 786370b324cSopenharmony_ci} 787370b324cSopenharmony_ci 788370b324cSopenharmony_ci} 789