Left: | ||
Right: |
OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |