if (Substring(name, 0, 9).Equals(NS_LITERAL_STRING("<!DOCTYPE"))) {
nsCaseInsensitiveStringComparator ignoreCase; if (Substring(name, 0, 9).Equals(NS_LITERAL_STRING("<!DOCTYPE"), ignoreCase)) {
HTMLContentSink::AddDocTypeDecl(const nsIParserNode& aNode){  MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::AddDocTypeDecl()\n"));  MOZ_TIMER_START(mWatch);  nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(mHTMLDocument));  if (!doc) {    return NS_OK;  }  nsAutoString docTypeStr(aNode.GetText());  nsresult rv = NS_OK;  PRInt32 publicStart = docTypeStr.Find("PUBLIC", PR_TRUE);  PRInt32 systemStart = docTypeStr.Find("SYSTEM", PR_TRUE);  nsAutoString name, publicId, systemId;  if (publicStart >= 0 || systemStart >= 0) {    /*     * If we find the keyword 'PUBLIC' after the keyword 'SYSTEM' we assume     * that we got a system id that happens to contain the string "PUBLIC"     * and we ignore that as the start of the public id.     */    if (systemStart >= 0 && (publicStart > systemStart)) {      publicStart = -1;    }    /*     * We found 'PUBLIC' or 'SYSTEM' in the doctype, put everything before     * the first one of those in name.     */    docTypeStr.Mid(name, 0, publicStart >= 0 ? publicStart : systemStart);    if (publicStart >= 0) {      // We did find 'PUBLIC'      docTypeStr.Mid(publicId, publicStart + 6,                     docTypeStr.Length() - publicStart);      publicId.Trim(" \t\n\r");      // Strip quotes      PRUnichar ch = publicId.IsEmpty() ? '\0' : publicId.First();      PRBool hasQuote = PR_FALSE;      if (ch == '"' || ch == '\'') {        publicId.Cut(0, 1);        PRInt32 end = publicId.FindChar(ch);        if (end < 0) {          /*           * We didn't find an end quote, so just make sure we cut off           * the '>' on the end of the doctype declaration           */          end = publicId.FindChar('>');        } else {          hasQuote = PR_TRUE;        }        /*         * If we didn't find a closing quote or a '>' we leave publicId as         * it is.         */        if (end >= 0) {          publicId.Truncate(end);        }      } else {        // No quotes, ignore the public id        publicId.Truncate();      }      /*       * Make sure the 'SYSTEM' word we found is not inside the pubilc id       */      PRInt32 pos = docTypeStr.Find(publicId);      if (systemStart > 0) {        if (systemStart < pos + (PRInt32)publicId.Length()) {          systemStart = docTypeStr.Find("SYSTEM", PR_TRUE,                                        pos + publicId.Length());        }      }      /*       * If we didn't find 'SYSTEM' we tread everything after the public id       * as the system id.       */      if (systemStart < 0) {        // 1 is the end quote        systemStart = pos + publicId.Length() + (hasQuote ? 1 : 0);      }    }    if (systemStart >= 0) {      // We either found 'SYSTEM' or we have data after the public id      docTypeStr.Mid(systemId, systemStart,                     docTypeStr.Length() - systemStart);      // Strip off 'SYSTEM' if we have it.      if (Substring(systemId, 0, 6).Equals(NS_LITERAL_STRING("SYSTEM")))        systemId.Cut(0, 6);      systemId.Trim(" \t\n\r");      // Strip quotes      PRUnichar ch = systemId.IsEmpty() ? '\0' : systemId.First();      if (ch == '"' || ch == '\'') {        systemId.Cut(0, 1);        PRInt32 end = systemId.FindChar(ch);        if (end < 0) {          // We didn't find an end quote, then we just make sure we          // cut of the '>' on the end of the doctype declaration          end = systemId.FindChar('>');        }        // If we found an closing quote nor a '>' we truncate systemId        // at that length.        if (end >= 0) {          systemId.Truncate(end);        }      } else {        systemId.Truncate();      }    }  } else {    name.Assign(docTypeStr);  }  // Cut out "<!DOCTYPE" or "DOCTYPE" from the name.  if (Substring(name, 0, 9).Equals(NS_LITERAL_STRING("<!DOCTYPE"))) {    name.Cut(0, 9);  } else if (Substring(name, 0, 7).Equals(NS_LITERAL_STRING("DOCTYPE"))) {    name.Cut(0, 7);  }  name.Trim(" \t\n\r");  // Check if name contains whitespace chars. If it does and the first  // char is not a quote, we set the name to contain the characters  // before the whitespace  PRInt32 nameEnd = 0;  if (name.IsEmpty() || (name.First() != '"' && name.First() != '\'')) {    nameEnd = name.FindCharInSet(" \n\r\t");  }  // If we didn't find a public id we grab everything after the name  // and use that as public id.  if (publicStart < 0) {    name.Mid(publicId, nameEnd, name.Length() - nameEnd);    publicId.Trim(" \t\n\r");    PRUnichar ch = publicId.IsEmpty() ? '\0' : publicId.First();    if (ch == '"' || ch == '\'') {      publicId.Cut(0, 1);      PRInt32 publicEnd = publicId.FindChar(ch);      if (publicEnd < 0) {        publicEnd = publicId.FindChar('>');      }      if (publicEnd < 0) {        publicEnd = publicId.Length();      }      publicId.Truncate(publicEnd);    } else {      // No quotes, no public id      publicId.Truncate();    }  }  if (nameEnd >= 0) {    name.Truncate(nameEnd);  } else {    nameEnd = name.FindChar('>');    if (nameEnd >= 0) {      name.Truncate(nameEnd);    }  }  if (!publicId.IsEmpty() || !systemId.IsEmpty() || !name.IsEmpty()) {    nsCOMPtr<nsIDOMDocumentType> oldDocType;    nsCOMPtr<nsIDOMDocumentType> docType;    doc->GetDoctype(getter_AddRefs(oldDocType));    nsCOMPtr<nsIDOMDOMImplementation> domImpl;    rv = doc->GetImplementation(getter_AddRefs(domImpl));    if (NS_FAILED(rv) || !domImpl) {      return rv;    }    if (name.IsEmpty()) {      name.Assign(NS_LITERAL_STRING("HTML"));    }    rv = domImpl->CreateDocumentType(name, publicId, systemId,                                     getter_AddRefs(docType));    if (NS_FAILED(rv) || !docType) {      return rv;    }    nsCOMPtr<nsIDOMNode> tmpNode;    if (oldDocType) {      // If we already have a doctype we replace the old one.      rv = doc->ReplaceChild(oldDocType, docType, getter_AddRefs(tmpNode));    } else {      // If we don't already have one we insert it as the first child,      // this might not be 100% correct but since this is called from      // the content sink we assume that this is what we want.      nsCOMPtr<nsIDOMNode> firstChild;      doc->GetFirstChild(getter_AddRefs(firstChild));      // If the above fails it must be because we don't have any child      // nodes, then firstChild will be 0 and InsertBefore() will      // append      rv = doc->InsertBefore(docType, firstChild, getter_AddRefs(tmpNode));    }  }  MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::AddDocTypeDecl()\n"));  MOZ_TIMER_STOP(mWatch);  return rv;}