Bug 461555: Don't clear out the parser until all deferred scripts have executed to ensure that a document.write in a deferred script doesn't clear the page. r/sr=mrbkap
☠☠ backed out by ea386d2dfc1c ☠ ☠
authorJonas Sicking <jonas@sicking.cc>
Wed, 14 Jan 2009 17:25:21 -0800
changeset 23693 4c4d0bf8622e9c0e17857e27ea8724d98f601cb6
parent 23692 20780ac6ca4a9f39d8ab74799ba3ec8368d4a200
child 23694 ea386d2dfc1c6ce65b6d668605ecddae22bb2fc0
push id4686
push usersicking@mozilla.com
push dateThu, 15 Jan 2009 01:26:52 +0000
treeherdermozilla-central@4c4d0bf8622e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs461555
milestone1.9.2a1pre
Bug 461555: Don't clear out the parser until all deferred scripts have executed to ensure that a document.write in a deferred script doesn't clear the page. r/sr=mrbkap
content/base/public/nsIDocument.h
content/base/src/nsContentSink.cpp
content/base/src/nsContentSink.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsScriptLoader.h
content/base/test/Makefile.in
content/base/test/test_bug461555.html
content/html/document/src/nsHTMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.h
content/xml/document/src/nsXMLDocument.cpp
parser/htmlparser/public/nsIContentSink.h
parser/htmlparser/src/nsParser.cpp
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1098,16 +1098,21 @@ public:
    * Enumerate the external resource documents associated with this document.
    * The enumerator callback should return PR_TRUE to continue enumerating, or
    * PR_FALSE to stop.  This callback will never get passed a null aDocument.
    */
   virtual void EnumerateExternalResources(nsSubDocEnumFunc aCallback,
                                           void* aData) = 0;
 
   /**
+   * Dispatch DOMContentLoaded and DOMFrameContentLoaded events
+   */
+  virtual void DispatchContentLoadedEvents() = 0;
+
+  /**
    * Return whether the document is currently showing (in the sense of
    * OnPageShow() having been called already and OnPageHide() not having been
    * called yet.
    */
   PRBool IsShowing() { return mIsShowing; }
 
 protected:
   ~nsIDocument()
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -344,29 +344,31 @@ nsContentSink::ScriptAvailable(nsresult 
                                PRInt32 aLineNo)
 {
   PRUint32 count = mScriptElements.Count();
   if (mParser && NS_SUCCEEDED(aResult)) {
     // Only notify the parser about scripts that are actually going to run.
     mParser->ScriptExecuting();
   }
 
-  if (count == 0) {
-    return NS_OK;
-  }
-
   // aElement will not be in mScriptElements if a <script> was added
   // using the DOM during loading, or if the script was inline and thus
   // never blocked.
-  NS_ASSERTION(mScriptElements.IndexOf(aElement) == count - 1 ||
+  NS_ASSERTION(count == 0 ||
+               mScriptElements.IndexOf(aElement) == count - 1 ||
                mScriptElements.IndexOf(aElement) == PRUint32(-1),
                "script found at unexpected position");
 
   // Check if this is the element we were waiting for
-  if (aElement != mScriptElements[count - 1]) {
+  if (count == 0 || aElement != mScriptElements[count - 1]) {
+    if (mDidGetReadyToCallDidBuildModelCall &&
+        !mScriptLoader->HasPendingOrCurrentScripts()) {
+      ContinueInterruptedParsingAsyncIfEnabled();
+    }
+
     return NS_OK;
   }
 
   if (mParser && !mParser->IsParserEnabled()) {
     // make sure to unblock the parser before evaluating the script,
     // we must unblock the parser even if loading the script failed or
     // if the script was empty, if we don't, the parser will never be
     // unblocked.
@@ -382,17 +384,17 @@ nsContentSink::ScriptAvailable(nsresult 
       // Loading external script failed!. So, resume parsing since the parser
       // got blocked when loading external script. See
       // http://bugzilla.mozilla.org/show_bug.cgi?id=94903.
       //
       // XXX We don't resume parsing if we get NS_BINDING_ABORTED from the
       //     script load, assuming that that error code means that the user
       //     stopped the load through some action (like clicking a link). See
       //     http://bugzilla.mozilla.org/show_bug.cgi?id=243392.
-      ContinueInterruptedParsingAsync();
+      ContinueInterruptedParsingAsyncIfEnabled();
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentSink::ScriptEvaluated(nsresult aResult,
@@ -401,29 +403,31 @@ nsContentSink::ScriptEvaluated(nsresult 
 {
   if (mParser) {
     mParser->ScriptDidExecute();
   }
 
   // Check if this is the element we were waiting for
   PRInt32 count = mScriptElements.Count();
   if (count == 0 || aElement != mScriptElements[count - 1]) {
+    if (mDidGetReadyToCallDidBuildModelCall &&
+        !mScriptLoader->HasPendingOrCurrentScripts()) {
+      ContinueInterruptedParsingAsyncIfEnabled();
+    }
     return NS_OK;
   }
 
   // Pop the script element stack
   mScriptElements.RemoveObjectAt(count - 1); 
 
   if (NS_SUCCEEDED(aResult)) {
     PostEvaluateScript(aElement);
   }
 
-  if (mParser && mParser->IsParserEnabled()) {
-    ContinueInterruptedParsingAsync();
-  }
+  ContinueInterruptedParsingAsyncIfEnabled();
 
   return NS_OK;
 }
 
 nsresult
 nsContentSink::ProcessHTTPHeaders(nsIChannel* aChannel)
 {
   nsCOMPtr<nsIHttpChannel> httpchannel(do_QueryInterface(aChannel));
@@ -1736,22 +1740,37 @@ void
 nsContentSink::ContinueInterruptedParsingIfEnabled()
 {
   if (mParser && mParser->IsParserEnabled()) {
     mParser->ContinueInterruptedParsing();
   }
 }
 
 void
-nsContentSink::ContinueInterruptedParsingAsync()
+nsContentSink::ContinueInterruptedParsingAsyncIfEnabled()
 {
-  nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsContentSink>(this,
-    &nsContentSink::ContinueInterruptedParsingIfEnabled);
+  if (mParser && mParser->IsParserEnabled()) {
+    nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsContentSink>(this,
+      &nsContentSink::ContinueInterruptedParsingIfEnabled);
+
+    NS_DispatchToCurrentThread(ev);
+  }
+}
 
-  NS_DispatchToCurrentThread(ev);
+PRBool
+nsContentSink::ReadyToCallDidBuildModelImpl()
+{
+  if (!mDidGetReadyToCallDidBuildModelCall) {
+    mDidGetReadyToCallDidBuildModelCall = PR_TRUE;
+
+    mDocument->DispatchContentLoadedEvents();
+    mScriptLoader->EndDeferringScripts();
+  }
+  
+  return !mScriptLoader->HasPendingOrCurrentScripts();
 }
 
 // URIs: action, href, src, longdesc, usemap, cite
 PRBool 
 IsAttrURI(nsIAtom *aName)
 {
   return (aName == nsGkAtoms::action ||
           aName == nsGkAtoms::href ||
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -132,16 +132,17 @@ class nsContentSink : public nsICSSLoade
 
   // nsIContentSink implementation helpers
   NS_HIDDEN_(nsresult) WillParseImpl(void);
   NS_HIDDEN_(nsresult) WillInterruptImpl(void);
   NS_HIDDEN_(nsresult) WillResumeImpl(void);
   NS_HIDDEN_(nsresult) DidProcessATokenImpl(void);
   NS_HIDDEN_(void) WillBuildModelImpl(void);
   NS_HIDDEN_(void) DidBuildModelImpl(void);
+  NS_HIDDEN_(PRBool) ReadyToCallDidBuildModelImpl(void);
   NS_HIDDEN_(void) DropParserAndPerfHint(void);
 
   void NotifyAppend(nsIContent* aContent, PRUint32 aStartIndex);
 
   // nsIDocumentObserver
   virtual void BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
   virtual void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
 
@@ -293,17 +294,17 @@ protected:
 
 private:
   // People shouldn't be allocating this class directly.  All subclasses should
   // be allocated using a zeroing operator new.
   void* operator new(size_t sz) CPP_THROW_NEW;  // Not to be implemented
 
 protected:
 
-  void ContinueInterruptedParsingAsync();
+  void ContinueInterruptedParsingAsyncIfEnabled();
   void ContinueInterruptedParsingIfEnabled();
 
   nsCOMPtr<nsIDocument>         mDocument;
   nsCOMPtr<nsIParser>           mParser;
   nsCOMPtr<nsIURI>              mDocumentURI;
   nsCOMPtr<nsIURI>              mDocumentBaseURI;
   nsCOMPtr<nsIDocShell>         mDocShell;
   nsCOMPtr<nsICSSLoader>        mCSSLoader;
@@ -344,16 +345,17 @@ protected:
   PRUint8 mDynamicLowerValue : 1;
   PRUint8 mParsing : 1;
   PRUint8 mDroppedTimer : 1;
   PRUint8 mChangeScrollPosWhenScrollingToRef : 1;
   // If true, we deferred starting layout until sheets load
   PRUint8 mDeferredLayoutStart : 1;
   // If true, we deferred notifications until sheets load
   PRUint8 mDeferredFlushTags : 1;
+  PRUint8 mDidGetReadyToCallDidBuildModelCall : 1;
   
   // -- Can interrupt parsing members --
   PRUint32 mDelayTimerStart;
 
   // Interrupt parsing during token procesing after # of microseconds
   PRInt32 mMaxTokenProcessingTime;
 
   // Switch between intervals when time is exceeded
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3949,20 +3949,16 @@ nsDocument::DispatchContentLoadedEvents(
           }
         }
       }
       
       parent = parent->GetParentDocument();
     } while (parent);
   }
 
-  if (mScriptLoader) {
-    mScriptLoader->EndDeferringScripts();
-  }
-
   UnblockOnload(PR_TRUE);
 }
 
 void
 nsDocument::EndLoad()
 {
   // Drop the ref to our parser, if any, but keep hold of the sink so that we
   // can flush it from FlushPendingNotifications as needed.  We might have to
@@ -3970,25 +3966,16 @@ nsDocument::EndLoad()
   if (mParser) {
     mWeakSink = do_GetWeakReference(mParser->GetContentSink());
     mParser = nsnull;
   }
   
   NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
   
   SetReadyStateInternal(READYSTATE_INTERACTIVE);
-
-  if (!mSynchronousDOMContentLoaded) {
-    nsRefPtr<nsIRunnable> ev =
-      new nsRunnableMethod<nsDocument>(this,
-                                       &nsDocument::DispatchContentLoadedEvents);
-    NS_DispatchToCurrentThread(ev);
-  } else {
-    DispatchContentLoadedEvents();
-  }
 }
 
 void
 nsDocument::ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2,
                                  PRInt32 aStateMask)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(ContentStatesChanged,
                                (this, aContent1, aContent2, aStateMask));
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -973,16 +973,17 @@ public:
   virtual NS_HIDDEN_(void) TryCancelFrameLoaderInitialization(nsIDocShell* aShell);
   virtual NS_HIDDEN_(PRBool) FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell);
   virtual NS_HIDDEN_(nsIDocument*)
     RequestExternalResource(nsIURI* aURI,
                             nsINode* aRequestingNode,
                             ExternalResourceLoad** aPendingLoad);
   virtual NS_HIDDEN_(void)
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
+  virtual void DispatchContentLoadedEvents();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDocument, nsIDocument)
 
   /**
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
   static nsresult GetElementsByClassNameHelper(nsINode* aRootNode,
@@ -1013,18 +1014,16 @@ protected:
   /**
    * Check that aId is not empty and log a message to the console
    * service if it is.
    * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
    */
   static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
   nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
 
-  void DispatchContentLoadedEvents();
-
   void RetrieveRelevantHeaders(nsIChannel *aChannel);
 
   static PRBool TryChannelCharset(nsIChannel *aChannel,
                                   PRInt32& aCharsetSource,
                                   nsACString& aCharset);
   
   void UpdateLinkMap();
   // Call this before the document does something that will unbind all content.
@@ -1170,18 +1169,16 @@ protected:
   // True if this document has ever had an HTML or SVG <title> element
   // bound to it
   PRPackedBool mMayHaveTitleElement:1;
 
   PRPackedBool mHasWarnedAboutBoxObjects:1;
 
   PRPackedBool mDelayFrameLoaderInitialization:1;
 
-  PRPackedBool mSynchronousDOMContentLoaded:1;
-
   // If true, we have an input encoding.  If this is false, then the
   // document was created entirely in memory
   PRPackedBool mHaveInputEncoding:1;
 
   PRUint8 mXMLDeclarationBits;
 
   PRUint8 mDefaultElementType;
 
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -201,16 +201,24 @@ public:
    * queue.
    *
    * WARNING: This function will syncronously execute content scripts, so be
    * prepared that the world might change around you.
    */
   void EndDeferringScripts();
 
   /**
+   * Returns the number of pending scripts, deferred or not.
+   */
+  PRUint32 HasPendingOrCurrentScripts()
+  {
+    return mCurrentScript || GetFirstPendingRequest();
+  }
+
+  /**
    * Adds aURI to the preload list and starts loading it.
    *
    * @param aURI The URI of the external script.
    * @param aCharset The charset parameter for the script.
    * @param aType The type parameter for the script.
    */
   virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                           const nsAString &aType);
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -274,16 +274,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug455629.html \
 		bug455629-helper.svg \
 		test_bug473162-1.html \
 		test_bug473162-2.html \
 		test_XHRSendData.html \
 		file_XHRSendData.sjs \
 		file_XHRSendData_doc.xml \
 		file_XHRSendData_doc.xml^headers^ \
+		test_bug461555.html \
 		$(NULL)
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug461555.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=461555
+-->
+<head>
+  <title>Test for Bug 461555</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="done()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=461555">Mozilla Bug 461555</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+function writeIt(n) {
+  document.write("<span>" + n + "</span>");
+}
+
+var recur = 0;
+function externalScript() {
+  if (++recur == 3) {
+    return;
+  }
+
+  base = (recur-1) * 4
+
+  writeIt(7 + base);
+  s = document.createElement("script");
+  s.src = "data:text/plain,writeIt(" + (9+base) + ");writeIt(" + (10+base) + ");externalScript();";
+  document.body.appendChild(s);
+  writeIt(8 + base);
+}
+
+function done() {
+  nodes = document.getElementsByTagName('span');
+  is(nodes.length, 14, "wrong length");
+  for (i = 0; i < nodes.length; ++i) {
+    is(nodes[i].textContent, i+1, "wrong order");
+  }
+  SimpleTest.finish();
+}
+
+document.addEventListener("DOMContentLoaded", function() {
+  writeIt(3);
+}, false);
+
+writeIt(1);
+
+</script>
+<script defer>
+writeIt(4);
+</script>
+<script>
+writeIt(2);
+</script>
+<script defer src="data:text/plain,writeIt(5);writeIt(6);"></script>
+<script defer src="data:text/plain,externalScript();"></script>
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -179,16 +179,17 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContentSink
   NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
+  virtual PRBool ReadyToCallDidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
 
   // nsIHTMLContentSink
@@ -1831,16 +1832,22 @@ HTMLContentSink::DidBuildModel(void)
   
   mDocument->EndLoad();
 
   DropParserAndPerfHint();
 
   return NS_OK;
 }
 
