| Index: src/plugin/PluginWbPassThrough.cpp |
| =================================================================== |
| --- a/src/plugin/PluginWbPassThrough.cpp |
| +++ b/src/plugin/PluginWbPassThrough.cpp |
| @@ -142,75 +142,85 @@ |
| { |
| } |
| -ContentType WBPassthruSink::GetContentTypeFromMimeType(const std::wstring& mimeType) |
| +namespace |
| { |
| - if ((mimeType.find(L"text/html") != std::wstring::npos) || |
| - (mimeType.find(L"application/xhtml+xml") != std::wstring::npos)) |
| + /** |
| + * Heuristic to infer an ABP content type from the media type list of an Accept: header field. |
| + * |
| + * Known IE Accept: strings for documents and images: |
| + * text/html, application/xhtml+xml, image/jxr, *\/* |
| + * image/png, image/svg+xml, image/jxr, image/*;q=0.8, *\/*;q = 0.5 |
| + * In IE9 the image/jxr part is missing. |
| + */ |
| + ContentType InferContentTypeFromMediaTypeList(const std::wstring& mediaTypeList) |
| { |
| - return ContentType::CONTENT_TYPE_SUBDOCUMENT; |
| - } |
| - if (mimeType.find(L"image/") != std::wstring::npos) |
| - { |
| - return ContentType::CONTENT_TYPE_IMAGE; |
| - } |
| - if (mimeType.find(L"text/css") != std::wstring::npos) |
| - { |
| - return ContentType::CONTENT_TYPE_STYLESHEET; |
| - } |
| - if ((mimeType.find(L"application/javascript") != std::wstring::npos) || (mimeType.find(L"application/json") != std::wstring::npos)) |
| - { |
| - return ContentType::CONTENT_TYPE_SCRIPT; |
| - } |
| - if (mimeType.find(L"application/x-shockwave-flash") != std::wstring::npos) |
| - { |
| - return ContentType::CONTENT_TYPE_OBJECT; |
| - } |
| - // It is important to have this check last, since it is rather generic, and might overlay text/html, for example |
| - if (mimeType.find(L"xml") != std::wstring::npos) |
| - { |
| - return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; |
| + if ((mediaTypeList.find(L"text/html") != std::wstring::npos) || |
| + (mediaTypeList.find(L"application/xhtml+xml") != std::wstring::npos)) |
| + { |
| + return ContentType::CONTENT_TYPE_SUBDOCUMENT; |
| + } |
| + if (mediaTypeList.find(L"image/") != std::wstring::npos) |
| + { |
| + return ContentType::CONTENT_TYPE_IMAGE; |
| + } |
| + if (mediaTypeList.find(L"text/css") != std::wstring::npos) |
| + { |
| + return ContentType::CONTENT_TYPE_STYLESHEET; |
| + } |
| + if ((mediaTypeList.find(L"application/javascript") != std::wstring::npos) || (mediaTypeList.find(L"application/json") != std::wstring::npos)) |
| + { |
| + return ContentType::CONTENT_TYPE_SCRIPT; |
| + } |
| + if (mediaTypeList.find(L"application/x-shockwave-flash") != std::wstring::npos) |
| + { |
| + return ContentType::CONTENT_TYPE_OBJECT; |
| + } |
| + // It is important to have this check last, since it is rather generic, and might overlay text/html, for example |
| + if (mediaTypeList.find(L"xml") != std::wstring::npos) |
| + { |
| + return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; |
| + } |
| + return ContentType::CONTENT_TYPE_OTHER; |
| } |
| - return ContentType::CONTENT_TYPE_OTHER; |
| -} |
| + ContentType InferContentTypeFromUrl(const std::wstring& src) |
| + { |
| + std::wstring schemeAndHierarchicalPart = GetSchemeAndHierarchicalPart(src); |
| + auto contentType = GetContentTypeFromString(schemeAndHierarchicalPart); |
| + if (contentType == ContentType::CONTENT_TYPE_OTHER && |
| + AdblockPlus::IE::InstalledMajorVersion() == 8) |
| + { |
| + std::wstring queryString = GetQueryString(src); |
| + wchar_t* nextToken = nullptr; |
| + const wchar_t* token = wcstok_s(&queryString[0], L"&=", &nextToken); |
| + while (token != nullptr) |
| + { |
| + contentType = GetContentTypeFromString(token); |
| + if (contentType != ContentType::CONTENT_TYPE_OTHER) |
| + { |
| + return contentType; |
| + } |
| + token = wcstok_s(nullptr, L"&=", &nextToken); |
| + } |
| + } |
| + return contentType; |
| + } |
| -ContentType WBPassthruSink::GetContentTypeFromURL(const std::wstring& src) |
| -{ |
| - std::wstring schemeAndHierarchicalPart = GetSchemeAndHierarchicalPart(src); |
| - auto contentType = GetContentTypeFromString(schemeAndHierarchicalPart); |
| - if (contentType == ContentType::CONTENT_TYPE_OTHER && |
| - AdblockPlus::IE::InstalledMajorVersion() == 8) |
| + ContentType InferContentType(const std::wstring& mediaTypeList, const std::wstring& domain, const std::wstring& src) |
| { |
| - std::wstring queryString = GetQueryString(src); |
| - wchar_t* nextToken = nullptr; |
| - const wchar_t* token = wcstok_s(&queryString[0], L"&=", &nextToken); |
| - while (token != nullptr) |
| + // No referer or mime type |
| + // BINDSTRING_XDR_ORIGIN works only for IE v8+ |
| + if (mediaTypeList.empty() && domain.empty() && AdblockPlus::IE::InstalledMajorVersion() >= 8) |
| { |
| - contentType = GetContentTypeFromString(token); |
| - if (contentType != ContentType::CONTENT_TYPE_OTHER) |
| - { |
| - return contentType; |
| - } |
| - token = wcstok_s(nullptr, L"&=", &nextToken); |
| + return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; |
| } |
| + ContentType contentType = InferContentTypeFromMediaTypeList(mediaTypeList); |
| + if (contentType == ContentType::CONTENT_TYPE_OTHER) |
| + { |
| + contentType = InferContentTypeFromUrl(src); |
| + } |
| + return contentType; |
| } |
| - return contentType; |
| -} |
| - |
| -ContentType WBPassthruSink::GetContentType(const std::wstring& mimeType, const std::wstring& domain, const std::wstring& src) |
| -{ |
| - // No referer or mime type |
| - // BINDSTRING_XDR_ORIGIN works only for IE v8+ |
| - if (mimeType.empty() && domain.empty() && AdblockPlus::IE::InstalledMajorVersion() >= 8) |
| - { |
| - return ContentType::CONTENT_TYPE_XMLHTTPREQUEST; |
| - } |
| - ContentType contentType = GetContentTypeFromMimeType(mimeType); |
| - if (contentType == ContentType::CONTENT_TYPE_OTHER) |
| - { |
| - contentType = GetContentTypeFromURL(src); |
| - } |
| - return contentType; |
| } |
| //////////////////////////////////////////////////////////////////////////////////////// |
| @@ -344,7 +354,7 @@ |
| m_boundDomain = ExtractHttpHeader<std::wstring>(*pszAdditionalHeaders, L"Referer:", L"\n"); |
| } |
| m_boundDomain = TrimString(m_boundDomain); |
| - m_contentType = GetContentType(ToUtf16String(ExtractHttpAcceptHeader(m_spTargetProtocol)), m_boundDomain, src); |
| + m_contentType = InferContentType(ToUtf16String(ExtractHttpAcceptHeader(m_spTargetProtocol)), m_boundDomain, src); |
| CPluginTab* tab = CPluginClass::GetTab(::GetCurrentThreadId()); |
| CPluginClient* client = CPluginClient::GetInstance(); |