Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1012)

Unified Diff: Source/core/xmlhttprequest/XMLHttpRequest.cpp

Issue 942433003: Protect XHR's wrapper while dispatching event. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/xmlhttprequest/XMLHttpRequest.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/xmlhttprequest/XMLHttpRequest.cpp
diff --git a/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index 065d9e10784c780b857c63125bad758d95b958e8..fce174ac9fb5dfa9ecf9b40f9eb54edb85b0fd9d 100644
--- a/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -75,12 +75,33 @@ namespace blink {
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XMLHttpRequest"));
-static bool isSetCookieHeader(const AtomicString& name)
+namespace {
+
+// This class protects the wrapper of the associated XMLHttpRequest object
+// via hasPendingActivity method which returns true if
+// m_eventDispatchRecursionLevel is positive.
+class ScopedEventDispatchProtect final {
+public:
+ explicit ScopedEventDispatchProtect(int* level) : m_level(level)
+ {
+ ++*m_level;
+ }
+ ~ScopedEventDispatchProtect()
+ {
+ ASSERT(*m_level > 0);
+ --*m_level;
+ }
+
+private:
+ int* const m_level;
+};
+
+bool isSetCookieHeader(const AtomicString& name)
{
return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
}
-static void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
+void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
{
unsigned pos = 0, len = 0;
@@ -99,7 +120,7 @@ static void replaceCharsetInMediaType(String& mediaType, const String& charsetVa
}
}
-static void logConsoleError(ExecutionContext* context, const String& message)
+void logConsoleError(ExecutionContext* context, const String& message)
{
if (!context)
return;
@@ -108,6 +129,8 @@ static void logConsoleError(ExecutionContext* context, const String& message)
context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
}
+} // namespace
+
using Result = WebDataConsumerHandle::Result;
// ReadableStreamSource is the underlying source for the response stream of
@@ -308,6 +331,7 @@ XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOri
, m_progressEventThrottle(this)
, m_responseTypeCode(ResponseTypeDefault)
, m_securityOrigin(securityOrigin)
+ , m_eventDispatchRecursionLevel(0)
, m_async(true)
, m_includeCredentials(false)
, m_parsedResponse(false)
@@ -1114,7 +1138,7 @@ bool XMLHttpRequest::internalAbort()
// If abort() called internalAbort() and a nested open() ended up
// clearing the error flag, but didn't send(), make sure the error
// flag is still set.
- bool newLoadStarted = hasPendingActivity();
+ bool newLoadStarted = m_loader;
if (!newLoadStarted)
m_error = true;
@@ -1179,10 +1203,6 @@ void XMLHttpRequest::handleNetworkError()
long long expectedLength = m_response.expectedContentLength();
long long receivedLength = m_receivedLength;
- // Prevent the XMLHttpRequest instance from being destoryed during
- // |internalAbort()|.
- RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
-
if (!internalAbort())
return;
@@ -1197,10 +1217,6 @@ void XMLHttpRequest::handleDidCancel()
long long expectedLength = m_response.expectedContentLength();
long long receivedLength = m_receivedLength;
- // Prevent the XMLHttpRequest instance from being destoryed during
- // |internalAbort()|.
- RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
-
if (!internalAbort())
return;
@@ -1400,6 +1416,7 @@ String XMLHttpRequest::statusText() const
void XMLHttpRequest::didFail(const ResourceError& error)
{
WTF_LOG(Network, "XMLHttpRequest %p didFail()", this);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
// If we are already in an error state, for instance we called abort(), bail out early.
if (m_error)
@@ -1428,6 +1445,7 @@ void XMLHttpRequest::didFail(const ResourceError& error)
void XMLHttpRequest::didFailRedirectCheck()
{
WTF_LOG(Network, "XMLHttpRequest %p didFailRedirectCheck()", this);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
handleNetworkError();
// Now the XMLHttpRequest instance may be dead.
@@ -1436,6 +1454,7 @@ void XMLHttpRequest::didFailRedirectCheck()
void XMLHttpRequest::didFinishLoading(unsigned long identifier, double)
{
WTF_LOG(Network, "XMLHttpRequest %p didFinishLoading(%lu)", this, identifier);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
if (m_error)
return;
@@ -1489,6 +1508,7 @@ void XMLHttpRequest::didFinishLoadingInternal()
void XMLHttpRequest::didFinishLoadingFromBlob()
{
WTF_LOG(Network, "XMLHttpRequest %p didFinishLoadingFromBlob", this);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
didFinishLoadingInternal();
}
@@ -1496,6 +1516,7 @@ void XMLHttpRequest::didFinishLoadingFromBlob()
void XMLHttpRequest::didFailLoadingFromBlob()
{
WTF_LOG(Network, "XMLHttpRequest %p didFailLoadingFromBlob()", this);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
if (m_error)
return;
@@ -1520,6 +1541,8 @@ PassRefPtr<BlobDataHandle> XMLHttpRequest::createBlobDataHandleFromResponse()
void XMLHttpRequest::notifyParserStopped()
{
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
+
// This should only be called when response document is parsed asynchronously.
ASSERT(m_responseDocumentParser);
ASSERT(!m_responseDocumentParser->isParsing());
@@ -1556,6 +1579,7 @@ void XMLHttpRequest::endLoading()
void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, totalBytesToBeSent);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
if (!m_upload)
return;
@@ -1573,6 +1597,7 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
{
WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier);
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
m_response = response;
if (!m_mimeTypeOverride.isEmpty()) {
@@ -1590,9 +1615,6 @@ void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const Resource
m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>(executionContext(), m_responseStreamSource);
m_responseStreamSource->startStream(m_responseStream);
- // This protection seems needed to keep |this| alive after changeState
- // calling which may call event listeners.
- RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
changeState(HEADERS_RECEIVED);
if (m_error) {
// We need to check for |m_error| because |changeState| may trigger
@@ -1649,6 +1671,7 @@ PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const
void XMLHttpRequest::didReceiveData(const char* data, unsigned len)
{
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
if (m_error)
return;
@@ -1703,6 +1726,7 @@ void XMLHttpRequest::didReceiveData(const char* data, unsigned len)
void XMLHttpRequest::didDownloadData(int dataLength)
{
+ ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel);
if (m_error)
return;
@@ -1732,10 +1756,6 @@ void XMLHttpRequest::handleDidTimeout()
long long expectedLength = m_response.expectedContentLength();
long long receivedLength = m_receivedLength;
- // Prevent the XMLHttpRequest instance from being destoryed during
- // |internalAbort()|.
- RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
-
if (!internalAbort())
return;
@@ -1769,7 +1789,7 @@ bool XMLHttpRequest::hasPendingActivity() const
return true;
if (m_responseStream && m_responseStream->hasPendingActivity())
return true;
- return false;
+ return m_eventDispatchRecursionLevel > 0;
}
void XMLHttpRequest::contextDestroyed()
« no previous file with comments | « Source/core/xmlhttprequest/XMLHttpRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698