Skip to content

Commit 1ebe02c

Browse files
committed
Fix Bug #3122: Fix 'sync_list' globbing rule application
* Add check for 'globbing' and 'wildcard' rules, that the number of segments before the first wildcard character need to match before the actual rule can be applied
1 parent 1166f86 commit 1ebe02c

File tree

1 file changed

+72
-41
lines changed

1 file changed

+72
-41
lines changed

src/clientSideFiltering.d

+72-41
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ class ClientSideFiltering {
371371
if (matchRuleSegmentsToPathSegments(syncListRuleEntry, path)) {
372372
// PARENTAL PATH MATCH
373373
if (debugLogging) {addLogEntry("Parental path match with 'sync_list' rule entry", ["debug"]);}
374-
374+
// What sort of rule was this?
375375
if (!thisIsAnExcludeRule) {
376376
// Include Rule
377377
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: parental path match", ["debug"]);}
@@ -481,63 +481,81 @@ class ClientSideFiltering {
481481
}
482482

483483
// Does the 'sync_list' rule contain a wildcard (*) or globbing (**) reference anywhere in the rule?
484+
// EXCLUSION
485+
// !/Programming/Projects/Android/**/build/*
484486
if (canFind(syncListRuleEntry, wildcard)) {
485487
// reset the applicable flag
486488
wildcardRuleMatched = false;
487-
488-
// sync_list rule contains some sort of wildcard sequence
489-
if (thisIsAnExcludeRule) {
490-
if (debugLogging) {addLogEntry("wildcard (* or **) exclusion rule: !" ~ syncListRuleEntry, ["debug"]);}
491-
} else {
492-
if (debugLogging) {addLogEntry("wildcard (* or **) inclusion rule: " ~ syncListRuleEntry, ["debug"]);}
489+
490+
// Does this 'wildcard' rule even apply to this path?
491+
auto wildcardDepth = firstWildcardDepth(syncListRuleEntry);
492+
auto pathSegments = count(pathSplitter(path));
493+
494+
// If the input path starts with a '/' the path segment count needs to be reduced by 1, as pathSplitter adds this as the first array element
495+
if (to!string(path[0]) == "/") {
496+
pathSegments = pathSegments - 1;
493497
}
494498

495-
// Is this a globbing rule (**) or just a single wildcard (*) entries
496-
if (canFind(syncListRuleEntry, globbing)) {
497-
// globbing (**) rule processing
498-
if (matchPathAgainstRule(path, syncListRuleEntry)) {
499-
// set the applicable flag
500-
wildcardRuleMatched = true;
501-
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: globbing pattern match", ["debug"]);}
502-
}
499+
// are there enough path segments for this wildcard rule to apply?
500+
if (pathSegments < wildcardDepth) {
501+
// there are not enough path segments up to the first wildcard character for this rule to even be applicable
502+
if (debugLogging) {addLogEntry("- This sync list wildcard rule should not be evaluated as the wildcard appears beyond the current input path", ["debug"]);}
503503
} else {
504-
// wildcard (*) rule processing
505-
// create regex from 'syncListRuleEntry'
506-
auto allowedMask = regex(createRegexCompatiblePath(syncListRuleEntry));
507-
if (matchAll(path, allowedMask)) {
508-
// set the applicable flag
509-
wildcardRuleMatched = true;
510-
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard pattern match", ["debug"]);}
504+
// path segments are enough for this wildcard rule to potentially apply
505+
// sync_list rule contains some sort of wildcard sequence
506+
if (thisIsAnExcludeRule) {
507+
if (debugLogging) {addLogEntry("wildcard (* or **) exclusion rule: !" ~ syncListRuleEntry, ["debug"]);}
511508
} else {
512-
// matchAll no match ... try another way just to be sure
509+
if (debugLogging) {addLogEntry("wildcard (* or **) inclusion rule: " ~ syncListRuleEntry, ["debug"]);}
510+
}
511+
512+
// Is this a globbing rule (**) or just a single wildcard (*) entries
513+
if (canFind(syncListRuleEntry, globbing)) {
514+
// globbing (**) rule processing
513515
if (matchPathAgainstRule(path, syncListRuleEntry)) {
514516
// set the applicable flag
515517
wildcardRuleMatched = true;
516-
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard pattern match using segment matching", ["debug"]);}
518+
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: globbing pattern match using segment matching", ["debug"]);}
517519
}
518-
}
519-
}
520-
521-
// Was the rule matched?
522-
if (wildcardRuleMatched) {
523-
// Is this an exclude rule?
524-
if (thisIsAnExcludeRule) {
525-
// Yes exclude rule
526-
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard|globbing rule matched and must be excluded", ["debug"]);}
527-
excludeWildcardMatched = true;
528-
exclude = true;
529-
finalResult = true;
530520
} else {
531-
// include rule
532-
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard|globbing pattern matched and must be included", ["debug"]);}
533-
finalResult = false;
534-
excludeWildcardMatched = false;
521+
// wildcard (*) rule processing
522+
// create regex from 'syncListRuleEntry'
523+
auto allowedMask = regex(createRegexCompatiblePath(syncListRuleEntry));
524+
if (matchAll(path, allowedMask)) {
525+
// set the applicable flag
526+
wildcardRuleMatched = true;
527+
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard pattern match", ["debug"]);}
528+
} else {
529+
// matchAll no match ... try another way just to be sure
530+
if (matchPathAgainstRule(path, syncListRuleEntry)) {
531+
// set the applicable flag
532+
wildcardRuleMatched = true;
533+
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard pattern match using segment matching", ["debug"]);}
534+
}
535+
}
536+
}
537+
538+
// Was the rule matched?
539+
if (wildcardRuleMatched) {
540+
// Is this an exclude rule?
541+
if (thisIsAnExcludeRule) {
542+
// Yes exclude rule
543+
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard|globbing rule matched and must be excluded", ["debug"]);}
544+
excludeWildcardMatched = true;
545+
exclude = true;
546+
finalResult = true;
547+
} else {
548+
// include rule
549+
if (debugLogging) {addLogEntry("Evaluation against 'sync_list' rule result: wildcard|globbing pattern matched and must be included", ["debug"]);}
550+
finalResult = false;
551+
excludeWildcardMatched = false;
552+
}
535553
}
536554
}
537555
}
538556
}
539557

540-
558+
// debug logging post 'sync_list' rule evaluations
541559
if (debugLogging) {
542560
// Rule evaluation complete
543561
addLogEntry("------------------------------------------------------------------------", ["debug"]);
@@ -564,6 +582,19 @@ class ClientSideFiltering {
564582
return finalResult;
565583
}
566584

585+
// Calculate wildcard character depth in path
586+
int firstWildcardDepth(string syncListRuleEntry)
587+
{
588+
int depth = 0;
589+
foreach (segment; pathSplitter(syncListRuleEntry))
590+
{
591+
if (segment.canFind("*")) // Check for wildcard characters
592+
return depth;
593+
depth++;
594+
}
595+
return depth; // No wildcard found should be '0'
596+
}
597+
567598
// Create a wildcard regex compatible string based on the sync list rule
568599
string createRegexCompatiblePath(string regexCompatiblePath) {
569600
regexCompatiblePath = regexCompatiblePath.replace(".", "\\."); // Escape the dot (.) if present

0 commit comments

Comments
 (0)