| OLD | NEW |
| 1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
| 2 | 2 |
| 3 #include "PluginFilter.h" | 3 #include "PluginFilter.h" |
| 4 | 4 |
| 5 #if (defined PRODUCT_ADBLOCKPLUS) | 5 #if (defined PRODUCT_ADBLOCKPLUS) |
| 6 #include "PluginSettings.h" | 6 #include "PluginSettings.h" |
| 7 #include "PluginClient.h" | 7 #include "PluginClient.h" |
| 8 #include "PluginClientFactory.h" | 8 #include "PluginClientFactory.h" |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 m_contentMapText[CFilter::contentTypeUnknown] = "?"; | 160 m_contentMapText[CFilter::contentTypeUnknown] = "?"; |
| 161 m_contentMapText[CFilter::contentTypeSubdocument] = "iframe"; | 161 m_contentMapText[CFilter::contentTypeSubdocument] = "iframe"; |
| 162 m_contentMapText[CFilter::contentTypeStyleSheet] = "css"; | 162 m_contentMapText[CFilter::contentTypeStyleSheet] = "css"; |
| 163 | 163 |
| 164 ClearFilters(); | 164 ClearFilters(); |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 bool CPluginFilter::AddFilterElementHide(CString filterText) | 168 bool CPluginFilter::AddFilterElementHide(CString filterText) |
| 169 { | 169 { |
| 170 int delimiterPos = filterText.Find(L"#"); | 170 |
| 171 if (delimiterPos < 0 || filterText.GetLength() <= delimiterPos + 1) | |
| 172 { | |
| 173 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterText
+ " (no tag)") | |
| 174 return false; | |
| 175 } | |
| 176 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 171 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); |
| 177 bool isOldFormat = true; | |
| 178 if (filterText.GetAt(delimiterPos + 1) == '#') | |
| 179 { | |
| 180 isOldFormat = false; | |
| 181 } | |
| 182 | 172 |
| 183 s_criticalSectionFilterMap.Lock(); | 173 s_criticalSectionFilterMap.Lock(); |
| 184 { | 174 { |
| 185 // Create filter descriptor | 175 // Create filter descriptor |
| 186 CFilterElementHide filter(filterText); | 176 CFilterElementHide filter(filterText); |
| 187 | 177 |
| 188 CString filterDomains = filterText.Left(delimiterPos).MakeLower(); | 178 CString filterString = filterText; |
| 189 CString filterString = filterText.Right(filterText.GetLength() - delimiterP
os - (isOldFormat ? 1 : 2)); | |
| 190 | |
| 191 bool isDomainSpecific = delimiterPos > 0 && filterDomains.Find('~') < 0; | |
| 192 | |
| 193 // Add not-domains to filter | |
| 194 if (!isDomainSpecific && delimiterPos > 0) | |
| 195 { | |
| 196 int endPos = 0; | |
| 197 | |
| 198 while ((endPos = filterDomains.Find(',')) >= 0 || !filterDomains.IsEmpty()
) | |
| 199 { | |
| 200 CString domain; | |
| 201 | |
| 202 if (endPos == -1) | |
| 203 { | |
| 204 domain = filterDomains; | |
| 205 | |
| 206 filterDomains.Empty(); | |
| 207 } | |
| 208 else | |
| 209 { | |
| 210 domain = filterDomains.Left(endPos); | |
| 211 | |
| 212 filterDomains = filterDomains.Right(filterDomains.GetLength() - endPos
- 1); | |
| 213 } | |
| 214 | |
| 215 if (domain.GetAt(0) == '~') | |
| 216 { | |
| 217 domain = domain.Right(domain.GetLength() - 1); | |
| 218 } | |
| 219 // Error | |
| 220 else | |
| 221 { | |
| 222 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filt
erText + " (conflicting domains)") | |
| 223 s_criticalSectionFilterMap.Unlock(); | |
| 224 return false; | |
| 225 } | |
| 226 | |
| 227 filter.m_domainsNot.insert(domain); | |
| 228 } | |
| 229 } | |
| 230 | 179 |
| 231 // Find tag name, class or any (*) | 180 // Find tag name, class or any (*) |
| 232 CString tag; | 181 CString tag; |
| 233 | 182 |
| 234 TCHAR firstTag = filterString.GetAt(0); | 183 TCHAR firstTag = filterString.GetAt(0); |
| 235 // Any tag | 184 // Any tag |
| 236 if (firstTag == '*') | 185 if (firstTag == '*') |
| 237 { | 186 { |
| 238 filterString = filterString.Right(filterString.GetLength() - 1); | 187 filterString = filterString.Right(filterString.GetLength() - 1); |
| 239 } | 188 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 261 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterTe
xt + " (invalid tag)") | 210 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterTe
xt + " (invalid tag)") |
| 262 s_criticalSectionFilterMap.Unlock(); | 211 s_criticalSectionFilterMap.Unlock(); |
| 263 return false; | 212 return false; |
| 264 } | 213 } |
| 265 | 214 |
| 266 // Find Id and class name | 215 // Find Id and class name |
| 267 CString id; | 216 CString id; |
| 268 CString className; | 217 CString className; |
| 269 | 218 |
| 270 // In old format, id/class is part of attributes | 219 // In old format, id/class is part of attributes |
| 271 if (isOldFormat == false && !filterString.IsEmpty()) | 220 if (!filterString.IsEmpty()) |
| 272 { | 221 { |
| 273 TCHAR firstId = filterString.GetAt(0); | 222 TCHAR firstId = filterString.GetAt(0); |
| 274 | 223 |
| 275 // Id | 224 // Id |
| 276 if (firstId == '#') | 225 if (firstId == '#') |
| 277 { | 226 { |
| 278 int pos = filterString.Find('['); | 227 int pos = filterString.Find('['); |
| 279 if (pos > 0) | 228 if (pos > 0) |
| 280 { | 229 { |
| 281 id = filterString.Mid(1, pos - 1); | 230 id = filterString.Mid(1, pos - 1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 305 { | 254 { |
| 306 } | 255 } |
| 307 else | 256 else |
| 308 { | 257 { |
| 309 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filter
Text + " (invalid id/class)") | 258 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filter
Text + " (invalid id/class)") |
| 310 s_criticalSectionFilterMap.Unlock(); | 259 s_criticalSectionFilterMap.Unlock(); |
| 311 return false; | 260 return false; |
| 312 } | 261 } |
| 313 } | 262 } |
| 314 | 263 |
| 315 char chAttrStart = isOldFormat ? '(' : '['; | 264 char chAttrStart = '['; |
| 316 char chAttrEnd = isOldFormat ? ')' : ']'; | 265 char chAttrEnd = ']'; |
| 317 | 266 |
| 318 // Find attribute selectors | 267 // Find attribute selectors |
| 319 if (!filterString.IsEmpty() && filterString.GetAt(0) != chAttrStart) | 268 if (!filterString.IsEmpty() && filterString.GetAt(0) != chAttrStart) |
| 320 { | 269 { |
| 321 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterTe
xt + " (invalid attr selector)") | 270 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filterTe
xt + " (invalid attr selector)") |
| 322 s_criticalSectionFilterMap.Unlock(); | 271 s_criticalSectionFilterMap.Unlock(); |
| 323 return false; | 272 return false; |
| 324 } | 273 } |
| 325 | 274 |
| 326 if (!filterString.IsEmpty()) | 275 if (!filterString.IsEmpty()) |
| 327 { | 276 { |
| 328 int startPos = 0; | 277 int startPos = 0; |
| 329 int endPos = 0; | 278 int endPos = 0; |
| 330 | 279 |
| 331 while ((startPos = filterString.Find(chAttrStart, startPos)) >= 0 && (endP
os = filterString.Find(chAttrEnd, startPos)) > startPos) | 280 while ((startPos = filterString.Find(chAttrStart, startPos)) >= 0 && (endP
os = filterString.Find(chAttrEnd, startPos)) > startPos) |
| 332 { | 281 { |
| 333 CFilterElementHideAttrSelector attrSelector; | 282 CFilterElementHideAttrSelector attrSelector; |
| 334 | 283 |
| 335 CString arg = filterString.Mid(startPos + 1, endPos - startPos - 1); | 284 CString arg = filterString.Mid(startPos + 1, endPos - startPos - 1); |
| 285 int delimiterPos = 0; |
| 336 | 286 |
| 337 if ((delimiterPos = arg.Find('=')) > 0) | 287 if ((delimiterPos = arg.Find('=')) > 0) |
| 338 { | 288 { |
| 339 attrSelector.m_value = arg.Mid(delimiterPos + 1, arg.GetLength() - del
imiterPos - 1); | 289 attrSelector.m_value = arg.Mid(delimiterPos + 1, arg.GetLength() - del
imiterPos - 1); |
| 340 if (attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetA
t(attrSelector.m_value.GetLength() - 1) == '\"' && attrSelector.m_value.GetLengt
h() >= 2) | 290 if (attrSelector.m_value.GetAt(0) == '\"' && attrSelector.m_value.GetA
t(attrSelector.m_value.GetLength() - 1) == '\"' && attrSelector.m_value.GetLengt
h() >= 2) |
| 341 { | 291 { |
| 342 attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_va
lue.GetLength() - 2); | 292 attrSelector.m_value = attrSelector.m_value.Mid(1, attrSelector.m_va
lue.GetLength() - 2); |
| 343 } | 293 } |
| 344 | 294 |
| 345 if (arg.GetAt(delimiterPos - 1) == '^') | 295 if (arg.GetAt(delimiterPos - 1) == '^') |
| (...skipping 25 matching lines...) Expand all Loading... |
| 371 } | 321 } |
| 372 else if (tag == "id") | 322 else if (tag == "id") |
| 373 { | 323 { |
| 374 attrSelector.m_isId = true; | 324 attrSelector.m_isId = true; |
| 375 } | 325 } |
| 376 else if (tag == "class") | 326 else if (tag == "class") |
| 377 { | 327 { |
| 378 attrSelector.m_isClass = true; | 328 attrSelector.m_isClass = true; |
| 379 } | 329 } |
| 380 | 330 |
| 381 // id/class name in old format should not be stored as attributes | 331 filter.m_attributeSelectors.push_back(attrSelector); |
| 382 if (isOldFormat && attrSelector.m_isExact && attrSelector.m_isId) | |
| 383 { | |
| 384 id = attrSelector.m_value; | |
| 385 } | |
| 386 else if (isOldFormat && attrSelector.m_isExact && attrSelector.m_isCla
ss) | |
| 387 { | |
| 388 className = attrSelector.m_value; | |
| 389 } | |
| 390 else | |
| 391 { | |
| 392 filter.m_attributeSelectors.push_back(attrSelector); | |
| 393 } | |
| 394 } | 332 } |
| 395 | 333 |
| 396 startPos = endPos + 1; | 334 startPos = endPos + 1; |
| 397 } | 335 } |
| 398 | 336 |
| 399 // End check | 337 // End check |
| 400 if (filterString.GetLength() != endPos + 1) | 338 if (filterString.GetLength() != endPos + 1) |
| 401 { | 339 { |
| 402 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filter
Text + " (more data)") | 340 DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + filter
Text + " (more data)") |
| 403 s_criticalSectionFilterMap.Unlock(); | 341 s_criticalSectionFilterMap.Unlock(); |
| 404 return false; | 342 return false; |
| 405 } | 343 } |
| 406 } | 344 } |
| 407 | 345 |
| 408 // Add the filter | 346 if (!id.IsEmpty()) |
| 409 if (isDomainSpecific) | |
| 410 { | |
| 411 filter.m_tagId = id; | |
| 412 filter.m_tagClassName = className; | |
| 413 | |
| 414 int endPos = 0; | |
| 415 | |
| 416 while ((endPos = filterDomains.Find(',')) >= 0 || !filterDomains.IsEmpty()
) | |
| 417 { | |
| 418 CString domain; | |
| 419 | |
| 420 if (endPos == -1) | |
| 421 { | |
| 422 domain = filterDomains; | |
| 423 | |
| 424 filterDomains.Empty(); | |
| 425 } | |
| 426 else | |
| 427 { | |
| 428 domain = filterDomains.Left(endPos); | |
| 429 | |
| 430 filterDomains = filterDomains.Right(filterDomains.GetLength() - endPos
- 1); | |
| 431 } | |
| 432 | |
| 433 TFilterElementHideDomains::iterator it = m_elementHideDomains.find(domai
n); | |
| 434 if (it == m_elementHideDomains.end()) | |
| 435 { | |
| 436 TFilterElementHideDomain domainList; | |
| 437 | |
| 438 domainList.insert(std::make_pair(tag, filter)); | |
| 439 | |
| 440 m_elementHideDomains[domain] = domainList; | |
| 441 } | |
| 442 else | |
| 443 { | |
| 444 it->second.insert(std::make_pair(tag, filter)); | |
| 445 } | |
| 446 } | |
| 447 } | |
| 448 else if (!id.IsEmpty()) | |
| 449 { | 347 { |
| 450 if (id.Find(L".") > 0) | 348 if (id.Find(L".") > 0) |
| 451 { | 349 { |
| 452 id = id.Left(id.Find(L".")); | 350 id = id.Left(id.Find(L".")); |
| 453 filter.m_tagClassName = id.Right(id.Find(L".")); | 351 filter.m_tagClassName = id.Right(id.Find(L".")); |
| 454 filter.m_tagId = id; | 352 filter.m_tagId = id; |
| 455 } | 353 } |
| 456 m_elementHideTagsId[std::make_pair(tag, id)] = filter; | 354 m_elementHideTagsId[std::make_pair(tag, id)] = filter; |
| 457 } | 355 } |
| 458 else if (!className.IsEmpty()) | 356 else if (!className.IsEmpty()) |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 s_criticalSectionFilterMap.Lock(); | 715 s_criticalSectionFilterMap.Lock(); |
| 818 { | 716 { |
| 819 for (std::vector<std::string>::iterator it = filters.begin(); it < filters.e
nd(); ++it) | 717 for (std::vector<std::string>::iterator it = filters.begin(); it < filters.e
nd(); ++it) |
| 820 { | 718 { |
| 821 CString filter((*it).c_str()); | 719 CString filter((*it).c_str()); |
| 822 // If the line is not commented out | 720 // If the line is not commented out |
| 823 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') | 721 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') |
| 824 { | 722 { |
| 825 int filterType = 0; | 723 int filterType = 0; |
| 826 | 724 |
| 827 // We need to categorize the filters | |
| 828 // We have three options, whitelist, block or element hiding | |
| 829 // See http://adblockplus.org/en/filters for further documentation | 725 // See http://adblockplus.org/en/filters for further documentation |
| 830 | 726 |
| 831 // @@ indicates white listing rule | |
| 832 if (filter.Find(L"@@") == 0) | |
| 833 { | |
| 834 filterType = CFilter::filterTypeWhiteList; | |
| 835 | |
| 836 filter.Delete(0, 2); | |
| 837 } | |
| 838 // If a filter contains ## then it is a element hiding rule | |
| 839 else if (filter.Find(L"#") >= 0) | |
| 840 { | |
| 841 filterType = CFilter::filterTypeElementHide; | |
| 842 } | |
| 843 //Anything we do not support here | |
| 844 else if (filter.Find(L"*") == 0) | |
| 845 { | |
| 846 filterType = CFilter::filterTypeUnknown; | |
| 847 } | |
| 848 // Else, it is a general rule | |
| 849 else | |
| 850 { | |
| 851 filterType = CFilter::filterTypeBlocking; | |
| 852 } | |
| 853 | |
| 854 try | 727 try |
| 855 { | 728 { |
| 856 if (filterType == CFilter::filterTypeElementHide) | 729 AddFilterElementHide(filter); |
| 857 { | |
| 858 AddFilterElementHide(filter); | |
| 859 } | |
| 860 } | 730 } |
| 861 catch(...) | 731 catch(...) |
| 862 { | 732 { |
| 863 //just ignore all errors we might get when adding filters | 733 #ifdef ENABLE_DEBUG_RESULT |
| 734 CPluginDebug::DebugResult(L"Error loading hide filter: " + filter); |
| 735 #endif |
| 864 } | 736 } |
| 865 } | 737 } |
| 866 } | 738 } |
| 867 } | 739 } |
| 868 s_criticalSectionFilterMap.Unlock(); | 740 s_criticalSectionFilterMap.Unlock(); |
| 869 | 741 |
| 870 return isRead; | 742 return isRead; |
| 871 } | 743 } |
| 872 | 744 |
| 873 void CPluginFilter::ClearFilters() | 745 void CPluginFilter::ClearFilters() |
| (...skipping 12 matching lines...) Expand all Loading... |
| 886 | 758 |
| 887 m_elementHideTags.clear(); | 759 m_elementHideTags.clear(); |
| 888 m_elementHideTagsId.clear(); | 760 m_elementHideTagsId.clear(); |
| 889 m_elementHideTagsClass.clear(); | 761 m_elementHideTagsClass.clear(); |
| 890 m_elementHideDomains.clear(); | 762 m_elementHideDomains.clear(); |
| 891 } | 763 } |
| 892 s_criticalSectionFilterMap.Unlock(); | 764 s_criticalSectionFilterMap.Unlock(); |
| 893 } | 765 } |
| 894 | 766 |
| 895 | 767 |
| 896 bool CPluginFilter::IsMatchFilter(const CFilter& filter, CString src, const CStr
ing& srcDomain, const CString& domain) const | |
| 897 { | |
| 898 // Initial checks | |
| 899 | |
| 900 // $match_case | |
| 901 if (!filter.m_isMatchCase) | |
| 902 { | |
| 903 src.MakeLower(); | |
| 904 } | |
| 905 | |
| 906 // $domain | |
| 907 if (!filter.m_domains.empty()) | |
| 908 { | |
| 909 bool bFound = false; | |
| 910 | |
| 911 for (std::set<CString>::const_iterator it = filter.m_domains.begin(); !bFoun
d && it != filter.m_domains.end(); ++it) | |
| 912 { | |
| 913 bFound = domain == *(it) || IsSubdomain(domain, *it); | |
| 914 } | |
| 915 | |
| 916 if (!bFound) | |
| 917 { | |
| 918 return false; | |
| 919 } | |
| 920 } | |
| 921 | |
| 922 // $domain ~ | |
| 923 if (!filter.m_domainsNot.empty()) | |
| 924 { | |
| 925 for (std::set<CString>::const_iterator it = filter.m_domainsNot.begin(); it
!= filter.m_domainsNot.end(); ++it) | |
| 926 { | |
| 927 if (domain == *(it) || IsSubdomain(domain, *it)) | |
| 928 { | |
| 929 return false; | |
| 930 } | |
| 931 } | |
| 932 } | |
| 933 | |
| 934 // $third_party | |
| 935 if (filter.m_isThirdParty) | |
| 936 { | |
| 937 if (srcDomain == domain || IsSubdomain(srcDomain, domain)) | |
| 938 { | |
| 939 return false; | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 // $third_party ~ | |
| 944 if (filter.m_isFirstParty) | |
| 945 { | |
| 946 if (srcDomain != domain && !IsSubdomain(srcDomain, domain)) | |
| 947 { | |
| 948 return false; | |
| 949 } | |
| 950 } | |
| 951 | |
| 952 // "regex" checks | |
| 953 | |
| 954 int startPos = 0; | |
| 955 int srcLength = src.GetLength(); | |
| 956 UINT indexEnd = filter.m_stringElements.size() - 1; | |
| 957 | |
| 958 for (UINT index = 0; index <= indexEnd; index++) | |
| 959 { | |
| 960 if (index == 0 && filter.m_isFromStartDomain) | |
| 961 { | |
| 962 CString loweredDomain = srcDomain; | |
| 963 int domainPos = src.Find(loweredDomain.MakeLower()); | |
| 964 int lastPos = src.Find('/', domainPos); | |
| 965 | |
| 966 bool bFoundDomain = false; | |
| 967 bool bContinueDomainSearch = true; | |
| 968 | |
| 969 while (bContinueDomainSearch) | |
| 970 { | |
| 971 if (domainPos == FindMatch(src, filter.m_stringElements[index])) | |
| 972 { | |
| 973 bContinueDomainSearch = false; | |
| 974 bFoundDomain = true; | |
| 975 } | |
| 976 else | |
| 977 { | |
| 978 domainPos = src.Find('.', domainPos + 1) + 1; | |
| 979 if (domainPos == 0 || (domainPos >= lastPos && lastPos >= 0)) | |
| 980 { | |
| 981 bContinueDomainSearch = false; | |
| 982 } | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 if (!bFoundDomain) | |
| 987 { | |
| 988 return false; | |
| 989 } | |
| 990 } | |
| 991 | |
| 992 startPos = FindMatch(src, filter.m_stringElements[index], startPos); | |
| 993 if (startPos < 0) | |
| 994 { | |
| 995 return false; | |
| 996 } | |
| 997 | |
| 998 int length = filter.m_stringElements[index].GetLength(); | |
| 999 | |
| 1000 // Check from start | |
| 1001 if (index == 0 && filter.m_isFromStart && startPos > 0) | |
| 1002 { | |
| 1003 return false; | |
| 1004 } | |
| 1005 | |
| 1006 // Check from end | |
| 1007 if (index == indexEnd && filter.m_isFromEnd && startPos + length != srcLengt
h) | |
| 1008 { | |
| 1009 return false; | |
| 1010 } | |
| 1011 | |
| 1012 startPos += length; | |
| 1013 } | |
| 1014 | |
| 1015 return true; | |
| 1016 } | |
| 1017 | |
| 1018 | |
| 1019 const CFilter* CPluginFilter::MatchFilter(int filterType, const CString& src, in
t contentType, const CString& domain) const | |
| 1020 { | |
| 1021 const CFilter* filter = NULL; | |
| 1022 | |
| 1023 int startCharacter = 0; | |
| 1024 int keyLength = 4; | |
| 1025 | |
| 1026 CString srcLower = src; | |
| 1027 srcLower.MakeLower(); | |
| 1028 int srcLowerLength = srcLower.GetLength(); | |
| 1029 | |
| 1030 // Extract src domain | |
| 1031 DWORD length = 2048; | |
| 1032 CString srcDomain; | |
| 1033 | |
| 1034 if (SUCCEEDED(::UrlGetPart(src, srcDomain.GetBufferSetLength(2048), &length, U
RL_PART_HOSTNAME, 0))) | |
| 1035 { | |
| 1036 srcDomain.ReleaseBuffer(); | |
| 1037 | |
| 1038 if (srcDomain.Left(4) == L"www.") | |
| 1039 { | |
| 1040 srcDomain = srcDomain.Right(srcDomain.GetLength() - 4); | |
| 1041 } | |
| 1042 else if (srcDomain.Left(5) == L"www2." || srcDomain.Left(5) == L"www3.") | |
| 1043 { | |
| 1044 srcDomain = srcDomain.Right(srcDomain.GetLength() - 5); | |
| 1045 } | |
| 1046 } | |
| 1047 else | |
| 1048 { | |
| 1049 srcDomain.ReleaseBuffer(); | |
| 1050 srcDomain.Empty(); | |
| 1051 } | |
| 1052 | |
| 1053 // Search in filter map | |
| 1054 s_criticalSectionFilterMap.Lock(); | |
| 1055 { | |
| 1056 const TFilterMap* filterMap = m_filterMap[filterType]; | |
| 1057 | |
| 1058 if (srcLowerLength >= 7) | |
| 1059 { | |
| 1060 if (srcLower.Find(L"http://") == 0) | |
| 1061 { | |
| 1062 startCharacter = 7; | |
| 1063 } | |
| 1064 else if (srcLower.Find(L"https://") == 0) | |
| 1065 { | |
| 1066 startCharacter = 8; | |
| 1067 } | |
| 1068 } | |
| 1069 | |
| 1070 DWORD dwKey = 0; | |
| 1071 | |
| 1072 while (filter == NULL && srcLowerLength >= startCharacter + keyLength) | |
| 1073 { | |
| 1074 if (dwKey == 0) | |
| 1075 { | |
| 1076 dwKey = (srcLower.GetAt(startCharacter) << 24) | (srcLower.GetAt(startCh
aracter+1) << 16) | (srcLower.GetAt(startCharacter+2) << 8) | srcLower.GetAt(sta
rtCharacter+3); | |
| 1077 } | |
| 1078 else | |
| 1079 { | |
| 1080 dwKey <<= 8; | |
| 1081 dwKey |= srcLower.GetAt(startCharacter+3); | |
| 1082 } | |
| 1083 | |
| 1084 TFilterMap::const_iterator foundEntry = filterMap[0].find(dwKey); | |
| 1085 if (foundEntry != filterMap[0].end()) | |
| 1086 { | |
| 1087 if (((foundEntry->second.m_contentType & contentType) || foundEntry->sec
ond.m_contentType == CFilter::contentTypeAny) && IsMatchFilter(foundEntry->secon
d, src, srcDomain, domain)) | |
| 1088 { | |
| 1089 filter = &(foundEntry->second); | |
| 1090 break; | |
| 1091 } | |
| 1092 } | |
| 1093 | |
| 1094 // No match - increment the start character | |
| 1095 startCharacter++; | |
| 1096 } | |
| 1097 | |
| 1098 // Second list | |
| 1099 if (filter == NULL) | |
| 1100 { | |
| 1101 dwKey = 0; | |
| 1102 startCharacter = 0; | |
| 1103 | |
| 1104 if (srcLowerLength >= 7) | |
| 1105 { | |
| 1106 if (srcLower.Find(L"http://") == 0) | |
| 1107 { | |
| 1108 startCharacter = 7; | |
| 1109 } | |
| 1110 else if (srcLower.Find(L"https://") == 0) | |
| 1111 { | |
| 1112 startCharacter = 8; | |
| 1113 } | |
| 1114 } | |
| 1115 | |
| 1116 while (filter == NULL && srcLowerLength >= startCharacter + keyLength) | |
| 1117 { | |
| 1118 if (dwKey == 0) | |
| 1119 { | |
| 1120 dwKey = (srcLower.GetAt(startCharacter) << 24) | (srcLower.GetAt(start
Character+1) << 16) | (srcLower.GetAt(startCharacter+2) << 8) | srcLower.GetAt(s
tartCharacter+3); | |
| 1121 } | |
| 1122 else | |
| 1123 { | |
| 1124 dwKey <<= 8; | |
| 1125 dwKey |= srcLower.GetAt(startCharacter+3); | |
| 1126 } | |
| 1127 | |
| 1128 TFilterMap::const_iterator foundEntry = filterMap[1].find(dwKey); | |
| 1129 if (foundEntry != filterMap[1].end()) | |
| 1130 { | |
| 1131 if (((foundEntry->second.m_contentType & contentType) || foundEntry->s
econd.m_contentType == CFilter::contentTypeAny) && IsMatchFilter(foundEntry->sec
ond, src, srcDomain, domain)) | |
| 1132 { | |
| 1133 filter = &(foundEntry->second); | |
| 1134 break; | |
| 1135 } | |
| 1136 } | |
| 1137 | |
| 1138 // No match - increment the start character | |
| 1139 startCharacter++; | |
| 1140 } | |
| 1141 } | |
| 1142 | |
| 1143 // Search in default filter map (try all filters) | |
| 1144 if (filter == NULL) | |
| 1145 { | |
| 1146 for (TFilterMapDefault::const_iterator it = m_filterMapDefault[filterType]
.begin(); it != m_filterMapDefault[filterType].end(); ++it) | |
| 1147 { | |
| 1148 if (((it->m_contentType & contentType) || it->m_contentType == CFilter::
contentTypeAny) && IsMatchFilter(*it, src, srcDomain, domain)) | |
| 1149 { | |
| 1150 filter = &(*it); | |
| 1151 break; | |
| 1152 } | |
| 1153 } | |
| 1154 } | |
| 1155 | |
| 1156 } | |
| 1157 s_criticalSectionFilterMap.Unlock(); | |
| 1158 | |
| 1159 return filter; | |
| 1160 } | |
| 1161 | |
| 1162 | |
| 1163 bool CPluginFilter::ShouldWhiteList(CString src) const | 768 bool CPluginFilter::ShouldWhiteList(CString src) const |
| 1164 { | 769 { |
| 1165 // We should not block the empty string, so all filtering does not make sense | 770 // We should not block the empty string, so all filtering does not make sense |
| 1166 // Therefore we just return | 771 // Therefore we just return |
| 1167 if (src.Trim().IsEmpty()) | 772 if (src.Trim().IsEmpty()) |
| 1168 { | 773 { |
| 1169 return false; | 774 return false; |
| 1170 } | 775 } |
| 1171 | 776 |
| 1172 const CFilter* filter = MatchFilter(CFilter::filterTypeWhiteList, src, CFilter
::contentTypeDocument, ""); | 777 //TODO: Implement whitelisting check from libadblockplus here. Probably not ne
eded anymore |
| 1173 | 778 return false; |
| 1174 return filter ? true : false; | |
| 1175 } | 779 } |
| 1176 | 780 |
| 1177 | 781 |
| 1178 bool CPluginFilter::ShouldBlock(CString src, int contentType, const CString& dom
ain, bool addDebug) const | 782 bool CPluginFilter::ShouldBlock(CString src, int contentType, const CString& dom
ain, bool addDebug) const |
| 1179 { | 783 { |
| 1180 // We should not block the empty string, so all filtering does not make sense | 784 // We should not block the empty string, so all filtering does not make sense |
| 1181 // Therefore we just return | 785 // Therefore we just return |
| 1182 if (src.Trim().IsEmpty()) | 786 if (src.Trim().IsEmpty()) |
| 1183 { | 787 { |
| 1184 return false; | 788 return false; |
| 1185 } | 789 } |
| 1186 | 790 |
| 1187 CPluginSettings* settings = CPluginSettings::GetInstance(); | 791 CPluginSettings* settings = CPluginSettings::GetInstance(); |
| 1188 | 792 |
| 1189 CString type; | 793 CString type; |
| 1190 if (addDebug) | 794 if (addDebug) |
| 1191 { | 795 { |
| 1192 type = "???"; | 796 type = "???"; |
| 1193 | 797 |
| 1194 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType
); | 798 std::map<int,CString>::const_iterator it = m_contentMapText.find(contentType
); |
| 1195 if (it != m_contentMapText.end()) | 799 if (it != m_contentMapText.end()) |
| 1196 { | 800 { |
| 1197 type = it->second; | 801 type = it->second; |
| 1198 } | 802 } |
| 1199 } | 803 } |
| 1200 | 804 |
| 1201 CPluginClient* client = CPluginClient::GetInstance(); | 805 CPluginClient* client = CPluginClient::GetInstance(); |
| 1202 AdblockPlus::FilterEngine* filterEngine = client->GetFilterEngine(); | 806 AdblockPlus::FilterEngine* filterEngine = client->GetFilterEngine(); |
| 1203 | 807 |
| 1204 // src.OemToCharA(); | 808 //TODO: Make sure if the content type names are in sync with libadblockplus |
| 809 std::string contentTypeString = CT2A(type, CP_UTF8); |
| 1205 | 810 |
| 1206 std::string contentTypeString = ""; | 811 CT2CA srcMb(src, CP_UTF8); |
| 812 std::string url(srcMb); |
| 1207 | 813 |
| 1208 CT2CA srcAnsi(src); | 814 std::string domainMb = CT2CA(domain); |
| 1209 std::string url(srcAnsi); | 815 |
| 1210 if (filterEngine->Matches(url, contentTypeString)) | 816 if (filterEngine->Matches(url, contentTypeString, domainMb)) |
| 1211 { | 817 { |
| 1212 if (addDebug) | 818 if (addDebug) |
| 1213 { | 819 { |
| 1214 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 820 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") |
| 1215 | 821 |
| 1216 #ifdef ENABLE_DEBUG_RESULT | 822 #ifdef ENABLE_DEBUG_RESULT |
| 1217 CPluginDebug::DebugResultBlocking(type, src); | 823 CPluginDebug::DebugResultBlocking(type, src); |
| 1218 #endif | 824 #endif |
| 1219 } | 825 } |
| 1220 return true; | 826 return true; |
| 1221 } | 827 } |
| 1222 return false; | 828 return false; |
| 1223 | |
| 1224 //The following is for reference only | |
| 1225 | |
| 1226 const CFilter* blockFilter = MatchFilter(CFilter::filterTypeBlocking, src, con
tentType, domain); | |
| 1227 if (blockFilter) | |
| 1228 { | |
| 1229 const CFilter* whiteFilter = MatchFilter(CFilter::filterTypeWhiteList, src,
contentType, domain); | |
| 1230 if (whiteFilter) | |
| 1231 { | |
| 1232 if (addDebug) | |
| 1233 { | |
| 1234 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src + " - whi
telist:\"" + whiteFilter->m_filterText + "\""); | |
| 1235 } | |
| 1236 blockFilter = NULL; | |
| 1237 } | |
| 1238 else if (addDebug) | |
| 1239 { | |
| 1240 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES src:" + src + " - \"" +
blockFilter->m_filterText + "\"") | |
| 1241 | |
| 1242 #ifdef ENABLE_DEBUG_RESULT | |
| 1243 CPluginDebug::DebugResultBlocking(type, src); | |
| 1244 #endif | |
| 1245 } | |
| 1246 } | |
| 1247 else if (addDebug) | |
| 1248 { | |
| 1249 DEBUG_FILTER("Filter::ShouldBlock " + type + " NO src:" + src) | |
| 1250 } | |
| 1251 | |
| 1252 return blockFilter ? true : false; | |
| 1253 } | 829 } |
| 1254 | 830 |
| 1255 int CPluginFilter::FindMatch(const CString& src, CString filterPart, int srcStar
tPos) const | 831 int CPluginFilter::FindMatch(const CString& src, CString filterPart, int srcStar
tPos) const |
| 1256 { | 832 { |
| 1257 int filterCurrentPos = filterPart.Find('^'); | 833 int filterCurrentPos = filterPart.Find('^'); |
| 1258 if (filterCurrentPos >= 0) | 834 if (filterCurrentPos >= 0) |
| 1259 { | 835 { |
| 1260 int srcLength = src.GetLength(); | 836 int srcLength = src.GetLength(); |
| 1261 int srcFilterPos = -1; | 837 int srcFilterPos = -1; |
| 1262 int srcCurrentPos = srcStartPos; | 838 int srcCurrentPos = srcStartPos; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 if (pos > 0 && domain.GetLength() + pos == subdomain.GetLength()) | 972 if (pos > 0 && domain.GetLength() + pos == subdomain.GetLength()) |
| 1397 { | 973 { |
| 1398 if (subdomain.GetAt(pos - 1) == '.') | 974 if (subdomain.GetAt(pos - 1) == '.') |
| 1399 { | 975 { |
| 1400 return true; | 976 return true; |
| 1401 } | 977 } |
| 1402 } | 978 } |
| 1403 | 979 |
| 1404 return false; | 980 return false; |
| 1405 } | 981 } |
| OLD | NEW |