| Left: | ||
| Right: | 
| LEFT | RIGHT | 
|---|---|
| 1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" | 
| 2 | 2 | 
| 3 #include "PluginFilter.h" | 3 #include "PluginFilter.h" | 
| 4 #include "PluginSettings.h" | 4 #include "PluginSettings.h" | 
| 5 #include "PluginClient.h" | 5 #include "PluginClient.h" | 
| 6 #include "PluginClientFactory.h" | 6 #include "PluginClientFactory.h" | 
| 7 #include "PluginMutex.h" | 7 #include "PluginMutex.h" | 
| 8 #include "PluginSettings.h" | 8 #include "PluginSettings.h" | 
| 9 #include "PluginSystem.h" | 9 #include "PluginSystem.h" | 
| 10 #include "PluginClass.h" | 10 #include "PluginClass.h" | 
| 11 #include "mlang.h" | 11 #include "mlang.h" | 
| 12 | 12 | 
| 13 #include "..\shared\CriticalSection.h" | 13 #include "..\shared\CriticalSection.h" | 
| 14 #include "..\shared\Utils.h" | |
| 14 | 15 | 
| 15 | 16 | 
| 16 // The filters are described at http://adblockplus.org/en/filters | 17 // The filters are described at http://adblockplus.org/en/filters | 
| 17 | 18 | 
| 18 static CriticalSection s_criticalSectionFilterMap; | 19 static CriticalSection s_criticalSectionFilterMap; | 
| 20 | |
| 21 namespace | |
| 22 { | |
| 23 struct GetHtmlElementAttributeResult | |
| 24 { | |
| 25 GetHtmlElementAttributeResult() : isAttributeFound(false) | |
| 26 { | |
| 27 } | |
| 28 std::wstring attributeValue; | |
| 29 bool isAttributeFound; | |
| 30 }; | |
| 31 | |
| 32 GetHtmlElementAttributeResult GetHtmlElementAttribute(IHTMLElement& htmlElemen t, | |
| 33 const ATL::CComBSTR& attributeName) | |
| 34 { | |
| 35 GetHtmlElementAttributeResult retValue; | |
| 36 ATL::CComVariant vAttr; | |
| 37 ATL::CComPtr<IHTMLElement4> htmlElement4; | |
| 38 if (FAILED(htmlElement.QueryInterface(&htmlElement4)) || !htmlElement4) | |
| 39 { | |
| 40 return retValue; | |
| 41 } | |
| 42 ATL::CComPtr<IHTMLDOMAttribute> attributeNode; | |
| 43 if (FAILED(htmlElement4->getAttributeNode(attributeName, &attributeNode)) || !attributeNode) | |
| 44 { | |
| 45 return retValue; | |
| 46 } | |
| 47 // we set that attribute found but it's not necessary that we can retrieve i ts value | |
| 48 retValue.isAttributeFound = true; | |
| 49 if (FAILED(attributeNode->get_nodeValue(&vAttr))) | |
| 50 { | |
| 51 return retValue; | |
| 52 } | |
| 53 if (vAttr.vt == VT_BSTR && vAttr.bstrVal) | |
| 54 { | |
| 55 retValue.attributeValue = vAttr.bstrVal; | |
| 56 } | |
| 57 else if (vAttr.vt == VT_I4) | |
| 58 { | |
| 59 retValue.attributeValue = std::to_wstring(vAttr.iVal); | |
| 60 } | |
| 61 return retValue; | |
| 62 } | |
| 63 } | |
| 19 | 64 | 
| 20 // ============================================================================ | 65 // ============================================================================ | 
| 21 // CFilterElementHideAttrSelector | 66 // CFilterElementHideAttrSelector | 
| 22 // ============================================================================ | 67 // ============================================================================ | 
| 23 | 68 | 
| 24 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 69 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 
| 25 { | 70 { | 
| 26 } | 71 } | 
| 27 | 72 | 
| 28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) | 73 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) | 
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 } | 310 } | 
| 266 if (!foundMatch) | 311 if (!foundMatch) | 
| 267 { | 312 { | 
| 268 return false; | 313 return false; | 
| 269 } | 314 } | 
| 270 } | 315 } | 
| 271 } | 316 } | 
| 272 if (!m_tag.IsEmpty()) | 317 if (!m_tag.IsEmpty()) | 
| 273 { | 318 { | 
| 274 CComBSTR tagName; | 319 CComBSTR tagName; | 
| 320 hr = pEl->get_tagName(&tagName); | |
| 275 tagName.ToLower(); | 321 tagName.ToLower(); | 
| 276 hr = pEl->get_tagName(&tagName); | |
| 277 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | 322 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | 
| 278 { | 323 { | 
| 279 return false; | 324 return false; | 
| 280 } | 325 } | 
| 281 } | 326 } | 
| 282 | 327 | 
| 283 // Check attributes | 328 // Check attributes | 
| 284 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); | 329 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); | 
| 285 attrIt != m_attributeSelectors.end(); ++ attrIt) | 330 attrIt != m_attributeSelectors.end(); ++ attrIt) | 
| 286 { | 331 { | 
| 287 CString value; | 332 ATL::CString value; | 
| 288 bool attrFound = false; | 333 bool attrFound = false; | 
| 289 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 334 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 
| 290 { | 335 { | 
| 291 CComPtr<IHTMLStyle> pStyle; | 336 CComPtr<IHTMLStyle> pStyle; | 
| 292 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 337 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 
| 293 { | 338 { | 
| 294 CComBSTR bstrStyle; | 339 CComBSTR bstrStyle; | 
| 295 | 340 | 
| 296 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | 341 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | 
| 297 { | 342 { | 
| (...skipping 14 matching lines...) Expand all Loading... | |
| 312 } | 357 } | 
| 313 else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 358 else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 
| 314 { | 359 { | 
| 315 CComBSTR bstrId; | 360 CComBSTR bstrId; | 
| 316 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 361 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 
| 317 { | 362 { | 
| 318 value = bstrId; | 363 value = bstrId; | 
| 319 attrFound = true; | 364 attrFound = true; | 
| 320 } | 365 } | 
| 321 } | 366 } | 
| 322 else | 367 else | 
| 323 { | 368 { | 
| 324 CComVariant vAttr; | 369 auto attributeValue = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr); | 
| 325 if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) | 370 if (attrFound = attributeValue.isAttributeFound) | 
| 326 { | 371 { | 
| 327 attrFound = true; | 372 value = ToCString(attributeValue.attributeValue); | 
| 328 if (vAttr.vt == VT_BSTR) | |
| 329 { | |
| 330 value = vAttr.bstrVal; | |
| 331 } | |
| 332 else if (vAttr.vt == VT_I4) | |
| 333 { | |
| 334 value.Format(L"%u", vAttr.iVal); | |
| 335 } | |
| 336 } | 373 } | 
| 337 } | 374 } | 
| 338 | 375 | 
| 339 if (attrFound) | 376 if (attrFound) | 
| 340 { | 377 { | 
| 341 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 378 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 
| 342 { | 379 { | 
| 343 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. | 380 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. | 
| 344 if (value != attrIt->m_value) | 381 if (value != attrIt->m_value) | 
| 345 return false; | 382 return false; | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 | 450 | 
| 414 | 451 | 
| 415 // ============================================================================ | 452 // ============================================================================ | 
| 416 // CPluginFilter | 453 // CPluginFilter | 
| 417 // ============================================================================ | 454 // ============================================================================ | 
| 418 | 455 | 
| 419 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 456 CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) | 
| 420 { | 457 { | 
| 421 m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT"; | 458 m_contentMapText[CFilter::contentTypeDocument] = "DOCUMENT"; | 
| 422 m_contentMapText[CFilter::contentTypeObject] = "OBJECT"; | 459 m_contentMapText[CFilter::contentTypeObject] = "OBJECT"; | 
| 423 m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT-SUBREQUEST"; | 460 m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT_SUBREQUEST"; | 
| 424 m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 461 m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 
| 425 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 462 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 
| 426 m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 463 m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 
| 427 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 464 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 
| 428 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 465 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 
| 429 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 466 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 
| 430 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 467 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 
| 431 | 468 | 
| 432 ClearFilters(); | 469 ClearFilters(); | 
| 433 } | 470 } | 
| 434 | 471 | 
| 435 | 472 | 
| 436 bool CPluginFilter::AddFilterElementHide(CString filterText) | 473 bool CPluginFilter::AddFilterElementHide(CString filterText) | 
| 437 { | 474 { | 
| 438 | |
| 439 | |
| 440 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 475 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 
| 441 | 476 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 442 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 477 { | 
| 443 { | |
| 444 | |
| 445 CString filterString = filterText; | 478 CString filterString = filterText; | 
| 446 // Create filter descriptor | 479 // Create filter descriptor | 
| 447 std::auto_ptr<CFilterElementHide> filter; | 480 std::auto_ptr<CFilterElementHide> filter; | 
| 448 | 481 | 
| 449 CString wholeFilterString = filterString; | 482 CString wholeFilterString = filterString; | 
| 450 wchar_t separatorChar; | 483 wchar_t separatorChar; | 
| 451 do | 484 do | 
| 452 { | 485 { | 
| 453 int chunkEnd = filterText.FindOneOf(L"+>"); | 486 int chunkEnd = filterText.FindOneOf(L"+>"); | 
| 454 if (chunkEnd > 0) | 487 if (chunkEnd > 0) | 
| 455 { | 488 { | 
| 456 separatorChar = filterText.GetAt(chunkEnd); | 489 separatorChar = filterText.GetAt(chunkEnd); | 
| 457 } | 490 } | 
| 458 else | 491 else | 
| 459 { | 492 { | 
| 460 chunkEnd = filterText.GetLength(); | 493 chunkEnd = filterText.GetLength(); | 
| 461 separatorChar = L'\0'; | 494 separatorChar = L'\0'; | 
| 462 } | 495 } | 
| 463 | 496 | 
| 464 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 497 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 
| 465 std::auto_ptr<CFilterElementHide> filterParent(filter); | 498 std::auto_ptr<CFilterElementHide> filterParent(filter); | 
| 466 | 499 | 
| 467 filter.reset(new CFilterElementHide(filterChunk)); | 500 filter.reset(new CFilterElementHide(filterChunk)); | 
| 468 | 501 | 
| 469 if (filterParent.get() != 0) | 502 if (filterParent.get() != 0) | 
| 470 { | 503 { | 
| 471 filter->m_predecessor.reset(filterParent.release()); | 504 filter->m_predecessor.reset(filterParent.release()); | 
| 472 } | 505 } | 
| 473 | 506 | 
| 474 if (separatorChar != L'\0') // complex selector | 507 if (separatorChar != L'\0') // complex selector | 
| 475 { | 508 { | 
| 476 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 509 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 
| 477 if (separatorChar == '+') | 510 if (separatorChar == '+') | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 id = bstrId; | 545 id = bstrId; | 
| 513 } | 546 } | 
| 514 | 547 | 
| 515 CString classNames; | 548 CString classNames; | 
| 516 CComBSTR bstrClassNames; | 549 CComBSTR bstrClassNames; | 
| 517 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 550 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 
| 518 { | 551 { | 
| 519 classNames = bstrClassNames; | 552 classNames = bstrClassNames; | 
| 520 } | 553 } | 
| 521 | 554 | 
| 522 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 555 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 523 { | 556 { | 
| 524 // Search tag/id filters | 557 // Search tag/id filters | 
| 525 if (!id.IsEmpty()) | 558 if (!id.IsEmpty()) | 
| 526 { | 559 { | 
| 527 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = | 560 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = | 
| 528 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 561 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 
| 529 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) | 562 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) | 
| 530 { | 563 { | 
| 531 if (idIt->second.IsMatchFilterElementHide(pEl)) | 564 if (idIt->second.IsMatchFilterElementHide(pEl)) | 
| 532 { | 565 { | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 } | 647 } | 
| 615 | 648 | 
| 616 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 649 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 
| 617 { | 650 { | 
| 618 ClearFilters(); | 651 ClearFilters(); | 
| 619 bool isRead = false; | 652 bool isRead = false; | 
| 620 CPluginClient* client = CPluginClient::GetInstance(); | 653 CPluginClient* client = CPluginClient::GetInstance(); | 
| 621 | 654 | 
| 622 // Parse hide string | 655 // Parse hide string | 
| 623 int pos = 0; | 656 int pos = 0; | 
| 624 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 657 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 625 { | 658 { | 
| 626 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) | 659 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) | 
| 627 { | 660 { | 
| 628 CString filter((*it).c_str()); | 661 CString filter((*it).c_str()); | 
| 629 // If the line is not commented out | 662 // If the line is not commented out | 
| 630 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') | 663 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') | 
| 631 { | 664 { | 
| 632 int filterType = 0; | 665 int filterType = 0; | 
| 633 | 666 | 
| 634 // See http://adblockplus.org/en/filters for further documentation | 667 // See http://adblockplus.org/en/filters for further documentation | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 646 } | 679 } | 
| 647 } | 680 } | 
| 648 } | 681 } | 
| 649 | 682 | 
| 650 return isRead; | 683 return isRead; | 
| 651 } | 684 } | 
| 652 | 685 | 
| 653 void CPluginFilter::ClearFilters() | 686 void CPluginFilter::ClearFilters() | 
| 654 { | 687 { | 
| 655 // Clear filter maps | 688 // Clear filter maps | 
| 656 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 689 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 
| 657 { | 690 { | 
| 658 for (int i = 0; i < 2; i++) | 691 for (int i = 0; i < 2; i++) | 
| 659 { | 692 { | 
| 660 for (int j = 0; j < 2; j++) | 693 for (int j = 0; j < 2; j++) | 
| 661 { | 694 { | 
| 662 m_filterMap[i][j].clear(); | 695 m_filterMap[i][j].clear(); | 
| 663 } | 696 } | 
| 664 m_filterMapDefault[i].clear(); | 697 m_filterMapDefault[i].clear(); | 
| 665 } | 698 } | 
| 666 | 699 | 
| 667 m_elementHideTags.clear(); | 700 m_elementHideTags.clear(); | 
| 668 m_elementHideTagsId.clear(); | 701 m_elementHideTagsId.clear(); | 
| 669 m_elementHideTagsClass.clear(); | 702 m_elementHideTagsClass.clear(); | 
| 670 } | 703 } | 
| 671 } | 704 } | 
| 672 | 705 | 
| 673 bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const std::wstring& domain, bool addDebug) const | 706 bool CPluginFilter::ShouldBlock(const std::wstring& src, int contentType, const std::wstring& domain, bool addDebug) const | 
| 674 { | 707 { | 
| 675 CString srcCString = ToCString(src); | 708 std::wstring srcTrimmed = TrimString(src); | 
| 676 srcCString.Trim(); | |
| 
 
Oleksandr
2015/01/05 11:55:40
We have TrimString function in shared/Utils.h for
 
Eric
2015/01/05 16:18:26
Done.
 
 | |
| 677 std::wstring srcTrimmed = ToWstring(srcCString); | |
| 678 | 709 | 
| 679 // We should not block the empty string, so all filtering does not make sense | 710 // We should not block the empty string, so all filtering does not make sense | 
| 680 // Therefore we just return | 711 // Therefore we just return | 
| 681 if (srcTrimmed.empty()) | 712 if (srcTrimmed.empty()) | 
| 682 { | 713 { | 
| 683 return false; | 714 return false; | 
| 684 } | 715 } | 
| 685 CPluginSettings* settings = CPluginSettings::GetInstance(); | 716 CPluginSettings* settings = CPluginSettings::GetInstance(); | 
| 686 | 717 | 
| 687 CString type; | 718 CString type; | 
| (...skipping 15 matching lines...) Expand all Loading... | |
| 703 { | 734 { | 
| 704 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 735 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 
| 705 | 736 | 
| 706 #ifdef ENABLE_DEBUG_RESULT | 737 #ifdef ENABLE_DEBUG_RESULT | 
| 707 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | 738 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | 
| 708 #endif | 739 #endif | 
| 709 } | 740 } | 
| 710 return true; | 741 return true; | 
| 711 } | 742 } | 
| 712 #ifdef ENABLE_DEBUG_RESULT | 743 #ifdef ENABLE_DEBUG_RESULT | 
| 713 CPluginDebug::DebugResultIgnoring(type, src, domain); | 744 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); | 
| 714 #endif | 745 #endif | 
| 715 return false; | 746 return false; | 
| 716 } | 747 } | 
| LEFT | RIGHT |