+PRBool
+HTMLContentSink::ReadyToCallDidBuildModel()
+{
+  return ReadyToCallDidBuildModelImpl();
+}
+
 NS_IMETHODIMP
 HTMLContentSink::SetParser(nsIParser* aParser)
 {
   NS_PRECONDITION(aParser, "Should have a parser here!");
   mParser = aParser;
   return NS_OK;
 }
 
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -378,16 +378,22 @@ nsXMLContentSink::DidBuildModel()
     mDocument->EndLoad();
   }
 
   DropParserAndPerfHint();
 
   return NS_OK;
 }
 
+PRBool
+nsXMLContentSink::ReadyToCallDidBuildModel()
+{
+  return ReadyToCallDidBuildModelImpl();
+}
+
 NS_IMETHODIMP
 nsXMLContentSink::OnDocumentCreated(nsIDocument* aResultDocument)
 {
   NS_ENSURE_ARG(aResultDocument);
 
   nsCOMPtr<nsIContentViewer> contentViewer;
   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
   if (contentViewer) {
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -88,16 +88,17 @@ public:
                                                      nsContentSink)
 
   NS_DECL_NSIEXPATSINK
 
   // nsIContentSink
   NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
+  virtual PRBool ReadyToCallDidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);  
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
 
   // nsITransformObserver
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -535,20 +535,18 @@ nsXMLDocument::StartDocumentLoad(const c
 }
 
 void
 nsXMLDocument::EndLoad()
 {
   mChannelIsPending = PR_FALSE;
   mLoopingForSyncLoad = PR_FALSE;
 
-  mSynchronousDOMContentLoaded = (mLoadedAsData || mLoadedAsInteractiveData);
   nsDocument::EndLoad();
-  if (mSynchronousDOMContentLoaded) {
-    mSynchronousDOMContentLoaded = PR_FALSE;
+  if (mLoadedAsData || mLoadedAsInteractiveData) {
     nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
     // Generate a document load event for the case when an XML
     // document was loaded as pure data without any presentation
     // attached to it.
     nsEvent event(PR_TRUE, NS_LOAD);
     nsEventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nsnull,
                                 &event);
   }    
--- a/parser/htmlparser/public/nsIContentSink.h
+++ b/parser/htmlparser/public/nsIContentSink.h
@@ -51,18 +51,18 @@
  */
 #include "nsISupports.h"
 #include "nsStringGlue.h"
 #include "mozFlushType.h"
 
 class nsIParser;
 
 #define NS_ICONTENT_SINK_IID \
-{ 0x94ec4df1, 0x6885, 0x4b1f, \
- { 0x85, 0x10, 0xe3, 0x5f, 0x4f, 0x36, 0xea, 0xaa } }
+{ 0xcfa3643b, 0xee60, 0x4bf0, \
+  { 0xbc, 0x83, 0x49, 0x95, 0xdb, 0xbc, 0xda, 0x75 } }
 
 class nsIContentSink : public nsISupports {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID)
 
   /**
    * This method is called by the parser when it is entered from
@@ -84,16 +84,22 @@ public:
    * This method gets called when the parser concludes the process
    * of building the content model via the content sink.
    *
    * @update 5/7/98 gess
    */
   NS_IMETHOD DidBuildModel()=0;
 
   /**
+   * Thie method gets caller right before DidBuildModel is called.
+   * If false
+   */
+  virtual PRBool ReadyToCallDidBuildModel() { return PR_TRUE; };
+
+  /**
    * This method gets called when the parser gets i/o blocked,
    * and wants to notify the sink that it may be a while before
    * more data is available.
    *
    * @update 5/7/98 gess
    */
   NS_IMETHOD WillInterrupt(void)=0;
 
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -1520,17 +1520,18 @@ nsParser::WillBuildModel(nsString& aFile
  */
 nsresult
 nsParser::DidBuildModel(nsresult anErrorCode)
 {
   nsresult result = anErrorCode;
 
   if (IsComplete()) {
     if (mParserContext && !mParserContext->mPrevContext) {
-      if (mParserContext->mDTD) {
+      if (mParserContext->mDTD && mSink &&
+          mSink->ReadyToCallDidBuildModel()) {
         result = mParserContext->mDTD->DidBuildModel(anErrorCode,PR_TRUE,this,mSink);
       }
 
       //Ref. to bug 61462.
       mParserContext->mRequest = 0;
     }
   }