Commit dd41010b authored by Boris Zbarsky's avatar Boris Zbarsky
Browse files

Bug 1550524 part 2. Add an explicit StartExecutor method on nsHtml5Parser,...

Bug 1550524 part 2.  Add an explicit StartExecutor method on nsHtml5Parser, for use from document.open().  r=hsivonen

The code has mostly moved, but there are a few simplifications:

1) If !GetStreamParser(), then GetChannel() always returns null and hence we
never set isSrcdoc to true.  Which is good, because we don't want to apply the
special srcdoc-parsing rules to document.open() stuff.  So we just pass false
to setIsSrcdocDocument(): It's the same behavior as before, but a lot clearer.
I've confirmed that code coverage says the "isSrcdoc =
NS_IsSrcdocChannel(channel)" line is unreached in our tests.

2) In the document.write-after-document.open case, aContentType is now always
"text/html" (because that's what document.open sets mContentTypeForWriteCalls
to.  So the block checking for it not being "text/html" was dead code (also
confirmed via code coverage results) and I'm just removing it.

Differential Revision: https://phabricator.services.mozilla.com/D30751

--HG--
extra : moz-landing-system : lando
parent 0c6443c5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
<iframe></iframe>
<script>
  var doc = frames[0].document;
  doc.open();
  doc.open();
  doc.close();
</script>
+1 −0
Original line number Diff line number Diff line
@@ -89,5 +89,6 @@ asserts(0-4) load 1401726.html
load 1412173.html
load 1440523.html
load 1547057.html
load 1550524.html
load 1550881-1.html
load 1550881-2.html
+5 −0
Original line number Diff line number Diff line
@@ -1193,6 +1193,11 @@ Document* nsHTMLDocument::Open(const Optional<nsAString>& /* unused */,
          static_cast<ReferrerPolicy>(mReferrerPolicy));
    }
  }
  nsresult rv = parser->StartExecutor();
  if (NS_WARN_IF(NS_FAILED(rv))) {
    aError.Throw(rv);
    return nullptr;
  }

  // Some internal non-spec bookkeeping.
  mContentTypeForWriteCalls.AssignLiteral("text/html");
+21 −29
Original line number Diff line number Diff line
@@ -195,35 +195,7 @@ nsresult nsHtml5Parser::Parse(const nsAString& aSourceBuffer, void* aKey,
  mozilla::Unused << streamKungFuDeathGrip;  // Not used within function
  RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);

  if (!executor->HasStarted()) {
    NS_ASSERTION(!GetStreamParser(),
                 "Had stream parser but document.write started life cycle.");
    // This is the first document.write() on a document.open()ed document
    executor->SetParser(this);
    mTreeBuilder->setScriptingEnabled(executor->IsScriptEnabled());

    bool isSrcdoc = false;
    nsCOMPtr<nsIChannel> channel;
    rv = GetChannel(getter_AddRefs(channel));
    if (NS_SUCCEEDED(rv)) {
      isSrcdoc = NS_IsSrcdocChannel(channel);
    }
    mTreeBuilder->setIsSrcdocDocument(isSrcdoc);

    mTokenizer->start();
    executor->Start();
    if (!aContentType.EqualsLiteral("text/html")) {
      mTreeBuilder->StartPlainText();
      mTokenizer->StartPlainText();
    }
    /*
     * If you move the following line, be very careful not to cause
     * WillBuildModel to be called before the document has had its
     * script global object set.
     */
    rv = executor->WillBuildModel(eDTDMode_unknown);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  MOZ_RELEASE_ASSERT(executor->HasStarted());

  // Return early if the parser has processed EOF
  if (executor->IsComplete()) {
@@ -670,6 +642,26 @@ nsresult nsHtml5Parser::ParseUntilBlocked() {
  }
}

nsresult nsHtml5Parser::StartExecutor() {
  MOZ_ASSERT(!GetStreamParser(),
             "Had stream parser but document.write started life cycle.");
  // This is part of the setup document.open() does.
  RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
  executor->SetParser(this);
  mTreeBuilder->setScriptingEnabled(executor->IsScriptEnabled());

  mTreeBuilder->setIsSrcdocDocument(false);

  mTokenizer->start();
  executor->Start();

  /*
   * We know we're in document.open(), so our document must already
   * have a script global andthe WillBuildModel call is safe.
   */
  return executor->WillBuildModel(eDTDMode_unknown);
}

nsresult nsHtml5Parser::Initialize(mozilla::dom::Document* aDoc, nsIURI* aURI,
                                   nsISupports* aContainer,
                                   nsIChannel* aChannel) {
+7 −0
Original line number Diff line number Diff line
@@ -254,6 +254,13 @@ class nsHtml5Parser final : public nsIParser, public nsSupportsWeakReference {
   */
  nsresult ParseUntilBlocked();

  /**
   * Start our executor.  This is meant to be used from document.open() _only_
   * and does some work similar to what nsHtml5StreamParser::OnStartRequest does
   * for normal parses.
   */
  nsresult StartExecutor();

 private:
  virtual ~nsHtml5Parser();