Index: src/plugin/PluginDomTraverserBase.h |
=================================================================== |
--- a/src/plugin/PluginDomTraverserBase.h |
+++ b/src/plugin/PluginDomTraverserBase.h |
@@ -32,7 +32,7 @@ |
virtual void ClearCache(); |
- void ShowNotification(CPluginTab* tab); |
+ void ShowNotification(CPluginTab* /*tab*/){} |
Eric
2014/09/26 16:36:40
ShowNotification is completely dead code. The symb
Oleksandr
2014/10/06 20:19:32
+1
On 2014/09/26 16:36:40, Eric wrote:
|
protected: |
@@ -46,6 +46,7 @@ |
void TraverseDocument(IWebBrowser2* pBrowser, bool isMainDoc, CString indent); |
void TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached=true); |
+ typedef ATL::CComCritSecLock<CComAutoCriticalSection> CriticalSectionLock; |
Eric
2014/10/08 16:26:55
"Sentry" is the word that Stroustrup uses for thes
|
CComAutoCriticalSection m_criticalSection; |
CString m_domain; |
@@ -53,15 +54,10 @@ |
bool m_isHeaderTraversed; |
- // Caching |
- long m_cacheDomElementCount; |
- |
- int m_cacheIndexLast; |
- int m_cacheElementsMax; |
std::set<CString> m_cacheDocumentHasFrames; |
std::set<CString> m_cacheDocumentHasIframes; |
- T* m_cacheElements; |
+ std::vector<T> m_cacheElements; |
CPluginTab* m_tab; |
CComPtr<IWebBrowser2> m_pBrowser; |
@@ -69,16 +65,14 @@ |
template <class T> |
CPluginDomTraverserBase<T>::CPluginDomTraverserBase(CPluginTab* tab) : |
- m_tab(tab), m_isHeaderTraversed(false), m_cacheDomElementCount(0), m_cacheIndexLast(0), m_cacheElementsMax(5000) |
+ m_tab(tab), m_isHeaderTraversed(false) |
{ |
- m_cacheElements = new T[m_cacheElementsMax]; |
+ m_cacheElements.reserve(5000); |
} |
- |
template <class T> |
CPluginDomTraverserBase<T>::~CPluginDomTraverserBase() |
{ |
- delete [] m_cacheElements; |
} |
template <class T> |
@@ -91,7 +85,6 @@ |
void CPluginDomTraverserBase<T>::TraverseDocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName) |
{ |
m_domain = domain; |
- |
TraverseDocument(pBrowser, true, ""); |
} |
@@ -100,7 +93,6 @@ |
void CPluginDomTraverserBase<T>::TraverseSubdocument(IWebBrowser2* pBrowser, const CString& domain, const CString& documentName) |
{ |
m_domain = domain; |
- |
TraverseDocument(pBrowser, false, ""); |
} |
@@ -118,13 +110,10 @@ |
DWORD res = WaitForSingleObject(m_tab->m_filter->hideFiltersLoadedEvent, ENGINE_STARTUP_TIMEOUT); |
if (!IsEnabled()) return; |
- VARIANT_BOOL isBusy; |
- if (SUCCEEDED(pBrowser->get_Busy(&isBusy))) |
+ VARIANT_BOOL isBusy; |
+ if (FAILED(pBrowser->get_Busy(&isBusy)) || isBusy) |
{ |
- if (isBusy) |
- { |
- return; |
- } |
+ return; |
} |
// Get document |
@@ -156,7 +145,7 @@ |
else |
{ |
CComPtr<IHTMLElementCollection> pBodyCollection; |
- if (FAILED(pDoc->getElementsByTagName(L"body", &pBodyCollection)) || !pBodyCollection) |
+ if (FAILED(pDoc->getElementsByTagName(ATL::CComBSTR(L"body"), &pBodyCollection)) || !pBodyCollection) |
Oleksandr
2014/10/06 20:19:32
I would be willing to have this committed without
|
{ |
return; |
} |
@@ -179,7 +168,7 @@ |
{ |
CComVariant vCacheIndex; |
- if (FAILED(pBodyEl->getAttribute(L"abp", 0, &vCacheIndex)) || vCacheIndex.vt == VT_NULL) |
+ if (FAILED(pBodyEl->getAttribute(ATL::CComBSTR(L"abp"), 0, &vCacheIndex)) || vCacheIndex.vt == VT_NULL) |
{ |
ClearCache(); |
} |
@@ -205,7 +194,7 @@ |
// eg. http://gamecopyworld.com/ |
long frameCount = 0; |
CComPtr<IHTMLElementCollection> pFrameCollection; |
- if (SUCCEEDED(pDoc->getElementsByTagName(L"frame", &pFrameCollection)) && pFrameCollection) |
+ if (SUCCEEDED(pDoc->getElementsByTagName(ATL::CComBSTR(L"frame"), &pFrameCollection)) && pFrameCollection) |
{ |
pFrameCollection->get_length(&frameCount); |
} |
@@ -245,7 +234,7 @@ |
{ |
long frameCount = 0; |
CComPtr<IHTMLElementCollection> pFrameCollection; |
- if (SUCCEEDED(pDoc->getElementsByTagName(L"iframe", &pFrameCollection)) && pFrameCollection) |
+ if (SUCCEEDED(pDoc->getElementsByTagName(ATL::CComBSTR(L"iframe"), &pFrameCollection)) && pFrameCollection) |
{ |
pFrameCollection->get_length(&frameCount); |
} |
@@ -263,8 +252,7 @@ |
if (pFrameEl) |
{ |
CComVariant vAttr; |
- |
- if (SUCCEEDED(pFrameEl->getAttribute(L"src", 0, &vAttr)) && vAttr.vt == VT_BSTR && ::SysStringLen(vAttr.bstrVal) > 0) |
+ if (SUCCEEDED(pFrameEl->getAttribute(ATL::CComBSTR(L"scr"), 0, &vAttr)) && vAttr.vt == VT_BSTR && ::SysStringLen(vAttr.bstrVal) > 0) |
{ |
CString src = vAttr.bstrVal; |
@@ -303,47 +291,37 @@ |
template <class T> |
void CPluginDomTraverserBase<T>::TraverseChild(IHTMLElement* pEl, IWebBrowser2* pBrowser, CString& indent, bool isCached) |
{ |
- int cacheIndex = -1; |
+ uint32_t cacheIndex = -1; |
long cacheAllElementsCount = -1; |
- |
- m_criticalSection.Lock(); |
{ |
+ CriticalSectionLock lock(m_criticalSection); |
CComVariant vCacheIndex; |
- if (isCached && SUCCEEDED(pEl->getAttribute(L"abp", 0, &vCacheIndex)) && vCacheIndex.vt == VT_I4) |
+ if (isCached |
+ && SUCCEEDED(pEl->getAttribute(ATL::CComBSTR(L"abp"), 0, &vCacheIndex)) |
+ && SUCCEEDED(vCacheIndex.ChangeType(VT_UI4))) |
{ |
- cacheIndex = vCacheIndex.intVal; |
- |
+ cacheIndex = vCacheIndex.uintVal; |
+ // right now the user can set arbitrary value of abp attribute which in the best case will |
+ // cause the crash. Test cacheIndex belongs to [0, m_cacheElements.size()) |
+ if (cacheIndex >= m_cacheElements.size()) |
+ { |
+ return; |
Oleksandr
2014/10/06 20:19:32
I agree. This makes it very easy for someone to di
|
+ } |
cacheAllElementsCount = m_cacheElements[cacheIndex].m_elements; |
} |
else |
{ |
isCached = false; |
- cacheIndex = m_cacheIndexLast++; |
- |
- // Resize cache??? |
- if (cacheIndex >= m_cacheElementsMax) |
- { |
- T* oldCacheElements = m_cacheElements; |
- |
- m_cacheElements = new T[2*m_cacheElementsMax]; |
- |
- memcpy(m_cacheElements, oldCacheElements, m_cacheElementsMax*sizeof(T)); |
- |
- m_cacheElementsMax *= 2; |
- |
- delete [] oldCacheElements; |
- } |
- |
+ // it's important to set cacheIndex before extending m_cacheElements because it's zero based. |
+ cacheIndex = m_cacheElements.size(); |
+ m_cacheElements.emplace_back(T()); |
m_cacheElements[cacheIndex].Init(); |
- vCacheIndex.vt = VT_I4; |
- vCacheIndex.intVal = cacheIndex; |
- |
- pEl->setAttribute(L"abp", vCacheIndex); |
+ vCacheIndex = cacheIndex; |
+ pEl->setAttribute(ATL::CComBSTR(L"abp"), vCacheIndex); |
} |
} |
- m_criticalSection.Unlock(); |
// Get number of elements in the scope of pEl |
long allElementsCount = 0; |
@@ -365,11 +343,10 @@ |
} |
// Update cache |
Eric
2014/10/08 16:26:55
Yes, this would perform better, at the expense of
|
- m_criticalSection.Lock(); |
{ |
+ CriticalSectionLock lock(m_criticalSection); |
m_cacheElements[cacheIndex].m_elements = allElementsCount; |
} |
- m_criticalSection.Unlock(); |
// Get tag |
CComBSTR bstrTag; |
@@ -390,19 +367,13 @@ |
// Update frame/iframe cache |
if (tag == "iframe") |
{ |
- m_criticalSection.Lock(); |
- { |
- m_cacheDocumentHasIframes.insert(m_documentName); |
- } |
- m_criticalSection.Unlock(); |
+ CriticalSectionLock lock(m_criticalSection); |
+ m_cacheDocumentHasIframes.insert(m_documentName); |
} |
else if (tag == "frame") |
{ |
- m_criticalSection.Lock(); |
- { |
- m_cacheDocumentHasFrames.insert(m_documentName); |
- } |
- m_criticalSection.Unlock(); |
+ CriticalSectionLock lock(m_criticalSection); |
+ m_cacheDocumentHasFrames.insert(m_documentName); |
} |
// Iterate through children of this element |
@@ -446,24 +417,10 @@ |
template <class T> |
void CPluginDomTraverserBase<T>::ClearCache() |
{ |
- m_criticalSection.Lock(); |
- { |
- m_cacheIndexLast = 0; |
- m_cacheDocumentHasFrames.clear(); |
- m_cacheDocumentHasIframes.clear(); |
- } |
- m_criticalSection.Unlock(); |
-} |
-template <class T> |
-void CPluginDomTraverserBase<T>::ShowNotification(CPluginTab* tab) |
-{ |
- if (tab->m_plugin->GetTabHWND() == NULL) |
- { |
- return; |
- } |
- |
- |
+ CriticalSectionLock lock(m_criticalSection); |
+ m_cacheElements.clear(); |
+ m_cacheDocumentHasFrames.clear(); |
+ m_cacheDocumentHasIframes.clear(); |
} |
- |
#endif // _PLUGIN_DOM_TRAVERSER_BASE_H_ |