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"; |
| 460 m_contentMapText[CFilter::contentTypeObjectSubrequest] = "OBJECT_SUBREQUEST"; |
423 m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; | 461 m_contentMapText[CFilter::contentTypeImage] = "IMAGE"; |
424 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; | 462 m_contentMapText[CFilter::contentTypeScript] = "SCRIPT"; |
425 m_contentMapText[CFilter::contentTypeOther] = "OTHER"; | 463 m_contentMapText[CFilter::contentTypeOther] = "OTHER"; |
426 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; | 464 m_contentMapText[CFilter::contentTypeUnknown] = "OTHER"; |
427 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 465 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; |
428 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 466 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; |
429 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 467 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; |
430 | 468 |
431 ClearFilters(); | 469 ClearFilters(); |
432 } | 470 } |
433 | 471 |
434 | 472 |
435 bool CPluginFilter::AddFilterElementHide(CString filterText) | 473 bool CPluginFilter::AddFilterElementHide(CString filterText) |
436 { | 474 { |
437 | |
438 | |
439 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 475 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); |
440 | 476 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
441 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 477 { |
442 { | |
443 | |
444 CString filterString = filterText; | 478 CString filterString = filterText; |
445 // Create filter descriptor | 479 // Create filter descriptor |
446 std::auto_ptr<CFilterElementHide> filter; | 480 std::auto_ptr<CFilterElementHide> filter; |
447 | 481 |
448 CString wholeFilterString = filterString; | 482 CString wholeFilterString = filterString; |
449 wchar_t separatorChar; | 483 wchar_t separatorChar; |
450 do | 484 do |
451 { | 485 { |
452 int chunkEnd = filterText.FindOneOf(L"+>"); | 486 int chunkEnd = filterText.FindOneOf(L"+>"); |
453 if (chunkEnd > 0) | 487 if (chunkEnd > 0) |
454 { | 488 { |
455 separatorChar = filterText.GetAt(chunkEnd); | 489 separatorChar = filterText.GetAt(chunkEnd); |
456 } | 490 } |
457 else | 491 else |
458 { | 492 { |
459 chunkEnd = filterText.GetLength(); | 493 chunkEnd = filterText.GetLength(); |
460 separatorChar = L'\0'; | 494 separatorChar = L'\0'; |
461 } | 495 } |
462 | 496 |
463 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 497 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); |
464 std::auto_ptr<CFilterElementHide> filterParent(filter); | 498 std::auto_ptr<CFilterElementHide> filterParent(filter); |
465 | 499 |
466 filter.reset(new CFilterElementHide(filterChunk)); | 500 filter.reset(new CFilterElementHide(filterChunk)); |
467 | 501 |
468 if (filterParent.get() != 0) | 502 if (filterParent.get() != 0) |
469 { | 503 { |
470 filter->m_predecessor.reset(filterParent.release()); | 504 filter->m_predecessor.reset(filterParent.release()); |
471 } | 505 } |
472 | 506 |
473 if (separatorChar != L'\0') // complex selector | 507 if (separatorChar != L'\0') // complex selector |
474 { | 508 { |
475 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 509 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); |
476 if (separatorChar == '+') | 510 if (separatorChar == '+') |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 id = bstrId; | 545 id = bstrId; |
512 } | 546 } |
513 | 547 |
514 CString classNames; | 548 CString classNames; |
515 CComBSTR bstrClassNames; | 549 CComBSTR bstrClassNames; |
516 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 550 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) |
517 { | 551 { |
518 classNames = bstrClassNames; | 552 classNames = bstrClassNames; |
519 } | 553 } |
520 | 554 |
521 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 555 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
522 { | 556 { |
523 // Search tag/id filters | 557 // Search tag/id filters |
524 if (!id.IsEmpty()) | 558 if (!id.IsEmpty()) |
525 { | 559 { |
526 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
agsNamed::const_iterator> idItEnum = | 560 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
agsNamed::const_iterator> idItEnum = |
527 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 561 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); |
528 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 ++) |
529 { | 563 { |
530 if (idIt->second.IsMatchFilterElementHide(pEl)) | 564 if (idIt->second.IsMatchFilterElementHide(pEl)) |
531 { | 565 { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 647 } |
614 | 648 |
615 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 649 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) |
616 { | 650 { |
617 ClearFilters(); | 651 ClearFilters(); |
618 bool isRead = false; | 652 bool isRead = false; |
619 CPluginClient* client = CPluginClient::GetInstance(); | 653 CPluginClient* client = CPluginClient::GetInstance(); |
620 | 654 |
621 // Parse hide string | 655 // Parse hide string |
622 int pos = 0; | 656 int pos = 0; |
623 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 657 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
624 { | 658 { |
625 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) |
626 { | 660 { |
627 CString filter((*it).c_str()); | 661 CString filter((*it).c_str()); |
628 // If the line is not commented out | 662 // If the line is not commented out |
629 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') | 663 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') |
630 { | 664 { |
631 int filterType = 0; | 665 int filterType = 0; |
632 | 666 |
633 // 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... |
645 } | 679 } |
646 } | 680 } |
647 } | 681 } |
648 | 682 |
649 return isRead; | 683 return isRead; |
650 } | 684 } |
651 | 685 |
652 void CPluginFilter::ClearFilters() | 686 void CPluginFilter::ClearFilters() |
653 { | 687 { |
654 // Clear filter maps | 688 // Clear filter maps |
655 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 689 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
656 { | 690 { |
657 for (int i = 0; i < 2; i++) | 691 for (int i = 0; i < 2; i++) |
658 { | 692 { |
659 for (int j = 0; j < 2; j++) | 693 for (int j = 0; j < 2; j++) |
660 { | 694 { |
661 m_filterMap[i][j].clear(); | 695 m_filterMap[i][j].clear(); |
662 } | 696 } |
663 m_filterMapDefault[i].clear(); | 697 m_filterMapDefault[i].clear(); |
664 } | 698 } |
665 | 699 |
666 m_elementHideTags.clear(); | 700 m_elementHideTags.clear(); |
667 m_elementHideTagsId.clear(); | 701 m_elementHideTagsId.clear(); |
668 m_elementHideTagsClass.clear(); | 702 m_elementHideTagsClass.clear(); |
669 } | 703 } |
670 } | 704 } |
671 | 705 |
672 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 |
673 { | 707 { |
674 CString srcCString = ToCString(src); | 708 std::wstring srcTrimmed = TrimString(src); |
675 srcCString.Trim(); | |
676 std::wstring srcTrimmed = ToWstring(srcCString); | |
677 | 709 |
678 // 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 |
679 // Therefore we just return | 711 // Therefore we just return |
680 if (srcTrimmed.empty()) | 712 if (srcTrimmed.empty()) |
681 { | 713 { |
682 return false; | 714 return false; |
683 } | 715 } |
684 CPluginSettings* settings = CPluginSettings::GetInstance(); | 716 CPluginSettings* settings = CPluginSettings::GetInstance(); |
685 | 717 |
686 CString type; | 718 CString type; |
(...skipping 14 matching lines...) Expand all Loading... |
701 if (addDebug) | 733 if (addDebug) |
702 { | 734 { |
703 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") | 735 DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") |
704 | 736 |
705 #ifdef ENABLE_DEBUG_RESULT | 737 #ifdef ENABLE_DEBUG_RESULT |
706 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); | 738 CPluginDebug::DebugResultBlocking(type, srcTrimmed, domain); |
707 #endif | 739 #endif |
708 } | 740 } |
709 return true; | 741 return true; |
710 } | 742 } |
| 743 #ifdef ENABLE_DEBUG_RESULT |
| 744 CPluginDebug::DebugResultIgnoring(type, srcTrimmed, domain); |
| 745 #endif |
711 return false; | 746 return false; |
712 } | 747 } |
LEFT | RIGHT |