Index: Shared/PluginFilter.cpp |
=================================================================== |
--- a/Shared/PluginFilter.cpp |
+++ b/Shared/PluginFilter.cpp |
@@ -80,14 +80,13 @@ |
// CFilterElementHide |
// ============================================================================ |
-CFilterElementHide::CFilterElementHide(const CString& filterText, const CString& filterFile) : m_filterText(filterText), m_filterFile(filterFile) |
+CFilterElementHide::CFilterElementHide(const CString& filterText) : m_filterText(filterText) |
{ |
} |
CFilterElementHide::CFilterElementHide(const CFilterElementHide& filter) |
{ |
m_filterText = filter.m_filterText; |
- m_filterFile = filter.m_filterFile; |
m_tagId = filter.m_tagId; |
m_tagClassName = filter.m_tagClassName; |
@@ -117,7 +116,6 @@ |
m_stringElements = filter.m_stringElements; |
m_filterText = filter.m_filterText; |
- m_filterFile = filter.m_filterFile; |
m_domains = filter.m_domains; |
m_domainsNot = filter.m_domainsNot; |
@@ -136,7 +134,7 @@ |
// CPluginFilter |
// ============================================================================ |
-CPluginFilter::CPluginFilter(const TFilterFileList& list, const CString& dataPath) : m_dataPath(dataPath) |
+CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) |
{ |
m_contentMap["document"] = CFilter::contentTypeDocument; |
m_contentMap["subdocument"] = CFilter::contentTypeSubdocument; |
@@ -163,16 +161,11 @@ |
m_contentMapText[CFilter::contentTypeSubdocument] = "iframe"; |
m_contentMapText[CFilter::contentTypeStyleSheet] = "css"; |
- ParseFilters(list); |
+ ClearFilters(); |
} |
-CPluginFilter::CPluginFilter(const CString& dataPath) : m_dataPath(dataPath) |
-{ |
-} |
- |
- |
-bool CPluginFilter::AddFilterElementHide(CString filterText, CString filterFile) |
+bool CPluginFilter::AddFilterElementHide(CString filterText) |
{ |
int delimiterPos = filterText.Find(L"#"); |
if (delimiterPos < 0 || filterText.GetLength() <= delimiterPos + 1) |
@@ -190,7 +183,7 @@ |
s_criticalSectionFilterMap.Lock(); |
{ |
// Create filter descriptor |
- CFilterElementHide filter(filterText, filterFile); |
+ CFilterElementHide filter(filterText); |
CString filterDomains = filterText.Left(delimiterPos).MakeLower(); |
CString filterString = filterText.Right(filterText.GetLength() - delimiterPos - (isOldFormat ? 1 : 2)); |
@@ -644,22 +637,22 @@ |
if (!id.IsEmpty() && !classNames.IsEmpty()) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText); |
} |
else if (!id.IsEmpty()) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "id:" + id, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "id:" + id, filterIt->second.m_filterText); |
} |
else if (!classNames.IsEmpty()) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "class:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "class:" + classNames, filterIt->second.m_filterText); |
} |
else |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "-" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "-" + classNames, filterIt->second.m_filterText); |
} |
} |
#endif |
@@ -682,12 +675,12 @@ |
if (!id.IsEmpty()) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "id:" + id + " class:" + classNames, filterIt->second.m_filterText); |
} |
else |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (domain) filter:" + filterIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "-" + classNames, filterIt->second.m_filterText, filterIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "-" + classNames, filterIt->second.m_filterText); |
} |
} |
#endif |
@@ -722,7 +715,7 @@ |
if (isHidden) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (tag/id) filter:" + idIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filterText, idIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filterText); |
} |
#endif |
} |
@@ -738,7 +731,7 @@ |
if (isHidden) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (?/id) filter:" + idIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filterText, idIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "id:" + id, idIt->second.m_filterText); |
} |
#endif |
} |
@@ -761,7 +754,7 @@ |
if (isHidden) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (tag/class) filter:" + classIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt->second.m_filterText, classIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt->second.m_filterText); |
} |
#endif |
} |
@@ -777,7 +770,7 @@ |
if (isHidden) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (?/class) filter:" + classIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt->second.m_filterText, classIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "class:" + className, classIt->second.m_filterText); |
} |
#endif |
} |
@@ -799,7 +792,7 @@ |
if (isHidden) |
{ |
DEBUG_HIDE_EL(indent + "HideEl::Found (tag) filter:" + tagIt->second.m_filterText) |
- CPluginDebug::DebugResultHiding(tag, "-", tagIt->second.m_filterText, tagIt->second.m_filterFile); |
+ CPluginDebug::DebugResultHiding(tag, "-", tagIt->second.m_filterText); |
} |
#endif |
} |
@@ -810,646 +803,74 @@ |
return isHidden; |
} |
- |
-void CPluginFilter::AddFilter(CString filterString, CString filterFile, int filterType) |
-{ |
- //We don't accept too short filters. Those are suspicious. |
- if (filterString.GetLength() < 5) |
- return; |
- |
- CString raw = filterString; |
- |
- // Here we should find a key for the filter |
- // We find a string of max 8 characters that does not contain any wildcards and which are unique for the filter |
- |
- // Find settings part, identified by $ |
- CString filterSettings; |
- |
- int pos = filterString.Find('$'); |
- if (pos > 0) |
- { |
- filterSettings = filterString.Right(filterString.GetLength() - pos - 1); |
- filterString = filterString.Left(pos); |
- } |
- |
- // Split filterString to parts |
- |
- bool bCheckFromStartDomain = false; |
- if (filterString.Find(L"||") == 0) |
- { |
- bCheckFromStartDomain = true; |
- filterString = filterString.Right(filterString.GetLength() - 2); |
- } |
- |
- bool bCheckFromStart = false; |
- if (filterString.GetAt(0) == '|') |
- { |
- bCheckFromStart = true; |
- filterString = filterString.Right(filterString.GetLength() - 1); |
- } |
- |
- bool bCheckFromEnd = false; |
- if (filterString.Right(1) == "|") |
- { |
- bCheckFromEnd = true; |
- filterString = filterString.Left(filterString.GetLength() - 1); |
- } |
- |
- std::vector<CString> filterParts; |
- pos = 0; |
- |
- while ((pos = filterString.Find('*')) >= 0) |
- { |
- if (pos > 0) |
- { |
- filterParts.push_back(filterString.Left(pos)); |
- } |
- filterString = filterString.Right(filterString.GetLength() - pos - 1); |
- } |
- |
- if (!filterString.IsEmpty()) |
- { |
- filterParts.push_back(filterString); |
- } |
- |
- TFilterMap* filterMap = m_filterMap[filterType]; |
- |
- // Define hash key |
- DWORD dwKey = 0; |
- DWORD dwKeyMap = 0; |
- |
- int keyLength = 4; |
- int startCharacter = 0; |
- if (filterParts.size() < 1) |
- { |
- return; |
- } |
- CString filterPart = filterParts[0]; |
- filterPart.MakeLower(); |
- |
- int nFilterParts = filterParts.size(); |
- int nFilterPart = 0; |
- |
- int filterPartLength = filterPart.GetLength(); |
- |
- if (filterPartLength >= 7) |
- { |
- if (filterPart.Find(L"http://") == 0) |
- { |
- startCharacter = 7; |
- } |
- else if (filterPart.Find(L"https://") == 0) |
- { |
- startCharacter = 8; |
- } |
- } |
- |
- while (true) |
- { |
- // Part is too short as unique key? - try next filter part |
- while (filterPartLength < startCharacter + keyLength) |
- { |
- nFilterPart++; |
- if (nFilterPart >= nFilterParts) |
- { |
- break; |
- } |
- |
- filterPart = filterParts[nFilterPart]; |
- filterPart.MakeLower(); |
- filterPartLength = filterPart.GetLength(); |
- |
- startCharacter = 0; |
- } |
- |
- if (nFilterPart >= nFilterParts) |
- { |
- break; |
- } |
- |
- int posSpecial = filterPart.Find('^', startCharacter); |
- if (posSpecial >= 0 && posSpecial < startCharacter + keyLength) |
- { |
- startCharacter = posSpecial + 1; |
- } |
- else |
- { |
- // Try key |
- DWORD dwTestKey = (filterPart.GetAt(startCharacter) << 24) | (filterPart.GetAt(startCharacter+1) << 16) | (filterPart.GetAt(startCharacter+2) << 8) | filterPart.GetAt(startCharacter+3); |
- |
- // Now we have a substring which we can check |
- if (filterMap[0].find(dwTestKey) == filterMap[0].end()) |
- { |
- dwKey = dwTestKey; |
- dwKeyMap = 0; |
- break; |
- } |
- |
- // We already had a match - increment the start character |
- startCharacter++; |
- } |
- } |
- |
- // Try second list |
- if (dwKey == 0) |
- { |
- dwKeyMap = 1; |
- |
- startCharacter = 0; |
- |
- filterPart = filterParts[0]; |
- filterPart.MakeLower(); |
- filterPartLength = filterPart.GetLength(); |
- |
- nFilterPart = 0; |
- |
- if (filterPartLength >= 7) |
- { |
- if (filterPart.Find(L"http://") == 0) |
- { |
- startCharacter = 7; |
- } |
- else if (filterPart.Find(L"https://") == 0) |
- { |
- startCharacter = 8; |
- } |
- } |
- |
- while (true) |
- { |
- // Part is too short as unique key? - try next filter part |
- while (filterPartLength < startCharacter + keyLength) |
- { |
- nFilterPart++; |
- if (nFilterPart >= nFilterParts) |
- { |
- break; |
- } |
- |
- filterPart = filterParts[nFilterPart]; |
- filterPart.MakeLower(); |
- filterPartLength = filterPart.GetLength(); |
- |
- startCharacter = 0; |
- } |
- |
- if (nFilterPart >= nFilterParts) |
- { |
- break; |
- } |
- |
- int posSpecial = filterPart.Find('^', startCharacter); |
- if (posSpecial >= 0 && posSpecial < startCharacter + keyLength) |
- { |
- startCharacter = posSpecial + 1; |
- } |
- else |
- { |
- // Try key |
- DWORD dwTestKey = (filterPart.GetAt(startCharacter) << 24) | (filterPart.GetAt(startCharacter+1) << 16) | (filterPart.GetAt(startCharacter+2) << 8) | filterPart.GetAt(startCharacter+3); |
- |
- // Now we have a substring which we can check |
- if (filterMap[1].find(dwTestKey) == filterMap[1].end()) |
- { |
- dwKey = dwTestKey; |
- break; |
- } |
- |
- // We already had a match - increment the start character |
- startCharacter++; |
- } |
- } |
- } |
- |
- // Create the filter |
- CFilter filter; |
- filter.m_filterType = CFilter::filterTypeBlocking; |
- filter.m_stringElements = filterParts; |
- filter.m_isFromStart = bCheckFromStart; |
- filter.m_isFromStartDomain = bCheckFromStartDomain; |
- filter.m_isFromEnd = bCheckFromEnd; |
- filter.m_filterText = raw; |
- filter.m_filterFile = filterFile; |
- |
- // Set content type of filter and other settings |
- if (!filterSettings.IsEmpty()) |
- { |
- // Split filterSettings to parts |
- pos = 0; |
- bool hasContent = false; |
- |
- while ((pos = filterSettings.Find(',')) >= 0 || !filterSettings.IsEmpty()) |
- { |
- CString setting = pos >= 0 ? filterSettings.Left(pos) : filterSettings; |
- filterSettings = pos >= 0 ? filterSettings.Right(filterSettings.GetLength() - pos - 1) : ""; |
- |
- // Is content type negated |
- bool bNegate = false; |
- if (setting.GetAt(0) == '~') |
- { |
- bNegate = true; |
- setting = setting.Right(setting.GetLength() - 1); |
- } |
- |
- // Apply content type |
- std::map<CString, int>::iterator it = m_contentMap.find(setting); |
- if (it != m_contentMap.end()) |
- { |
- if (!hasContent) |
- { |
- if (bNegate) |
- { |
- filter.m_contentType = ~it->second; |
- } |
- else |
- { |
- filter.m_contentType = it->second; |
- } |
- hasContent = true; |
- } |
- else if (bNegate) |
- { |
- filter.m_contentType &= ~it->second; |
- } |
- else |
- { |
- filter.m_contentType |= it->second; |
- } |
- } |
- else if (setting == "match-case") |
- { |
- filter.m_isMatchCase = true; |
- } |
- else if (setting == "third-party") |
- { |
- if (bNegate) |
- { |
- filter.m_isFirstParty = true; |
- } |
- else |
- { |
- filter.m_isThirdParty = true; |
- } |
- } |
- else if (setting.Left(7) == "domain=") |
- { |
- int posDomain = 0; |
- setting = setting.Right(setting.GetLength() - 7); |
- |
- while ((posDomain = setting.Find('|')) >= 0 || !setting.IsEmpty()) |
- { |
- CString domain = posDomain >= 0 ? setting.Left(posDomain) : setting; |
- setting = posDomain >= 0 ? setting.Right(setting.GetLength() - posDomain - 1) : ""; |
- |
- if (domain.GetAt(0) == '~') |
- { |
- domain = domain.Right(domain.GetLength() - 1); |
- |
- filter.m_domainsNot.insert(domain); |
- } |
- else |
- { |
- filter.m_domains.insert(domain); |
- } |
- } |
- } |
- else |
- { |
- DEBUG_FILTER("Filter::Error parsing filter:" + filterFile + "/" + raw + " (unhandled tag: " + setting + ")") |
- return; |
- } |
- } |
- } |
- |
- // Add the filter |
- if (dwKey != 0) |
- { |
- filterMap[dwKeyMap][dwKey] = filter; |
- } |
- else |
- { |
- m_filterMapDefault[filterType].push_back(filter); |
- } |
-} |
- |
-#ifdef PRODUCT_ADBLOCKPLUS |
- |
-bool CPluginFilter::DownloadFilterFile(const CString& url, const CString& filename) |
-{ |
- CString tempFile = CPluginSettings::GetTempFile(TEMP_FILE_PREFIX); |
- |
- DEBUG_GENERAL("*** Downloading filter file:" + filename + " (to " + tempFile + ")"); |
- |
- bool bResult = !tempFile.IsEmpty(); |
- if (bResult) |
- { |
- // if new filter urls are found download them and update the persistent data |
- HRESULT hr = ::URLDownloadToFile(NULL, url, tempFile, 0, NULL); |
- if (SUCCEEDED(hr)) |
- { |
- CPluginFilterLock lock(filename); |
- if (lock.IsLocked()) |
- { |
- // Move the temporary file to the new text file. |
- if (!::MoveFileEx(tempFile, CPluginSettings::GetDataPath(filename), MOVEFILE_REPLACE_EXISTING)) |
- { |
- DWORD dwError = ::GetLastError(); |
- |
- // Not same device? copy/delete instead |
- if (dwError == ERROR_NOT_SAME_DEVICE) |
- { |
- if (!::CopyFile(tempFile, CPluginSettings::GetDataPath(filename), FALSE)) |
- { |
- DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_COPY_FILE, "Filter::Unable to copy file:" + filename) |
- |
- bResult = false; |
- } |
- |
- ::DeleteFile(tempFile); |
- } |
- else |
- { |
- DEBUG_ERROR_LOG(dwError, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_MOVE_FILE, "Filter::Unable to replace file:" + filename) |
- |
- bResult = false; |
- } |
- } |
- } |
- else |
- { |
- bResult = false; |
- } |
- } |
- else |
- { |
- DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_DOWNLOAD_FILE, "Filter::Unable to download file: " + filename) |
- |
- bResult = false; |
- } |
- } |
- |
- return bResult; |
-} |
- |
-#endif |
- |
-bool CPluginFilter::ReadFilter(const CString& filename, const CString& downloadPath) |
+bool CPluginFilter::LoadHideFilters(std::vector<std::string> filters) |
{ |
bool isRead = false; |
#ifdef PRODUCT_ADBLOCKPLUS |
CPluginClient* client = CPluginClient::GetInstance(); |
#endif |
- CString fileContent; |
-#ifdef PRODUCT_ADBLOCKPLUS |
- CPluginFilterLock lock(filename); |
- if (lock.IsLocked()) |
+ // Parse hide string |
+ int pos = 0; |
+ |
+ s_criticalSectionFilterMap.Lock(); |
{ |
-#endif |
- DEBUG_GENERAL("*** Loading filter:" + m_dataPath + filename); |
+ for (std::vector<std::string>::iterator it = filters.begin(); it < filters.end(); ++it) |
+ { |
+ CString filter((*it).c_str()); |
+ // If the line is not commented out |
+ if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') |
Wladimir Palant
2013/04/03 12:42:19
I think you can assume that the filter engine will
|
+ { |
+ int filterType = 0; |
- //Rename old filter file if exists |
- if (filename == PERSONAL_FILTER_FILE) |
- { |
- HANDLE hFile = ::CreateFile(m_dataPath + PERSONAL_FILTER_FILE_OLD, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
- if (hFile != INVALID_HANDLE_VALUE) |
- { |
- CloseHandle(hFile); |
- int res = _wrename(m_dataPath + PERSONAL_FILTER_FILE_OLD, m_dataPath + filename); |
- DWORD err = GetLastError(); |
- err = 0; |
- } |
- } |
+ // We need to categorize the filters |
+ // We have three options, whitelist, block or element hiding |
+ // See http://adblockplus.org/en/filters for further documentation |
- // Read file |
- HANDLE hFile = ::CreateFile(m_dataPath + filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
- if (hFile == INVALID_HANDLE_VALUE) |
- { |
- DWORD dwError = ::GetLastError(); |
-#ifdef PRODUCT_ADBLOCKPLUS |
- // File not found - request another download! |
- if (dwError == ERROR_FILE_NOT_FOUND) |
- { |
- if (!downloadPath.IsEmpty()) |
+ // @@ indicates white listing rule |
+ if (filter.Find(L"@@") == 0) |
{ |
- client->RequestFilterDownload(filename, downloadPath); |
+ filterType = CFilter::filterTypeWhiteList; |
+ |
+ filter.Delete(0, 2); |
} |
- else if (filename == PERSONAL_FILTER_FILE) |
+ // If a filter contains ## then it is a element hiding rule |
+ else if (filter.Find(L"#") >= 0) |
{ |
- // Open new file |
- HANDLE hPersonalFile = ::CreateFile(CPluginSettings::GetDataPath(PERSONAL_FILTER_FILE), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
- if (hPersonalFile) |
- { |
- // Build filter string |
- CStringA line; |
+ filterType = CFilter::filterTypeElementHide; |
+ } |
+ //Anything we do not support here |
+ else if (filter.Find(L"*") == 0) |
+ { |
+ filterType = CFilter::filterTypeUnknown; |
+ } |
+ // Else, it is a general rule |
+ else |
+ { |
+ filterType = CFilter::filterTypeBlocking; |
+ } |
- line += "[Adblock Plus - personal filters]\r\n"; |
- line += "!\r\n"; |
- line += "! In this file you can enter your own filters.\r\n"; |
- line += "! Any updates to this file\r\n"; |
- line += "! will take effect the next time a new tab or window is opened in\r\n"; |
- line += "! Internet Explorer.\r\n"; |
- line += "!\r\n"; |
- line += "! To define filters you should use the adblockplus format, described on:\r\n"; |
- line += "! http://adblockplus.org/en/filters\r\n"; |
- line += "!\r\n"; |
- line += "! File encoding: ANSI\r\n"; |
- line += "!\r\n"; |
- line += "!-------------------------Ad blocking rules--------------------------!\r\n"; |
- |
- // Write file |
- DWORD dwBytesWritten = 0; |
- ::WriteFile(hPersonalFile, line.GetBuffer(), line.GetLength(), &dwBytesWritten, NULL); |
- |
- // Close file |
- ::CloseHandle(hPersonalFile); |
+ try |
+ { |
+ if (filterType == CFilter::filterTypeElementHide) |
+ { |
+ AddFilterElementHide(filter); |
} |
} |
- } |
- else |
-#endif |
- { |
- DEBUG_ERROR_LOG(dwError, PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_READ_FILE, "Filter::ParseFilters - Open file:" + filename) |
- } |
- } |
- else |
- { |
- // Read file |
- char buffer[8193]; |
- LPVOID pBuffer = buffer; |
- LPBYTE pByteBuffer = (LPBYTE)pBuffer; |
- DWORD dwBytesRead = 0; |
- BOOL bRead = TRUE; |
- |
- //Init MLang |
- CoInitialize(NULL); |
- HRESULT hr = S_OK; |
- CComPtr<IMultiLanguage2> pMultiLanguage; |
- hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (void**)&pMultiLanguage); |
- |
- |
- bool codepageAvailable = false; |
- DetectEncodingInfo encodingInfos[10]; |
- int scores = 10; |
- while ((bRead = ::ReadFile(hFile, pBuffer, 8192, &dwBytesRead, NULL)) == TRUE && dwBytesRead > 0) |
- { |
- //detect codepage based on first buffer |
- if (!codepageAvailable) |
+ catch(...) |
{ |
- unsigned int srcLength = fileContent.GetLength(); |
- char* buf = (char*)fileContent.GetBufferSetLength(fileContent.GetLength()); |
- hr = pMultiLanguage->DetectInputCodepage(0, 0, (char*)pBuffer, (int*)&dwBytesRead, encodingInfos, &scores); |
- codepageAvailable = true; |
- } |
- |
- |
- |
- //Unicode |
- if ((encodingInfos[0].nCodePage == 1200) || (encodingInfos[0].nCodePage == 1201)) |
- { |
- fileContent += CString((wchar_t*)buffer, dwBytesRead / 2); |
- } |
- else |
- { |
- pByteBuffer[dwBytesRead] = 0; |
- fileContent += buffer; |
- } |
- } |
- |
- //Remove the BOM for UTF-8 |
- if (((BYTE)fileContent.GetAt(0) == 0x3F) && ((BYTE)fileContent.GetAt(1) == 0xBB) && ((BYTE)fileContent.GetAt(2) == 0x57)) |
- { |
- fileContent.Delete(0, 3); |
- } |
- // Read error |
- if (!bRead) |
- { |
- DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_READ_FILE, "Filter::ParseFilters - Read") |
- } |
- else |
- { |
- isRead = true; |
- |
- UINT dstSize = 0; |
- BYTE* buf = (BYTE*)fileContent.GetString(); |
- UINT srcLength = fileContent.GetLength(); |
- if (((encodingInfos[scores - 1].nCodePage) == 1200) || ((encodingInfos[scores - 1].nCodePage) == 1201)) |
- { |
- srcLength = srcLength * 2; |
- } |
- hr = pMultiLanguage->ConvertString(NULL, encodingInfos[scores - 1].nCodePage, 1252, (BYTE*)buf, &srcLength, NULL, &dstSize); |
- char* bufferTmp = new char[dstSize + 1]; |
- hr = pMultiLanguage->ConvertString(NULL, encodingInfos[scores - 1].nCodePage, 1252, (BYTE*)buf, &srcLength, (BYTE*)bufferTmp, &dstSize); |
- bufferTmp[dstSize] = 0; |
- //Unicode |
- if ((encodingInfos[0].nCodePage == 1200) || (encodingInfos[0].nCodePage == 1201)) |
- { |
- //remove BOM for Unicode |
- fileContent = (char*)bufferTmp; |
- fileContent.Delete(0, 1); |
- |
- } |
- else |
- { |
- wchar_t* fileContentBuffer = fileContent.GetBufferSetLength(dstSize); |
- memset(fileContentBuffer, 0, dstSize); |
- memcpy(fileContentBuffer, bufferTmp, dstSize); |
- } |
- delete [] bufferTmp; |
- |
- } |
- |
- // Close file |
- ::CloseHandle(hFile); |
- } |
- |
-#ifdef PRODUCT_ADBLOCKPLUS |
- } |
-#endif |
- if (isRead) |
- { |
- // Parse file string |
- int pos = 0; |
- CString filter = fileContent.Tokenize(L"\n\r", pos); |
- |
- s_criticalSectionFilterMap.Lock(); |
- { |
- while (pos >= 0) |
- { |
- // If the line is not commented out |
- if (!filter.Trim().IsEmpty() && filter.GetAt(0) != '!' && filter.GetAt(0) != '[') |
- { |
- int filterType = 0; |
- |
- // We need to categorize the filters |
- // We have three options, whitelist, block or element hiding |
- // See http://adblockplus.org/en/filters for further documentation |
- |
- // @@ indicates white listing rule |
- if (filter.Find(L"@@") == 0) |
- { |
- filterType = CFilter::filterTypeWhiteList; |
- |
- filter.Delete(0, 2); |
- } |
- // If a filter contains ## then it is a element hiding rule |
- else if (filter.Find(L"#") >= 0) |
- { |
- filterType = CFilter::filterTypeElementHide; |
- } |
- //Anything we do not support here |
- else if (filter.Find(L"*") == 0) |
- { |
- filterType = CFilter::filterTypeUnknown; |
- } |
- // Else, it is a general rule |
- else |
- { |
- filterType = CFilter::filterTypeBlocking; |
- } |
- |
- try |
- { |
- // Element hiding not supported yet |
- if (filterType == CFilter::filterTypeElementHide) |
- { |
- AddFilterElementHide(filter, filename); |
- } |
- else if (filterType != CFilter::filterTypeUnknown) |
- { |
- AddFilter(filter, filename, filterType); |
- } |
- } |
- catch(...) |
- { |
- //just ignore all errors we might get when adding filters |
- } |
- } |
- |
- CString tmp = L""; |
- tmp.Format(L"Current %d, Total %d", pos, fileContent.GetLength()); |
- filter = fileContent.Tokenize(L"\n\r", pos); |
- int nextPos = fileContent.Find(L"\n", pos + 1); |
- if (nextPos < 0) |
- { |
- filter = ""; |
- pos = -1; |
- |
- } |
- if ((filter.GetLength() > 5000) || (fileContent.GetLength() - 5 <= pos)) |
- { |
- filter = ""; |
+ //just ignore all errors we might get when adding filters |
Felix Dahlke
2013/04/03 05:35:27
We should probably at least log exceptions.
|
} |
} |
} |
- s_criticalSectionFilterMap.Unlock(); |
- } |
+ } |
+ s_criticalSectionFilterMap.Unlock(); |
return isRead; |
} |
-void CPluginFilter::ParseFilters(const TFilterFileList& list) |
+void CPluginFilter::ClearFilters() |
{ |
// Clear filter maps |
s_criticalSectionFilterMap.Lock(); |
@@ -1469,29 +890,6 @@ |
m_elementHideDomains.clear(); |
} |
s_criticalSectionFilterMap.Unlock(); |
- |
- // Load the files |
-#ifdef PRODUCT_ADBLOCKPLUS |
- CPluginClient* client = CPluginClient::GetInstance(); |
-#endif |
- for (TFilterFileList::const_iterator it = list.begin(); it != list.end(); ++it) |
- { |
- ReadFilter(it->first, it->second); |
- } |
- |
-#ifdef PERSONAL_FILTER_FILE |
- ReadFilter(PERSONAL_FILTER_FILE); |
-#endif |
- |
-#ifdef ENABLE_DEBUG_SELFTEST |
- CStringA sCount; |
- s_criticalSectionFilterMap.Lock(); |
- { |
- sCount.Format("Block:%d/%d - BlockDef:%d - White:%d - WhiteDef:%d - Hide:%d/%d", m_filterMap[0][0].size(), m_filterMap[0][1].size(), m_filterMapDefault[0].size(), m_filterMap[1][0].size(), m_filterMapDefault[1].size(), m_elementHideTags.size() + m_elementHideTagsClass.size() + m_elementHideTagsId.size(), m_elementHideDomains.size()); |
- } |
- s_criticalSectionFilterMap.Unlock(); |
- DEBUG_GENERAL("*** Filter count:" + sCount); |
-#endif |
} |
@@ -1800,6 +1198,26 @@ |
} |
} |
+ CPluginClient* client = CPluginClient::GetInstance(); |
+ AdblockPlus::FilterEngine* filterEngine = client->GetFilterEngine(); |
+ |
+ src.OemToCharA(); |
Wladimir Palant
2013/04/03 12:42:19
Are we really getting all URLs as ASCII? What abou
Felix Dahlke
2013/04/03 12:51:04
The problem is that ABP for IE uses UTF-16 interna
Oleksandr
2013/04/03 13:12:17
I've used CT2CA in the end (not included in this p
|
+ |
+ std::string contentTypeString = ""; |
Wladimir Palant
2013/04/03 12:42:19
This needs a TODO comment: "Need to guess the cont
|
+ |
+ std::string url = (char*)src.GetBuffer(); |
Felix Dahlke
2013/04/03 05:35:27
I'm really leaving my comfort zone here, but some
|
+ if (filterEngine->Matches(url, contentTypeString)) |
+ { |
+ if (addDebug) |
+ { |
+ DEBUG_FILTER("Filter::ShouldBlock " + type + " YES") |
+ |
+#ifdef ENABLE_DEBUG_RESULT |
+ CPluginDebug::DebugResultBlocking(type, src); |
+#endif |
+ } |
+ return true; |
+ } |
const CFilter* blockFilter = MatchFilter(CFilter::filterTypeBlocking, src, contentType, domain); |
if (blockFilter) |
{ |
@@ -1817,7 +1235,7 @@ |
DEBUG_FILTER("Filter::ShouldBlock " + type + " YES src:" + src + " - \"" + blockFilter->m_filterText + "\"") |
#ifdef ENABLE_DEBUG_RESULT |
- CPluginDebug::DebugResultBlocking(type, src, blockFilter->m_filterText, blockFilter->m_filterFile); |
+ CPluginDebug::DebugResultBlocking(type, src); |
#endif |
} |
} |
@@ -1980,88 +1398,3 @@ |
return false; |
} |
- |
-#ifdef PRODUCT_ADBLOCKPLUS |
- |
-void CPluginFilter::CreateFilters() |
-{ |
- CPluginFilterLock lock("filter1.txt"); |
- if (lock.IsLocked()) |
- { |
- // Check file existence |
- std::ifstream is; |
- is.open(CPluginSettings::GetDataPath("filter1.txt"), std::ios_base::in); |
- if (is.is_open()) |
- { |
- is.close(); |
- return; |
- } |
- |
- // Open file |
- HANDLE hFile = ::CreateFile(CPluginSettings::GetDataPath("filter1.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
- if (hFile == INVALID_HANDLE_VALUE) |
- { |
- DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_CREATE_FILE_OPEN, "Filter::Create - CreateFile"); |
- } |
- else |
- { |
- // Build filter string |
- CStringA line; |
- line += "[Adblock Plus 1.1]\r\n"; |
- line += "! Checksum: 0xN4e5SegJGeZuYZQGhShQ\r\n"; |
- line += "! EasyList - https://easylist.adblockplus.org/\r\n"; |
- line += "! Last modified: 4 Nov 2010 16:30 UTC\r\n"; |
- line += "! Expires: 5 days (update frequency)\r\n"; |
- line += "! Licence: https://easylist-downloads.adblockplus.org/COPYING\r\n"; |
- line += "!\r\n"; |
- line += "! Please report any unblocked adverts or problems\r\n"; |
- line += "! in the forums (http://forums.lanik.us/)\r\n"; |
- line += "! or via e-mail (easylist.subscription@gmail.com).\r\n"; |
- line += "!\r\n"; |
- line += "!-----------------General advert blocking filters-----------------!\r\n"; |
- |
- |
- // Write file |
- DWORD dwBytesWritten = 0; |
- if (::WriteFile(hFile, line.GetBuffer(), line.GetLength(), &dwBytesWritten, NULL) && dwBytesWritten == line.GetLength()) |
- { |
- // Set correct version |
- CPluginSettings* settings = CPluginSettings::GetInstance(); |
- |
- settings->AddFilterUrl(CString(FILTERS_PROTOCOL) + CString(FILTERS_HOST) + "/easylist.txt", 1); |
- settings->AddFilterFileName(CString(FILTERS_PROTOCOL) + CString(FILTERS_HOST) + "/easylist.txt", "filter1.txt"); |
- settings->Write(); |
- } |
- else |
- { |
- DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_CREATE_FILE_WRITE, "Filter::Create - WriteFile"); |
- } |
- |
- // Close file |
- if (!::CloseHandle(hFile)) |
- { |
- DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_FILTER, PLUGIN_ERROR_FILTER_CREATE_FILE_CLOSE, "Filter::Create - CloseHandle"); |
- } |
- } |
- } |
-} |
- |
-#endif // PRODUCT_ADBLOCKPLUS |
- |
- |
-#ifdef PRODUCT_ADBLOCKPLUS |
- |
-bool CPluginFilter::IsAlive() const |
-{ |
- bool isAlive; |
- |
- s_criticalSectionFilterMap.Lock(); |
- { |
- isAlive = !m_filterMap[0][0].empty(); |
- } |
- s_criticalSectionFilterMap.Unlock(); |
- |
- return isAlive; |
-} |
- |
-#endif |