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 // Returns attribute value and the bool flag which indicates whether the attri
bute is found. |
| 24 // For the cases like <some-tag on-some-event="do();"/> IE returns the value o
f 'on-some-event' |
| 25 // attribute as 'function(event){\ndo();\n}'. Our filters are not designed for
such |
| 26 // transformations, so this method retrives the value of (body) of /^.*?\{(bod
y)\}$/ as well. |
| 27 std::pair<std::wstring, bool> GetHtmlElementAttribute(IHTMLElement& htmlElemen
t, const ATL::CComBSTR& attributeName) |
| 28 { |
| 29 std::pair<std::wstring, bool> retResult; |
| 30 retResult.second = false; |
| 31 ATL::CComVariant vAttr; |
| 32 // Performs a property search that is not case-sensitive, |
| 33 // and returns an interpolated value if the property is found. |
| 34 LONG flags = 0; |
| 35 if (FAILED(htmlElement.getAttribute(attributeName, flags, &vAttr))) |
| 36 { |
| 37 return retResult; |
| 38 } |
| 39 // we set that attribute found but it's not necessary that we can retrieve i
ts value |
| 40 retResult.second = true; |
| 41 if (vAttr.vt == VT_BSTR && vAttr.bstrVal) |
| 42 { |
| 43 retResult.first.assign(vAttr.bstrVal); |
| 44 } |
| 45 else if (vAttr.vt == VT_I4) |
| 46 { |
| 47 retResult.first = std::to_wstring(vAttr.iVal); |
| 48 } |
| 49 else if (vAttr.vt == VT_DISPATCH) |
| 50 { |
| 51 wchar_t* toStringMethod = L"toString"; |
| 52 DISPID methodId = 0; |
| 53 if (FAILED(vAttr.pdispVal->GetIDsOfNames(/*must be null iid*/IID_NULL, &to
StringMethod, |
| 54 /*cNames*/1, LOCALE_SYSTEM_DEFAULT, &methodId))) |
| 55 { |
| 56 return retResult; |
| 57 } |
| 58 ATL::CComVariant variantFunctionAsString; // result of IDispatch::Invoke |
| 59 DISPID dispidNamed = DISPATCH_METHOD | DISPATCH_PROPERTYGET; |
| 60 DISPPARAMS dispparams; |
| 61 dispparams.rgvarg = &variantFunctionAsString; |
| 62 dispparams.cArgs = 1; |
| 63 dispparams.cNamedArgs = 1; |
| 64 dispparams.rgdispidNamedArgs = &dispidNamed; |
| 65 UINT ArgErr = 0; |
| 66 if (FAILED(vAttr.pdispVal->Invoke(methodId, /*must be null iid*/IID_NULL, |
| 67 LOCALE_SYSTEM_DEFAULT, dispidNamed, &dispparams, &variantFunctionAsStrin
g, /*exception info*/nullptr, |
| 68 &ArgErr))) |
| 69 { |
| 70 return retResult; |
| 71 } |
| 72 if (variantFunctionAsString.vt != VT_BSTR) |
| 73 { |
| 74 return retResult; |
| 75 } |
| 76 std::wstring functionAsString = variantFunctionAsString.bstrVal; |
| 77 auto bodyBeginsAt = functionAsString.find(L'{'); |
| 78 if (bodyBeginsAt == std::wstring::npos) |
| 79 { |
| 80 return retResult; |
| 81 } |
| 82 // eat spaces |
| 83 while (::iswspace(functionAsString[++bodyBeginsAt])); |
| 84 auto bodyEndsAt = functionAsString.rfind(L'}'); |
| 85 if (bodyEndsAt == std::wstring::npos || bodyEndsAt < bodyBeginsAt) |
| 86 { |
| 87 return retResult; |
| 88 } |
| 89 // eat spaces |
| 90 while(::iswspace(functionAsString[--bodyEndsAt])); |
| 91 retResult.first = functionAsString.substr(bodyBeginsAt, bodyEndsAt - bodyB
eginsAt + 1); |
| 92 } |
| 93 return retResult; |
| 94 } |
| 95 } |
| 96 |
20 // ============================================================================ | 97 // ============================================================================ |
21 // CFilterElementHideAttrSelector | 98 // CFilterElementHideAttrSelector |
22 // ============================================================================ | 99 // ============================================================================ |
23 | 100 |
24 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N
ONE), m_pos(POS_NONE), m_bstrAttr(NULL) | 101 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector() : m_type(TYPE_N
ONE), m_pos(POS_NONE), m_bstrAttr(NULL) |
25 { | 102 { |
26 } | 103 } |
27 | 104 |
28 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem
entHideAttrSelector& filter) | 105 CFilterElementHideAttrSelector::CFilterElementHideAttrSelector(const CFilterElem
entHideAttrSelector& filter) |
29 { | 106 { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 } | 342 } |
266 if (!foundMatch) | 343 if (!foundMatch) |
267 { | 344 { |
268 return false; | 345 return false; |
269 } | 346 } |
270 } | 347 } |
271 } | 348 } |
272 if (!m_tag.IsEmpty()) | 349 if (!m_tag.IsEmpty()) |
273 { | 350 { |
274 CComBSTR tagName; | 351 CComBSTR tagName; |
| 352 hr = pEl->get_tagName(&tagName); |
275 tagName.ToLower(); | 353 tagName.ToLower(); |
276 hr = pEl->get_tagName(&tagName); | |
277 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) | 354 if ((hr != S_OK) || (tagName != CComBSTR(m_tag))) |
278 { | 355 { |
279 return false; | 356 return false; |
280 } | 357 } |
281 } | 358 } |
282 | 359 |
283 // Check attributes | 360 // Check attributes |
284 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at
tributeSelectors.begin(); | 361 for (std::vector<CFilterElementHideAttrSelector>::const_iterator attrIt = m_at
tributeSelectors.begin(); |
285 attrIt != m_attributeSelectors.end(); ++ attrIt) | 362 attrIt != m_attributeSelectors.end(); ++ attrIt) |
286 { | 363 { |
287 CString value; | 364 ATL::CString value; |
288 bool attrFound = false; | 365 bool attrFound = false; |
289 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) | 366 if (attrIt->m_type == CFilterElementHideAttrType::STYLE) |
290 { | 367 { |
291 CComPtr<IHTMLStyle> pStyle; | 368 CComPtr<IHTMLStyle> pStyle; |
292 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) | 369 if (SUCCEEDED(pEl->get_style(&pStyle)) && pStyle) |
293 { | 370 { |
294 CComBSTR bstrStyle; | 371 CComBSTR bstrStyle; |
295 | 372 |
296 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) | 373 if (SUCCEEDED(pStyle->get_cssText(&bstrStyle)) && bstrStyle) |
297 { | 374 { |
(...skipping 14 matching lines...) Expand all Loading... |
312 } | 389 } |
313 else if (attrIt->m_type == CFilterElementHideAttrType::ID) | 390 else if (attrIt->m_type == CFilterElementHideAttrType::ID) |
314 { | 391 { |
315 CComBSTR bstrId; | 392 CComBSTR bstrId; |
316 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) | 393 if (SUCCEEDED(pEl->get_id(&bstrId)) && bstrId) |
317 { | 394 { |
318 value = bstrId; | 395 value = bstrId; |
319 attrFound = true; | 396 attrFound = true; |
320 } | 397 } |
321 } | 398 } |
322 else | 399 else |
323 { | 400 { |
324 CComVariant vAttr; | 401 auto attribute = GetHtmlElementAttribute(*pEl, attrIt->m_bstrAttr); |
325 if (SUCCEEDED(pEl->getAttribute(attrIt->m_bstrAttr, 0, &vAttr))) | 402 if (attrFound = attribute.second) |
326 { | 403 { |
327 attrFound = true; | 404 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 } | 405 } |
337 } | 406 } |
338 | 407 |
339 if (attrFound) | 408 if (attrFound) |
340 { | 409 { |
341 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) | 410 if (attrIt->m_pos == CFilterElementHideAttrPos::EXACT) |
342 { | 411 { |
343 // TODO: IE rearranges the style attribute completely. Figure out if any
thing can be done about it. | 412 // TODO: IE rearranges the style attribute completely. Figure out if any
thing can be done about it. |
344 if (value != attrIt->m_value) | 413 if (value != attrIt->m_value) |
345 return false; | 414 return false; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; | 497 m_contentMapText[CFilter::contentTypeSubdocument] = "SUBDOCUMENT"; |
429 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; | 498 m_contentMapText[CFilter::contentTypeStyleSheet] = "STYLESHEET"; |
430 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; | 499 m_contentMapText[CFilter::contentTypeXmlHttpRequest] = "XMLHTTPREQUEST"; |
431 | 500 |
432 ClearFilters(); | 501 ClearFilters(); |
433 } | 502 } |
434 | 503 |
435 | 504 |
436 bool CPluginFilter::AddFilterElementHide(CString filterText) | 505 bool CPluginFilter::AddFilterElementHide(CString filterText) |
437 { | 506 { |
438 | |
439 | |
440 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); | 507 DEBUG_FILTER("Input: " + filterText + " filterFile" + filterFile); |
441 | 508 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
442 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | |
443 { | 509 { |
444 | |
445 CString filterString = filterText; | 510 CString filterString = filterText; |
446 // Create filter descriptor | 511 // Create filter descriptor |
447 std::auto_ptr<CFilterElementHide> filter; | 512 std::auto_ptr<CFilterElementHide> filter; |
448 | 513 |
449 CString wholeFilterString = filterString; | 514 CString wholeFilterString = filterString; |
450 wchar_t separatorChar; | 515 wchar_t separatorChar; |
451 do | 516 do |
452 { | 517 { |
453 int chunkEnd = filterText.FindOneOf(L"+>"); | 518 int chunkEnd = filterText.FindOneOf(L"+>"); |
454 if (chunkEnd > 0) | 519 if (chunkEnd > 0) |
455 { | 520 { |
456 separatorChar = filterText.GetAt(chunkEnd); | 521 separatorChar = filterText.GetAt(chunkEnd); |
457 } | 522 } |
458 else | 523 else |
459 { | 524 { |
460 chunkEnd = filterText.GetLength(); | 525 chunkEnd = filterText.GetLength(); |
461 separatorChar = L'\0'; | 526 separatorChar = L'\0'; |
462 } | 527 } |
463 | 528 |
464 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); | 529 CString filterChunk = filterText.Left(chunkEnd).TrimRight(); |
465 std::auto_ptr<CFilterElementHide> filterParent(filter); | 530 std::auto_ptr<CFilterElementHide> filterParent(filter); |
466 | 531 |
467 filter.reset(new CFilterElementHide(filterChunk)); | 532 filter.reset(new CFilterElementHide(filterChunk)); |
468 | 533 |
469 if (filterParent.get() != 0) | 534 if (filterParent.get() != 0) |
470 { | 535 { |
471 filter->m_predecessor.reset(filterParent.release()); | 536 filter->m_predecessor.reset(filterParent.release()); |
472 } | 537 } |
473 | 538 |
474 if (separatorChar != L'\0') // complex selector | 539 if (separatorChar != L'\0') // complex selector |
475 { | 540 { |
476 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); | 541 filterText = filterText.Mid(chunkEnd + 1).TrimLeft(); |
477 if (separatorChar == '+') | 542 if (separatorChar == '+') |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 id = bstrId; | 577 id = bstrId; |
513 } | 578 } |
514 | 579 |
515 CString classNames; | 580 CString classNames; |
516 CComBSTR bstrClassNames; | 581 CComBSTR bstrClassNames; |
517 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) | 582 if (SUCCEEDED(pEl->get_className(&bstrClassNames)) && bstrClassNames) |
518 { | 583 { |
519 classNames = bstrClassNames; | 584 classNames = bstrClassNames; |
520 } | 585 } |
521 | 586 |
522 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 587 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
523 { | 588 { |
524 // Search tag/id filters | 589 // Search tag/id filters |
525 if (!id.IsEmpty()) | 590 if (!id.IsEmpty()) |
526 { | 591 { |
527 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
agsNamed::const_iterator> idItEnum = | 592 std::pair<TFilterElementHideTagsNamed::const_iterator, TFilterElementHideT
agsNamed::const_iterator> idItEnum = |
528 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); | 593 m_elementHideTagsId.equal_range(std::make_pair(tagCString, id)); |
529 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id
It != idItEnum.second; idIt ++) | 594 for (TFilterElementHideTagsNamed::const_iterator idIt = idItEnum.first; id
It != idItEnum.second; idIt ++) |
530 { | 595 { |
531 if (idIt->second.IsMatchFilterElementHide(pEl)) | 596 if (idIt->second.IsMatchFilterElementHide(pEl)) |
532 { | 597 { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 } | 679 } |
615 | 680 |
616 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) | 681 bool CPluginFilter::LoadHideFilters(std::vector<std::wstring> filters) |
617 { | 682 { |
618 ClearFilters(); | 683 ClearFilters(); |
619 bool isRead = false; | 684 bool isRead = false; |
620 CPluginClient* client = CPluginClient::GetInstance(); | 685 CPluginClient* client = CPluginClient::GetInstance(); |
621 | 686 |
622 // Parse hide string | 687 // Parse hide string |
623 int pos = 0; | 688 int pos = 0; |
624 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); | 689 CriticalSection::Lock filterEngineLock(s_criticalSectionFilterMap); |
625 { | 690 { |
626 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.
end(); ++it) | 691 for (std::vector<std::wstring>::iterator it = filters.begin(); it < filters.
end(); ++it) |
627 { | 692 { |
628 CString filter((*it).c_str()); | 693 CString filter((*it).c_str()); |
629 // If the line is not commented out | 694 // If the line is not commented out |
630 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') | 695 if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0)
!= '[') |
631 { | 696 { |
632 int filterType = 0; | 697 int filterType = 0; |
633 | 698 |
634 // See http://adblockplus.org/en/filters for further documentation | 699 // 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); | 771 CPluginDebug::DebugResultBlocking(type, srcCString, domain); |
707 #endif | 772 #endif |
708 } | 773 } |
709 return true; | 774 return true; |
710 } | 775 } |
711 #ifdef ENABLE_DEBUG_RESULT | 776 #ifdef ENABLE_DEBUG_RESULT |
712 CPluginDebug::DebugResultIgnoring(type, srcCString, domain); | 777 CPluginDebug::DebugResultIgnoring(type, srcCString, domain); |
713 #endif | 778 #endif |
714 return false; | 779 return false; |
715 } | 780 } |
OLD | NEW |