Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginFilter.cpp

Issue 6433575100481536: Issue 1148 - ABP on chrome blocks ads but IE doesnt (Closed)
Patch Set: fix IE8 and simplify the code Created Nov. 10, 2014, 3:32 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/plugin/PluginUtil.h » ('j') | src/plugin/PluginUtil.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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;
19 20
21 namespace
22 {
23 std::wstring GetAttributeValueAsString(const ATL::CComVariant& vAttr)
Oleksandr 2014/11/19 03:24:23 Is it really required for this to be a separate fu
sergei 2014/11/19 11:53:24 It's not required. Firstly I extracted it during d
24 {
25 if (vAttr.vt == VT_BSTR && vAttr.bstrVal)
26 {
27 return vAttr.bstrVal;
28 }
29 else if (vAttr.vt == VT_I4)
30 {
31 return std::to_wstring(vAttr.iVal);
32 }
33 return std::wstring();
34 }
35
36 std::pair<std::wstring, bool> GetHtmlElementAttribute(IHTMLElement& htmlElemen t, const ATL::CComBSTR& attributeName)
Oleksandr 2014/11/19 03:24:23 How about something like this instead std::wstring
sergei 2014/11/19 11:53:24 - I don't think that making `htmlElement` to be po
Oleksandr 2014/11/20 10:21:56 - I think it is inconsistent. We use pointers for
sergei 2014/11/21 12:02:21 In the function we need to check that it's not nul
Felix Dahlke 2014/11/26 14:23:16 I agree with Sergei here, IMO we should go with re
37 {
38 std::pair<std::wstring, bool> retResult;
39 retResult.second = false;
40 ATL::CComVariant vAttr;
41 ATL::CComQIPtr<IHTMLElement4> htmlElement4 = &htmlElement;
Oleksandr 2014/11/19 03:24:23 I prefer manually calling QueryInterface. We are c
sergei 2014/11/19 11:53:24 We don't need HRESULT here, so I would say that AT
Oleksandr 2014/11/20 10:21:56 We do QueryInterface in a lot of places in the cod
42 if (!htmlElement4)
43 {
44 return retResult;
45 }
46 ATL::CComPtr<IHTMLDOMAttribute> attributeNode;
47 if (FAILED(htmlElement4->getAttributeNode(attributeName, &attributeNode)) || !attributeNode)
48 {
49 return retResult;
50 }
51 // we set that attribute found but it's not necessary that we can retrieve i ts value
52 retResult.second = true;
53 if (FAILED(attributeNode->get_nodeValue(&vAttr)))
54 {
55 return retResult;
56 }
57 retResult.first = GetAttributeValueAsString(vAttr);
58 return retResult;
59 }
60 }
61
20 // ============================================================================ 62 // ============================================================================
21 // CFilterElementHideAttrSelector 63 // CFilterElementHideAttrSelector
22 // ============================================================================ 64 // ============================================================================
23 65
24 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL) 66 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N ONE), m_pos(POS_NONE), m_bstrAttr(NULL)
25 { 67 {
26 } 68 }
27 69
28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter) 70 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem entHideAttrSelector& filter)
29 { 71 {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 307 }
266 if (!foundMatch) 308 if (!foundMatch)
267 { 309 {
268 return false; 310 return false;
269 } 311 }
270 } 312 }
271 } 313 }
272 if (!m_tag.IsEmpty()) 314 if (!m_tag.IsEmpty())
273 { 315 {
274 CComBSTR tagName; 316 CComBSTR tagName;
317 hr = pEl->get_tagName(&tagName);
Oleksandr 2014/11/19 03:24:23 Well this was a long living bug :D. Nice!
275 tagName.ToLower(); 318 tagName.ToLower();
276 hr = pEl->get_tagName(&tagName);
277 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) 319 if ((hr != S_OK) || (tagName != CComBSTR(m_tag)))
278 { 320 {
279 return false; 321 return false;
280 } 322 }
281 } 323 }
282 324
283 // Check attributes 325 // Check attributes
284 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin(); 326 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at tributeSelectors.begin();
285 attrIt != m_attributeSelectors.end(); ++ attrIt) 327 attrIt != m_attributeSelectors.end(); ++ attrIt)
286 { 328 {
287 CString value; 329 ATL::CString value;
288 bool attrFound = false; 330 bool attrFound = false;
289 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) 331 if (attrIt->m_type == CFilterElementHideAttrType::STYLE)
290 { 332 {
291 CComPtr<IHTMLStyle> pStyle; 333 CComPtr<IHTMLStyle> pStyle;
292 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) 334 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle)
293 { 335 {
294 CComBSTR bstrStyle; 336 CComBSTR bstrStyle;
295 337
296 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) 338 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle)
297 { 339 {
(...skipping 14 matching lines...) Expand all
312 } 354 }
313 else if (attrIt->m_type == CFilterElementHideAttrType::ID) 355 else if (attrIt->m_type == CFilterElementHideAttrType::ID)
314 { 356 {
315 CComBSTR bstrId; 357 CComBSTR bstrId;
316 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) 358 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId)
317 { 359 {
318 value = bstrId; 360 value = bstrId;
319 attrFound = true; 361 attrFound = true;
320 } 362 }
321 } 363 }
322 else 364 else
323 { 365 {
324 CComVariant vAttr; 366 auto attribute = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr);
325 if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) 367 if (attrFound = attribute.second)
326 { 368 {
327 attrFound = true; 369 value = ToCString(attribute.first);
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 } 370 }
337 } 371 }
338 372
339 if (attrFound) 373 if (attrFound)
340 { 374 {
341 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) 375 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT)
342 { 376 {
343 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it. 377 // TODO: IE rearranges the style attribute completely. Figure out if any thing can be done about it.
344 if (value != attrIt->m_value) 378 if (value != attrIt->m_value)
345 return false; 379 return false;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; 462 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT";
429 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; 463 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET";
430 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; 464 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST";
431 465
432 ClearFilters(); 466 ClearFilters();
433 } 467 }
434 468
435 469
436 bool CPluginFilter::AddFilterElementHide(CString filterText) 470 bool CPluginFilter::AddFilterElementHide(CString filterText)
437 { 471 {
438
439
440 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); 472 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile);
441 473 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
442 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
443 { 474 {
444
445 CString filterString = filterText; 475 CString filterString = filterText;
446 // Create filter descriptor 476 // Create filter descriptor
447 std::auto_ptr<CFilterElementHide> filter; 477 std::auto_ptr<CFilterElementHide> filter;
448 478
449 CString wholeFilterString = filterString; 479 CString wholeFilterString = filterString;
450 wchar_t separatorChar; 480 wchar_t separatorChar;
451 do 481 do
452 { 482 {
453 int chunkEnd = filterText.FindOneOf(L"+>"); 483 int chunkEnd = filterText.FindOneOf(L"+>");
454 if (chunkEnd > 0) 484 if (chunkEnd > 0)
455 { 485 {
456 separatorChar = filterText.GetAt(chunkEnd); 486 separatorChar = filterText.GetAt(chunkEnd);
457 } 487 }
458 else 488 else
459 { 489 {
460 chunkEnd = filterText.GetLength(); 490 chunkEnd = filterText.GetLength();
461 separatorChar = L'\0'; 491 separatorChar = L'\0';
462 } 492 }
463 493
464 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); 494 CString filterChunk = filterText.Left(chunkEnd).TrimRight();
465 std::auto_ptr<CFilterElementHide> filterParent(filter); 495 std::auto_ptr<CFilterElementHide> filterParent(filter);
466 496
467 filter.reset(new CFilterElementHide(filterChunk)); 497 filter.reset(new CFilterElementHide(filterChunk));
468 498
469 if (filterParent.get() != 0) 499 if (filterParent.get() != 0)
470 { 500 {
471 filter->m_predecessor.reset(filterParent.release()); 501 filter->m_predecessor.reset(filterParent.release());
472 } 502 }
473 503
474 if (separatorChar != L'\0') // complex selector 504 if (separatorChar != L'\0') // complex selector
475 { 505 {
476 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); 506 filterText = filterText.Mid(chunkEnd + 1).TrimLeft();
477 if (separatorChar == '+') 507 if (separatorChar == '+')
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 id = bstrId; 542 id = bstrId;
513 } 543 }
514 544
515 CString classNames; 545 CString classNames;
516 CComBSTR bstrClassNames; 546 CComBSTR bstrClassNames;
517 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) 547 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames)
518 { 548 {
519 classNames = bstrClassNames; 549 classNames = bstrClassNames;
520 } 550 }
521 551
522 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 552 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
523 { 553 {
524 // Search tag/id filters 554 // Search tag/id filters
525 if (!id.IsEmpty()) 555 if (!id.IsEmpty())
526 { 556 {
527 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum = 557 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT agsNamed::const_iterator> idItEnum =
528 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); 558 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id));
529 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++) 559 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id It != idItEnum.second; idIt ++)
530 { 560 {
531 if (idIt->second.IsMatchFilterElementHide(pEl)) 561 if (idIt->second.IsMatchFilterElementHide(pEl))
532 { 562 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 } 644 }
615 645
616 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) 646 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters)
617 { 647 {
618 ClearFilters(); 648 ClearFilters();
619 bool isRead = false; 649 bool isRead = false;
620 CPluginClient* client = CPluginClient::GetInstance(); 650 CPluginClient* client = CPluginClient::GetInstance();
621 651
622 // Parse hide string 652 // Parse hide string
623 int pos = 0; 653 int pos = 0;
624 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); 654 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap);
625 { 655 {
626 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it) 656 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters. end(); ++it)
627 { 657 {
628 CString filter((*it).c_str()); 658 CString filter((*it).c_str());
629 // If the line is not commented out 659 // If the line is not commented out
630 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') 660 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[')
631 { 661 {
632 int filterType = 0; 662 int filterType = 0;
633 663
634 // See http://adblockplus.org/en/filters for further documentation 664 // See http://adblockplus.org/en/filters for further documentation
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 CPluginDebug::DebugResultBlocking(type, srcCString, domain); 736 CPluginDebug::DebugResultBlocking(type, srcCString, domain);
707 #endif 737 #endif
708 } 738 }
709 return true; 739 return true;
710 } 740 }
711 #ifdef ENABLE_DEBUG_RESULT 741 #ifdef ENABLE_DEBUG_RESULT
712 CPluginDebug::DebugResultIgnoring(type, srcCString, domain); 742 CPluginDebug::DebugResultIgnoring(type, srcCString, domain);
713 #endif 743 #endif
714 return false; 744 return false;
715 } 745 }
OLDNEW
« no previous file with comments | « no previous file | src/plugin/PluginUtil.h » ('j') | src/plugin/PluginUtil.h » ('J')

Powered by Google App Engine
This is Rietveld