nsresult nsMsgSearchOfflineMail::Search(bool *aDone)
{
  nsresult err = NS_OK;

  NS_ENSURE_ARG(aDone);
  nsresult dbErr = NS_OK;
  nsCOMPtr<nsIMsgDBHdr> msgDBHdr;
  nsMsgSearchBoolExpression *expressionTree = nullptr;

  const uint32_t kTimeSliceInMS = 200;

  *aDone = false;
  // Try to open the DB lazily. This will set up a parser if one is required
  if (!m_db)
    err = OpenSummaryFile ();
  if (!m_db)  // must be reparsing.
    return err;

  // Reparsing is unnecessary or completed
  if (NS_SUCCEEDED(err))
  {
    if (!m_listContext)
      dbErr = m_db->ReverseEnumerateMessages(getter_AddRefs(m_listContext));
    if (NS_SUCCEEDED(dbErr) && m_listContext)
    {
      PRIntervalTime startTime = PR_IntervalNow();
      while (!*aDone)  // we'll break out of the loop after kTimeSliceInMS milliseconds
      {
        nsCOMPtr<nsISupports> currentItem;

        dbErr = m_listContext->GetNext(getter_AddRefs(currentItem));
        if(NS_SUCCEEDED(dbErr))
        {
          msgDBHdr = do_QueryInterface(currentItem, &dbErr);
        }
        if (NS_FAILED(dbErr))
          *aDone = true; //###phil dbErr is dropped on the floor. just note that we did have an error so we'll clean up later
        else
        {
          bool match = false;
          nsAutoString nullCharset, folderCharset;
          GetSearchCharsets(nullCharset, folderCharset);
          NS_ConvertUTF16toUTF8 charset(folderCharset);
          // Is this message a hit?
          err = MatchTermsForSearch (msgDBHdr, m_searchTerms, charset.get(), m_scope, m_db, &expressionTree, &match);
          // Add search hits to the results list
          if (NS_SUCCEEDED(err) && match)
          {
            AddResultElement (msgDBHdr);
          }
          PRIntervalTime elapsedTime = PR_IntervalNow() - startTime;
          // check if more than kTimeSliceInMS milliseconds have elapsed in this time slice started
          if (PR_IntervalToMilliseconds(elapsedTime) > kTimeSliceInMS)
            break;
        }
      }
    }
  }
  else
    *aDone = true; // we couldn't open up the DB. This is an unrecoverable error so mark the scope as done.

  delete expressionTree;

  // in the past an error here would cause an "infinite" search because the url would continue to run...
  // i.e. if we couldn't open the database, it returns an error code but the caller of this function says, oh,
  // we did not finish so continue...what we really want is to treat this current scope as done
  if (*aDone)
    CleanUpScope(); // Do clean up for end-of-scope processing
  return err;
}
nsresult
nsXFormsMDGEngine::AttachInheritance(nsCOMArray<nsIDOMNode> *aSet,
                                     nsIDOMNode             *aSrc,
                                     PRBool                  aState,
                                     eFlag_t                 aStateFlag)
{
  NS_ENSURE_ARG(aSrc);
  
  nsCOMPtr<nsIDOMNode> node;
  nsresult rv;
  PRBool updateNode = PR_FALSE;

  nsCOMPtr<nsIDOMNodeList> childList;
  rv = aSrc->GetChildNodes(getter_AddRefs(childList));
  NS_ENSURE_SUCCESS(rv, rv);

  PRUint32 childCount;
  rv = childList->GetLength(&childCount);
  NS_ENSURE_SUCCESS(rv, rv);

  for (PRUint32 i = 0; i < childCount; i++) {
    rv = childList->Item(i, getter_AddRefs(node));
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);

    nsXFormsNodeState *ns = GetNCNodeState(node);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

    PRBool curState = ns->Test(aStateFlag);    

    if (aStateFlag == eFlag_RELEVANT) {
      if (!aState) { // The nodes are getting irrelevant
        if (ns->Test(eFlag_INHERITED_RELEVANT) && curState) {
          ns->Set(eFlag_INHERITED_RELEVANT, PR_FALSE);
          ns->Set(eFlag_DISPATCH_RELEVANT_CHANGED, PR_TRUE);
          updateNode = PR_TRUE;
        }
      } else { // The nodes are becoming relevant
        if (curState) {
          // Relevant has changed from inheritance
          ns->Set(eFlag_DISPATCH_RELEVANT_CHANGED, PR_TRUE);
          ns->Set(eFlag_INHERITED_RELEVANT, PR_TRUE);
          updateNode = PR_TRUE;
        }
      }
    } else if (aStateFlag == eFlag_READONLY) {
      if (aState) { // The nodes are getting readonly
        if (!ns->Test(eFlag_INHERITED_READONLY) && curState == PR_FALSE) {
          ns->Set(eFlag_INHERITED_READONLY | eFlag_DISPATCH_READONLY_CHANGED,
                  PR_TRUE);
          updateNode = PR_TRUE;
        }
      } else { // The nodes are getting readwrite
        if (curState) {
          ns->Set(eFlag_DISPATCH_READONLY_CHANGED, PR_TRUE);
          ns->Set(eFlag_INHERITED_READONLY, PR_FALSE);
          updateNode = PR_TRUE;
        }
      }
    }
    
    if (updateNode) {
      rv = AttachInheritance(aSet, node, aState, aStateFlag);
      NS_ENSURE_SUCCESS(rv, rv);
      NS_ENSURE_TRUE(aSet->AppendObject(node), NS_ERROR_FAILURE);
      updateNode = PR_FALSE;
    }
  }

  return NS_OK;
}
nsresult
nsXFormsMDGEngine::Recalculate(nsCOMArray<nsIDOMNode> *aChangedNodes)
{
  NS_ENSURE_ARG(aChangedNodes);

#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::Recalculate(aChangedNodes=|%d|)\n",
         aChangedNodes->Count());
#endif

  // XXX: There's something wrong with the marking of nodes, as we assume that
  // recalculate will always be called first. bug 338146
  nsresult rv = HandleMarkedNodes(aChangedNodes);
  NS_ENSURE_SUCCESS(rv, rv);
  
  PRBool res = PR_TRUE;

  mFirstCalculate = mJustRebuilt;

#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif
  
  // Go through all dirty nodes in the graph
  nsXFormsMDGNode* g;
  for (PRInt32 i = 0; i < mGraph.Count(); ++i) {
    g = static_cast<nsXFormsMDGNode*>(mGraph[i]);

    if (!g) {
      NS_WARNING("nsXFormsMDGEngine::Calculate(): Empty node in graph!!!");
      continue;
    }

    NS_ASSERTION(g->mCount == 0,
                 "nsXFormsMDGEngine::Calculate(): Graph node with mCount != 0");

#ifdef DEBUG_XF_MDG
    nsAutoString domNodeName;
    g->mContextNode->GetNodeName(domNodeName);

    printf("\tNode #%d: This=%p, Dirty=%d, DynFunc=%d, Type=%d, Count=%d, Suc=%d, CSize=%d, CPos=%d, Next=%p, HasExpr=%d, domnode=%s\n",
           i, (void*) g, g->IsDirty(), g->mDynFunc, g->mType,
           g->mCount, g->mSuc.Count(), g->mContextSize, g->mContextPosition,
           (void*) g->mNext, g->HasExpr(), NS_ConvertUTF16toUTF8(domNodeName).get());
#endif

    // Ignore node if it is not dirty
    if (!g->IsDirty()) {
      continue;
    }

    nsXFormsNodeState* ns = GetNCNodeState(g->mContextNode);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);
    
    PRBool constraint = PR_TRUE;
    PRBool conChanged;
    // Find MIP-type and handle it accordingly
    switch (g->mType) {
    case eModel_calculate:
      if (g->HasExpr()) {
        nsCOMPtr<nsISupports> result;
        rv = g->mExpression->EvaluateWithContext(g->mContextNode,
                                                 g->mContextPosition,
                                                 g->mContextSize,
                                                 nsIDOMXPathResult::STRING_TYPE,
                                                 nsnull,
                                                 getter_AddRefs(result));
        NS_ENSURE_SUCCESS(rv, rv);

        nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(result);
        NS_ENSURE_STATE(xpath_res);
        
        nsAutoString nodeval;
        rv = xpath_res->GetStringValue(nodeval);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = SetNodeValueInternal(g->mContextNode,
                                  nodeval,
                                  PR_FALSE,
                                  PR_TRUE);
        if (NS_SUCCEEDED(rv)) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }

        ns->Set(eFlag_DISPATCH_VALUE_CHANGED, PR_TRUE);
      }

      break;
      
    case eModel_constraint:
      if (g->HasExpr()) {
        rv = BooleanExpression(g, constraint);
        NS_ENSURE_SUCCESS(rv, rv);
      }

      conChanged = ns->IsConstraint() != constraint;
        // On the first calculate after a rebuild (mFirstCalculate) we also
        // add constraints to the set of changed nodes to trigger validation
        // of type information if present.
      if (conChanged || mFirstCalculate) {
        if (conChanged) {
          ns->Set(eFlag_CONSTRAINT, constraint);
          ns->Set(eFlag_DISPATCH_VALID_CHANGED, PR_TRUE);
        }
        NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                       NS_ERROR_FAILURE);
      }

      break;

    case eModel_readonly:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_READONLY,
                                       eFlag_DISPATCH_READONLY_CHANGED,
                                       eFlag_INHERITED_READONLY,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_relevant:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_RELEVANT,
                                       eFlag_DISPATCH_RELEVANT_CHANGED,
                                       eFlag_INHERITED_RELEVANT,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_required:
      if (g->HasExpr()) {
        PRBool didChange;
        rv = ComputeMIP(eFlag_REQUIRED,
                        eFlag_DISPATCH_REQUIRED_CHANGED,
                        g,
                        didChange);
        NS_ENSURE_SUCCESS(rv, rv);
      
        if (didChange) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }
      }
      break;
      
    default:
      NS_ERROR("There was no expression which matched\n");
      res = PR_FALSE;
      break;
    }

    // Mark successors dirty
    nsXFormsMDGNode* sucnode;
    for (PRInt32 j = 0; j < g->mSuc.Count(); ++j) {
      sucnode = static_cast<nsXFormsMDGNode*>(g->mSuc[j]);
      if (!sucnode) {
        NS_ERROR("nsXFormsMDGEngine::Calculate(): Node has NULL successor!");
        return NS_ERROR_FAILURE;
      }
      sucnode->MarkDirty();
    }

    g->MarkClean();
  }
  nsXFormsUtils::MakeUniqueAndSort(aChangedNodes);
  
#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif

  return res;
}
NS_IMETHODIMP 
nsNSSCertificateDB::ImportCertsFromFile(nsISupports *aToken, 
                                        nsILocalFile *aFile,
                                        PRUint32 aType)
{
  NS_ENSURE_ARG(aFile);
  switch (aType) {
    case nsIX509Cert::CA_CERT:
    case nsIX509Cert::EMAIL_CERT:
    case nsIX509Cert::SERVER_CERT:
      // good
      break;
    
    default:
      // not supported (yet)
      return NS_ERROR_FAILURE;
  }

  nsresult rv;
  PRFileDesc *fd = nsnull;

  rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);

  if (NS_FAILED(rv))
    return rv;

  if (!fd)
    return NS_ERROR_FAILURE;

  PRFileInfo file_info;
  if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &file_info))
    return NS_ERROR_FAILURE;
  
  unsigned char *buf = new unsigned char[file_info.size];
  if (!buf)
    return NS_ERROR_OUT_OF_MEMORY;
  
  PRInt32 bytes_obtained = PR_Read(fd, buf, file_info.size);
  PR_Close(fd);
  
  if (bytes_obtained != file_info.size)
    rv = NS_ERROR_FAILURE;
  else {
	  nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();

    switch (aType) {
      case nsIX509Cert::CA_CERT:
        rv = ImportCertificates(buf, bytes_obtained, aType, cxt);
        break;
        
      case nsIX509Cert::SERVER_CERT:
        rv = ImportServerCertificate(buf, bytes_obtained, cxt);
        break;

      case nsIX509Cert::EMAIL_CERT:
        rv = ImportEmailCertificate(buf, bytes_obtained, cxt);
        break;
      
      default:
        break;
    }
  }

  delete [] buf;
  return rv;  
}
Exemple #5
0
//
// Find:
// Take nodes out of the tree with NextNode,
// until null (NextNode will return 0 at the end of our range).
//
NS_IMETHODIMP
nsFind::Find(const PRUnichar *aPatText, nsIDOMRange* aSearchRange,
             nsIDOMRange* aStartPoint, nsIDOMRange* aEndPoint,
             nsIDOMRange** aRangeRet)
{
#ifdef DEBUG_FIND
  printf("============== nsFind::Find('%s'%s, %p, %p, %p)\n",
         NS_LossyConvertUTF16toASCII(aPatText).get(),
         mFindBackward ? " (backward)" : " (forward)",
         (void*)aSearchRange, (void*)aStartPoint, (void*)aEndPoint);
#endif

  NS_ENSURE_ARG(aSearchRange);
  NS_ENSURE_ARG(aStartPoint);
  NS_ENSURE_ARG(aEndPoint);
  NS_ENSURE_ARG_POINTER(aRangeRet);
  *aRangeRet = 0;

  if (!aPatText)
    return NS_ERROR_NULL_POINTER;

  ResetAll();

  nsAutoString patAutoStr(aPatText);
  if (!mCaseSensitive)
    ToLowerCase(patAutoStr);

  // Ignore soft hyphens in the pattern  
  static const char kShy[] = { char(CH_SHY), 0 };
  patAutoStr.StripChars(kShy);

  const PRUnichar* patStr = patAutoStr.get();
  PRInt32 patLen = patAutoStr.Length() - 1;

  // current offset into the pattern -- reset to beginning/end:
  PRInt32 pindex = (mFindBackward ? patLen : 0);

  // Current offset into the fragment
  PRInt32 findex = 0;

  // Direction to move pindex and ptr*
  int incr = (mFindBackward ? -1 : 1);

  nsCOMPtr<nsIContent> tc;
  const nsTextFragment *frag = nsnull;
  PRInt32 fragLen = 0;

  // Pointers into the current fragment:
  const PRUnichar *t2b = nsnull;
  const char      *t1b = nsnull;

  // Keep track of when we're in whitespace:
  // (only matters when we're matching)
  PRBool inWhitespace = PR_FALSE;

  // Have we extended a search past the endpoint?
  PRBool continuing = PR_FALSE;

  // Place to save the range start point in case we find a match:
  nsCOMPtr<nsIDOMNode> matchAnchorNode;
  PRInt32 matchAnchorOffset = 0;

  // Get the end point, so we know when to end searches:
  nsCOMPtr<nsIDOMNode> endNode;
  PRInt32 endOffset;
  aEndPoint->GetEndContainer(getter_AddRefs(endNode));
  aEndPoint->GetEndOffset(&endOffset);

  PRUnichar prevChar = 0;
  while (1)
  {
#ifdef DEBUG_FIND
    printf("Loop ...\n");
#endif

    // If this is our first time on a new node, reset the pointers:
    if (!frag)
    {

      tc = nsnull;
      NextNode(aSearchRange, aStartPoint, aEndPoint, PR_FALSE);
      if (!mIterNode)    // Out of nodes
      {
        // Are we in the middle of a match?
        // If so, try again with continuation.
        if (matchAnchorNode && !continuing)
          NextNode(aSearchRange, aStartPoint, aEndPoint, PR_TRUE);

        // Reset the iterator, so this nsFind will be usable if
        // the user wants to search again (from beginning/end).
        ResetAll();
        return NS_OK;
      }

      // We have a new text content.  If its block parent is different
      // from the block parent of the last text content, then we
      // need to clear the match since we don't want to find
      // across block boundaries.
      nsCOMPtr<nsIDOMNode> blockParent;
      GetBlockParent(mIterNode, getter_AddRefs(blockParent));
#ifdef DEBUG_FIND
      printf("New node: old blockparent = %p, new = %p\n",
             (void*)mLastBlockParent.get(), (void*)blockParent.get());
#endif
      if (blockParent != mLastBlockParent)
      {
#ifdef DEBUG_FIND
        printf("Different block parent!\n");
#endif
        mLastBlockParent = blockParent;
        // End any pending match:
        matchAnchorNode = nsnull;
        matchAnchorOffset = 0;
        pindex = (mFindBackward ? patLen : 0);
        inWhitespace = PR_FALSE;
      }
 
      // Get the text content:
      tc = do_QueryInterface(mIterNode);
      if (!tc || !(frag = tc->GetText())) // Out of nodes
      {
        mIterator = nsnull;
        mLastBlockParent = 0;
        ResetAll();
        return NS_OK;
      }

      fragLen = frag->GetLength();

      // Set our starting point in this node.
      // If we're going back to the anchor node, which means that we
      // just ended a partial match, use the saved offset:
      if (mIterNode == matchAnchorNode)
        findex = matchAnchorOffset + (mFindBackward ? 1 : 0);

      // mIterOffset, if set, is the range's idea of an offset,
      // and points between characters.  But when translated
      // to a string index, it points to a character.  If we're
      // going backward, this is one character too late and
      // we'll match part of our previous pattern.
      else if (mIterOffset >= 0)
        findex = mIterOffset - (mFindBackward ? 1 : 0);

      // Otherwise, just start at the appropriate end of the fragment:
      else if (mFindBackward)
        findex = fragLen - 1;
      else
        findex = 0;

      // Offset can only apply to the first node:
      mIterOffset = -1;

      // If this is outside the bounds of the string, then skip this node:
      if (findex < 0 || findex > fragLen-1)
      {
#ifdef DEBUG_FIND
        printf("At the end of a text node -- skipping to the next\n");
#endif
        frag = 0;
        continue;
      }

#ifdef DEBUG_FIND
      printf("Starting from offset %d\n", findex);
#endif
      if (frag->Is2b())
      {
        t2b = frag->Get2b();
        t1b = nsnull;
#ifdef DEBUG_FIND
        nsAutoString str2(t2b, fragLen);
        printf("2 byte, '%s'\n", NS_LossyConvertUTF16toASCII(str2).get());
#endif
      }
      else
      {
        t1b = frag->Get1b();
        t2b = nsnull;
#ifdef DEBUG_FIND
        nsCAutoString str1(t1b, fragLen);
        printf("1 byte, '%s'\n", str1.get());
#endif
      }
    }
    else // still on the old node
    {
      // Still on the old node.  Advance the pointers,
      // then see if we need to pull a new node.
      findex += incr;
#ifdef DEBUG_FIND
      printf("Same node -- (%d, %d)\n", pindex, findex);
#endif
      if (mFindBackward ? (findex < 0) : (findex >= fragLen))
      {
#ifdef DEBUG_FIND
        printf("Will need to pull a new node: mAO = %d, frag len=%d\n",
               matchAnchorOffset, fragLen);
#endif
        // Done with this node.  Pull a new one.
        frag = nsnull;
        continue;
      }
    }

    // Have we gone past the endpoint yet?
    // If we have, and we're not in the middle of a match, return.
    if (mIterNode == endNode && !continuing &&
        ((mFindBackward && (findex < endOffset)) ||
         (!mFindBackward && (findex > endOffset))))
    {
      ResetAll();
      return NS_OK;
    }

    // The two characters we'll be comparing:
    PRUnichar c = (t2b ? t2b[findex] : CHAR_TO_UNICHAR(t1b[findex]));
    PRUnichar patc = patStr[pindex];

#ifdef DEBUG_FIND
    printf("Comparing '%c'=%x to '%c' (%d of %d), findex=%d%s\n",
           (char)c, (int)c, patc, pindex, patLen, findex,
           inWhitespace ? " (inWhitespace)" : "");
#endif

    // Do we need to go back to non-whitespace mode?
    // If inWhitespace, then this space in the pat str
    // has already matched at least one space in the document.
    if (inWhitespace && !IsSpace(c))
    {
      inWhitespace = PR_FALSE;
      pindex += incr;
#ifdef DEBUG
      // This shouldn't happen -- if we were still matching, and we
      // were at the end of the pat string, then we should have
      // caught it in the last iteration and returned success.
      if (OVERFLOW_PINDEX)
        NS_ASSERTION(PR_FALSE, "Missed a whitespace match\n");
#endif
      patc = patStr[pindex];
    }
    if (!inWhitespace && IsSpace(patc))
      inWhitespace = PR_TRUE;

    // convert to lower case if necessary
    else if (!inWhitespace && !mCaseSensitive && IsUpperCase(c))
      c = ToLowerCase(c);

    // ignore soft hyphens in the document
    if (c == CH_SHY)
      continue;

    // a '\n' between CJ characters is ignored
    if (pindex != (mFindBackward ? patLen : 0) && c != patc && !inWhitespace) {
      if (c == '\n' && t2b && IS_CJ_CHAR(prevChar)) {
        PRInt32 nindex = findex + incr;
        if (mFindBackward ? (nindex >= 0) : (nindex < fragLen)) {
          if (IS_CJ_CHAR(t2b[nindex]))
            continue;
        }
      }
    }

    // Compare
    if ((c == patc) || (inWhitespace && IsSpace(c)))
    {
      prevChar = c;
#ifdef DEBUG_FIND
      if (inWhitespace)
        printf("YES (whitespace)(%d of %d)\n", pindex, patLen);
      else
        printf("YES! '%c' == '%c' (%d of %d)\n", c, patc, pindex, patLen);
#endif

      // Save the range anchors if we haven't already:
      if (!matchAnchorNode) {
        matchAnchorNode = mIterNode;
        matchAnchorOffset = findex;
      }

      // Are we done?
      if (DONE_WITH_PINDEX)
        // Matched the whole string!
      {
#ifdef DEBUG_FIND
        printf("Found a match!\n");
#endif

        // Make the range:
        nsCOMPtr<nsIDOMNode> startParent;
        nsCOMPtr<nsIDOMNode> endParent;
        nsCOMPtr<nsIDOMRange> range = CreateRange();
        if (range)
        {
          PRInt32 matchStartOffset, matchEndOffset;
          // convert char index to range point:
          PRInt32 mao = matchAnchorOffset + (mFindBackward ? 1 : 0);
          if (mFindBackward)
          {
            startParent = do_QueryInterface(tc);
            endParent = matchAnchorNode;
            matchStartOffset = findex;
            matchEndOffset = mao;
          }
          else
          {
            startParent = matchAnchorNode;
            endParent = do_QueryInterface(tc);
            matchStartOffset = mao;
            matchEndOffset = findex+1;
          }
          if (startParent && endParent && 
              IsVisibleNode(startParent) && IsVisibleNode(endParent))
          {
            range->SetStart(startParent, matchStartOffset);
            range->SetEnd(endParent, matchEndOffset);
            *aRangeRet = range.get();
            NS_ADDREF(*aRangeRet);
          }
          else {
            startParent = nsnull; // This match is no good -- invisible or bad range
          }
        }

        if (startParent) {
          // If startParent == nsnull, we didn't successfully make range
          // or, we didn't make a range because the start or end node were invisible
          // Reset the offset to the other end of the found string:
          mIterOffset = findex + (mFindBackward ? 1 : 0);
  #ifdef DEBUG_FIND
          printf("mIterOffset = %d, mIterNode = ", mIterOffset);
          DumpNode(mIterNode);
  #endif

          ResetAll();
          return NS_OK;
        }
        matchAnchorNode = nsnull;  // This match is no good, continue on in document
      }

      if (matchAnchorNode) {
        // Not done, but still matching.
        // Advance and loop around for the next characters.
        // But don't advance from a space to a non-space:
        if (!inWhitespace || DONE_WITH_PINDEX || IsSpace(patStr[pindex+incr]))
        {
          pindex += incr;
          inWhitespace = PR_FALSE;
#ifdef DEBUG_FIND
          printf("Advancing pindex to %d\n", pindex);
#endif
        }
      
        continue;
      }
    }

#ifdef DEBUG_FIND
    printf("NOT: %c == %c\n", c, patc);
#endif
    // If we were continuing, then this ends our search.
    if (continuing) {
      ResetAll();
      return NS_OK;
    }

    // If we didn't match, go back to the beginning of patStr,
    // and set findex back to the next char after
    // we started the current match.
    if (matchAnchorNode)    // we're ending a partial match
    {
      findex = matchAnchorOffset;
      mIterOffset = matchAnchorOffset;
          // +incr will be added to findex when we continue

      // Are we going back to a previous node?
      if (matchAnchorNode != mIterNode)
      {
        nsCOMPtr<nsIContent> content (do_QueryInterface(matchAnchorNode));
        nsresult rv = NS_ERROR_UNEXPECTED;
        if (content)
          rv = mIterator->PositionAt(content);
        frag = 0;
        NS_ASSERTION(NS_SUCCEEDED(rv), "Text content wasn't nsIContent!");
#ifdef DEBUG_FIND
        printf("Repositioned anchor node\n");
#endif
      }
#ifdef DEBUG_FIND
      printf("Ending a partial match; findex -> %d, mIterOffset -> %d\n",
             findex, mIterOffset);
#endif
    }
    matchAnchorNode = nsnull;
    matchAnchorOffset = 0;
    inWhitespace = PR_FALSE;
    pindex = (mFindBackward ? patLen : 0);
#ifdef DEBUG_FIND
    printf("Setting findex back to %d, pindex to %d\n", findex, pindex);
           
#endif
  } // end while loop

  // Out of nodes, and didn't match.
  ResetAll();
  return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::DownloadUpdates(
  const nsACString &aRequestTables,
  const nsACString &aRequestBody,
  const nsACString &aUpdateUrl,
  nsIUrlClassifierCallback *aSuccessCallback,
  nsIUrlClassifierCallback *aUpdateErrorCallback,
  nsIUrlClassifierCallback *aDownloadErrorCallback,
  bool *_retval)
{
  NS_ENSURE_ARG(aSuccessCallback);
  NS_ENSURE_ARG(aUpdateErrorCallback);
  NS_ENSURE_ARG(aDownloadErrorCallback);

  if (mIsUpdating) {
    LOG(("Already updating, queueing update %s from %s", aRequestBody.Data(),
         aUpdateUrl.Data()));
    *_retval = false;
    PendingRequest *request = mPendingRequests.AppendElement();
    request->mTables = aRequestTables;
    request->mRequest = aRequestBody;
    request->mUrl = aUpdateUrl;
    request->mSuccessCallback = aSuccessCallback;
    request->mUpdateErrorCallback = aUpdateErrorCallback;
    request->mDownloadErrorCallback = aDownloadErrorCallback;
    return NS_OK;
  }

  if (aUpdateUrl.IsEmpty()) {
    NS_ERROR("updateUrl not set");
    return NS_ERROR_NOT_INITIALIZED;
  }

  nsresult rv;

  if (!mInitialized) {
    // Add an observer for shutdown so we can cancel any pending list
    // downloads.  quit-application is the same event that the download
    // manager listens for and uses to cancel pending downloads.
    nsCOMPtr<nsIObserverService> observerService =
      mozilla::services::GetObserverService();
    if (!observerService)
      return NS_ERROR_FAILURE;

    observerService->AddObserver(this, gQuitApplicationMessage, false);

    mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    mInitialized = true;
  }

  rv = mDBService->BeginUpdate(this, aRequestTables);
  if (rv == NS_ERROR_NOT_AVAILABLE) {
    LOG(("Service busy, already updating, queuing update %s from %s",
         aRequestBody.Data(), aUpdateUrl.Data()));
    *_retval = false;
    PendingRequest *request = mPendingRequests.AppendElement();
    request->mTables = aRequestTables;
    request->mRequest = aRequestBody;
    request->mUrl = aUpdateUrl;
    request->mSuccessCallback = aSuccessCallback;
    request->mUpdateErrorCallback = aUpdateErrorCallback;
    request->mDownloadErrorCallback = aDownloadErrorCallback;
    return NS_OK;
  }

  if (NS_FAILED(rv)) {
    return rv;
  }

  mSuccessCallback = aSuccessCallback;
  mUpdateErrorCallback = aUpdateErrorCallback;
  mDownloadErrorCallback = aDownloadErrorCallback;

  mIsUpdating = true;
  *_retval = true;

  LOG(("FetchUpdate: %s", aUpdateUrl.Data()));
  //LOG(("requestBody: %s", aRequestBody.Data()));

  return FetchUpdate(aUpdateUrl, aRequestBody, EmptyCString());
}
NS_IMETHODIMP
nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
                                       PRUint32 aContextPosition,
                                       PRUint32 aContextSize,
                                       PRUint16 aType,
                                       nsISupports *aInResult,
                                       nsISupports **aResult)
{
    nsCOMPtr<nsINode> context = do_QueryInterface(aContextNode);
    NS_ENSURE_ARG(context);

    if (aContextPosition > aContextSize)
        return NS_ERROR_FAILURE;

    if (!nsContentUtils::CanCallerAccess(aContextNode))
        return NS_ERROR_DOM_SECURITY_ERR;

    if (mDocument && mDocument != aContextNode) {
        nsCOMPtr<nsIDOMDocument> contextDocument;
        aContextNode->GetOwnerDocument(getter_AddRefs(contextDocument));

        if (mDocument != contextDocument) {
            return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
        }
    }

    nsresult rv;
    PRUint16 nodeType;
    rv = aContextNode->GetNodeType(&nodeType);
    NS_ENSURE_SUCCESS(rv, rv);

    if (nodeType == nsIDOMNode::TEXT_NODE ||
        nodeType == nsIDOMNode::CDATA_SECTION_NODE) {
        nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode);
        NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE);

        if (textNode) {
            PRUint32 textLength;
            textNode->GetLength(&textLength);
            if (textLength == 0)
                return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
        }

        // XXX Need to get logical XPath text node for CDATASection
        //     and Text nodes.
    }
    else if (nodeType != nsIDOMNode::DOCUMENT_NODE &&
             nodeType != nsIDOMNode::ELEMENT_NODE &&
             nodeType != nsIDOMNode::ATTRIBUTE_NODE &&
             nodeType != nsIDOMNode::COMMENT_NODE &&
             nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE &&
             nodeType != nsIDOMXPathNamespace::XPATH_NAMESPACE_NODE) {
        return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    }

    NS_ENSURE_ARG(aResult);
    *aResult = nsnull;

    nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode));
    if (!contextNode) {
        return NS_ERROR_OUT_OF_MEMORY;
    }

    EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
                             mRecycler);
    nsRefPtr<txAExprResult> exprResult;
    rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
    NS_ENSURE_SUCCESS(rv, rv);

    PRUint16 resultType = aType;
    if (aType == nsIDOMXPathResult::ANY_TYPE) {
        short exprResultType = exprResult->getResultType();
        switch (exprResultType) {
            case txAExprResult::NUMBER:
                resultType = nsIDOMXPathResult::NUMBER_TYPE;
                break;
            case txAExprResult::STRING:
                resultType = nsIDOMXPathResult::STRING_TYPE;
                break;
            case txAExprResult::BOOLEAN:
                resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
                break;
            case txAExprResult::NODESET:
                resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
                break;
            case txAExprResult::RESULT_TREE_FRAGMENT:
                NS_ERROR("Can't return a tree fragment!");
                return NS_ERROR_FAILURE;
        }
    }

    // We need a result object and it must be our implementation.
    nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
    if (!xpathResult) {
        // Either no aInResult or not one of ours.
        xpathResult = new nsXPathResult();
        NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
    }
    rv = xpathResult->SetExprResult(exprResult, resultType, context);
    NS_ENSURE_SUCCESS(rv, rv);

    return CallQueryInterface(xpathResult, aResult);
}
NS_IMETHODIMP 
nsHTMLContentSerializer::AppendText(nsIDOMText* aText, 
                                    PRInt32 aStartOffset,
                                    PRInt32 aEndOffset,
                                    nsAString& aStr)
{
  NS_ENSURE_ARG(aText);

  if (mNeedLineBreaker) {
    mNeedLineBreaker = PR_FALSE;

    nsCOMPtr<nsIDOMDocument> domDoc;
    aText->GetOwnerDocument(getter_AddRefs(domDoc));
    nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
    if (document) {
      mLineBreaker = document->GetLineBreaker();
    }

    if (!mLineBreaker) {
      nsresult rv;
      nsCOMPtr<nsILineBreakerFactory> lf(do_GetService(kLWBrkCID, &rv));
      if (NS_SUCCEEDED(rv)) {
        rv = lf->GetBreaker(EmptyString(), getter_AddRefs(mLineBreaker));
        // Ignore result value.
        // If we are unable to obtain a line breaker,
        // we will use our simple fallback logic.
      }
    }
  }

  nsAutoString data;

  nsresult rv;
  rv = AppendTextData((nsIDOMNode*)aText, aStartOffset, 
                      aEndOffset, data, PR_TRUE, PR_FALSE);
  if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;

  if (mPreLevel > 0) {
    AppendToStringConvertLF(data, aStr);
  }
  else if (mFlags & nsIDocumentEncoder::OutputRaw) {
    PRInt32 lastNewlineOffset = data.RFindChar('\n');
    AppendToString(data, aStr);
    if (lastNewlineOffset != kNotFound)
      mColPos = data.Length() - lastNewlineOffset;
  }
  else if (!mDoFormat) {
    PRInt32 lastNewlineOffset = kNotFound;
    PRBool hasLongLines = HasLongLines(data, lastNewlineOffset);
    if (hasLongLines) {
      // We have long lines, rewrap
      AppendToStringWrapped(data, aStr, PR_FALSE);
      if (lastNewlineOffset != kNotFound)
        mColPos = data.Length() - lastNewlineOffset;
    }
    else {
      AppendToStringConvertLF(data, aStr);
    }
  }
  else {
    AppendToStringWrapped(data, aStr, PR_FALSE);
  }

  return NS_OK;
}
NS_IMETHODIMP
nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
                                            PRBool aHasChildren,
                                            nsAString& aStr)
{
  NS_ENSURE_ARG(aElement);
  
  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  if (!content) return NS_ERROR_FAILURE;
  
  // The _moz_dirty attribute is emitted by the editor to
  // indicate that this element should be pretty printed
  // even if we're not in pretty printing mode
  PRBool hasDirtyAttr = content->HasAttr(kNameSpaceID_None,
                                         nsLayoutAtoms::mozdirty);

  nsIAtom *name = content->Tag();

  if (name == nsHTMLAtoms::br && mPreLevel > 0
      && (mFlags & nsIDocumentEncoder::OutputNoFormattingInPre)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
    return NS_OK;
  }

  if (name == nsHTMLAtoms::body) {
    mInBody = PR_TRUE;
  }

  if (LineBreakBeforeOpen(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
    mAddSpace = PR_FALSE;
  }
  else if (mAddSpace) {
    AppendToString(PRUnichar(' '), aStr);
    mAddSpace = PR_FALSE;
  }
  else {
    MaybeAddNewline(aStr);
  }
  // Always reset to avoid false newlines in case MaybeAddNewline wasn't
  // called
  mAddNewline = PR_FALSE;

  StartIndentation(name, hasDirtyAttr, aStr);

  if (name == nsHTMLAtoms::pre ||
      name == nsHTMLAtoms::script ||
      name == nsHTMLAtoms::style) {
    mPreLevel++;
  }
  
  AppendToString(kLessThan, aStr);

  nsAutoString nameStr;
  name->ToString(nameStr);
  AppendToString(nameStr.get(), -1, aStr);

  // Need to keep track of OL and LI elements in order to get ordinal number 
  // for the LI.
  if (mIsCopying && name == nsHTMLAtoms::ol){
    // We are copying and current node is an OL;
    // Store it's start attribute value in olState->startVal.
    nsAutoString start;
    PRInt32 startAttrVal = 0;
    aElement->GetAttribute(NS_LITERAL_STRING("start"), start);
    if (!start.IsEmpty()){
      PRInt32 rv = 0;
      startAttrVal = start.ToInteger(&rv);
      //If OL has "start" attribute, first LI element has to start with that value
      //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
      //In failure of ToInteger(), default StartAttrValue to 0.
      if (NS_SUCCEEDED(rv))
        startAttrVal--; 
      else
        startAttrVal = 0;
    }
    olState* state = new olState(startAttrVal, PR_TRUE);
    if (state)
      mOLStateStack.AppendElement(state);
  }

  if (mIsCopying && name == nsHTMLAtoms::li) {
    mIsFirstChildOfOL = IsFirstChildOfOL(aElement);
    if (mIsFirstChildOfOL){
      // If OL is parent of this LI, serialize attributes in different manner.
      SerializeLIValueAttribute(aElement, aStr);
    }
  }

  // Even LI passed above have to go through this 
  // for serializing attributes other than "value".
  SerializeAttributes(content, name, aStr);

  AppendToString(kGreaterThan, aStr);

  if (LineBreakAfterOpen(name, hasDirtyAttr)) {
    AppendToString(mLineBreak, aStr);
    mMayIgnoreLineBreakSequence = PR_TRUE;
    mColPos = 0;
  }

  if (name == nsHTMLAtoms::script ||
      name == nsHTMLAtoms::style ||
      name == nsHTMLAtoms::noscript ||
      name == nsHTMLAtoms::noframes) {
    mInCDATA = PR_TRUE;
  }

  return NS_OK;
}
NS_IMETHODIMP nsNntpUrl::GetGetOldMessages(bool *aGetOldMessages) {
  NS_ENSURE_ARG(aGetOldMessages);
  *aGetOldMessages = m_getOldMessages;
  return NS_OK;
}
NS_IMETHODIMP
nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
{
    nsCOMPtr<nsILocalFile>  localFile;
    nsresult rv = NS_ERROR_FAILURE;

    NS_ENSURE_ARG(prop);
    *_retval = nsnull;
    *persistent = true;

#ifdef MOZ_WIDGET_COCOA
    FSRef fileRef;
    nsCOMPtr<nsILocalFileMac> macFile;
#endif

    if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
    {
        rv = GetProductDirectory(getter_AddRefs(localFile));
    }
    else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
    {
        rv = GetProductDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendNative(APP_REGISTRY_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv)) {
            rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
            if (NS_SUCCEEDED(rv))
                rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
        }
    }
    else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
             nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv)) {
            rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
            if (NS_SUCCEEDED(rv))
                rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
        }
    }
    else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
    {
        rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
    }
    else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0)
    {
        rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true);
    }
    else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
    }
#ifdef MOZ_WIDGET_COCOA
    else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
    {
        if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
            rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
            if (NS_SUCCEEDED(rv))
                localFile = macFile;
        }
    }
    else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
    {
        if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
            rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
            if (NS_SUCCEEDED(rv))
                localFile = macFile;
        }
    }
    else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0)
    {
        static const char *const java2PluginDirPath =
            "/System/Library/Java/Support/Deploy.bundle/Contents/Resources/";
        rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile));
    }
#else
    else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
    {
        NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
                 "Use nsAppFileLocationProvider::GetFiles(...).");
        const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
        if (pathVar && *pathVar)
            rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true,
                                       getter_AddRefs(localFile));
    }
    else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
    {
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS
        rv = GetProductDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
#else
        rv = NS_ERROR_FAILURE;
#endif
    }
#ifdef XP_UNIX
    else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) {
#ifdef ENABLE_SYSTEM_EXTENSION_DIRS
        static const char *const sysLPlgDir =
#if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__)
            "/usr/lib64/mozilla/plugins";
#else
            "/usr/lib/mozilla/plugins";
#endif
        rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir),
                                   false, getter_AddRefs(localFile));
#else
        rv = NS_ERROR_FAILURE;
#endif
    }
#endif
#endif
    else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
    {
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
        if (NS_SUCCEEDED(rv))
            rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0)
    {
        rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval);
        if (NS_SUCCEEDED(rv))
            rv = (*_retval)->AppendNative(SEARCH_DIR_NAME);
    }
    else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
    {
        // This is cloned so that embeddors will have a hook to override
        // with their own cleanup dir.  See bugzilla bug #105087
        rv = CloneMozBinDirectory(getter_AddRefs(localFile));
    }

    if (localFile && NS_SUCCEEDED(rv))
        return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);

    return rv;
}
NS_IMETHODIMP
nsParserUtils::ParseFragment(const nsAString& aFragment,
                             PRUint32 aFlags,
                             bool aIsXML,
                             nsIURI* aBaseURI,
                             nsIDOMElement* aContextElement,
                             nsIDOMDocumentFragment** aReturn)
{
  NS_ENSURE_ARG(aContextElement);
  *aReturn = nsnull;

  nsresult rv;
  nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDocument> document;
  nsCOMPtr<nsIDOMDocument> domDocument;
  nsCOMPtr<nsIDOMNode> contextNode;
  contextNode = do_QueryInterface(aContextElement);
  contextNode->GetOwnerDocument(getter_AddRefs(domDocument));
  document = do_QueryInterface(domDocument);
  NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);

  nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;

  // stop scripts
  nsRefPtr<nsScriptLoader> loader;
  bool scripts_enabled = false;
  if (document) {
    loader = document->ScriptLoader();
    scripts_enabled = loader->GetEnabled();
  }
  if (scripts_enabled) {
    loader->SetEnabled(false);
  }

  // Wrap things in a div or body for parsing, but it won't show up in
  // the fragment.
  nsAutoTArray<nsString, 2> tagStack;
  nsCAutoString base, spec;
  if (aIsXML) {
    // XHTML
    if (aBaseURI) {
      base.Append(NS_LITERAL_CSTRING(XHTML_DIV_TAG));
      base.Append(NS_LITERAL_CSTRING(" xml:base=\""));
      aBaseURI->GetSpec(spec);
      // nsEscapeHTML is good enough, because we only need to get
      // quotes, ampersands, and angle brackets
      char* escapedSpec = nsEscapeHTML(spec.get());
      if (escapedSpec)
        base += escapedSpec;
      NS_Free(escapedSpec);
      base.Append(NS_LITERAL_CSTRING("\""));
      tagStack.AppendElement(NS_ConvertUTF8toUTF16(base));
    }  else {
      tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
    }
  }

  if (NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIContent> fragment;
    if (aIsXML) {
      rv = nsContentUtils::ParseFragmentXML(aFragment,
                                            document,
                                            tagStack,
                                            true,
                                            aReturn);
      fragment = do_QueryInterface(*aReturn);
    } else {
      NS_NewDocumentFragment(aReturn,
                             document->NodeInfoManager());
      fragment = do_QueryInterface(*aReturn);
      rv = nsContentUtils::ParseFragmentHTML(aFragment,
                                             fragment,
                                             nsGkAtoms::body,
                                             kNameSpaceID_XHTML,
                                             false,
                                             true);
      // Now, set the base URI on all subtree roots.
      if (aBaseURI) {
        aBaseURI->GetSpec(spec);
        nsAutoString spec16;
        CopyUTF8toUTF16(spec, spec16);
        nsIContent* node = fragment->GetFirstChild();
        while (node) {
          if (node->IsElement()) {
            node->SetAttr(kNameSpaceID_XML,
                          nsGkAtoms::base,
                          nsGkAtoms::xml,
                          spec16,
                          false);
          }
          node = node->GetNextSibling();
        }
      }
    }
    if (fragment) {
      nsTreeSanitizer sanitizer(aFlags);
      sanitizer.Sanitize(fragment);
    }
  }

  if (scripts_enabled)
      loader->SetEnabled(true);
  
  return rv;
}
Exemple #13
0
NS_IMETHODIMP 
morkStdioFile::AcquireBud(nsIMdbEnv * mdbev, nsIMdbHeap* ioHeap, nsIMdbFile **acquiredFile)
  // AcquireBud() starts a new "branch" version of the file, empty of content,
  // so that a new version of the file can be written.  This new file
  // can later be told to BecomeTrunk() the original file, so the branch
  // created by budding the file will replace the original file.  Some
  // file subclasses might initially take the unsafe but expedient
  // approach of simply truncating this file down to zero length, and
  // then returning the same morkFile pointer as this, with an extra
  // reference count increment.  Note that the caller of AcquireBud() is
  // expected to eventually call CutStrongRef() on the returned file
  // in order to release the strong reference.  High quality versions
  // of morkFile subclasses will create entirely new files which later
  // are renamed to become the old file, so that better transactional
  // behavior is exhibited by the file, so crashes protect old files.
  // Note that AcquireBud() is an illegal operation on readonly files.
{
  NS_ENSURE_ARG(acquiredFile);
  MORK_USED_1(ioHeap);
  nsresult rv = NS_OK;
  morkFile* outFile = 0;
  morkEnv *ev = morkEnv::FromMdbEnv(mdbev);

  if ( this->IsOpenAndActiveFile() )
  {
    FILE* file = (FILE*) mStdioFile_File;
    if ( file )
    {
//#ifdef MORK_WIN
//      truncate(file, /*eof*/ 0);
//#else /*MORK_WIN*/
      char* name = mFile_Name;
      if ( name )
      {
        if ( MORK_FILECLOSE(file) >= 0 )
        {
          this->SetFileActive(morkBool_kFalse);
          this->SetFileIoOpen(morkBool_kFalse);
          mStdioFile_File = 0;
          
          file = MORK_FILEOPEN(name, "wb+"); // open for write, discarding old content
          if ( file )
          {
            mStdioFile_File = file;
            this->SetFileActive(morkBool_kTrue);
            this->SetFileIoOpen(morkBool_kTrue);
            this->SetFileFrozen(morkBool_kFalse);
          }
          else
            this->new_stdio_file_fault(ev);
        }
        else
          this->new_stdio_file_fault(ev);
      }
      else
        this->NilFileNameError(ev);
      
//#endif /*MORK_WIN*/

      if ( ev->Good() && this->AddStrongRef(ev->AsMdbEnv()) )
      {
        outFile = this;
        AddRef();
      }
    }
    else if ( mFile_Thief )
    {
      rv = mFile_Thief->AcquireBud(ev->AsMdbEnv(), ioHeap, acquiredFile);
    }
    else
      this->NewMissingIoError(ev);
  }
  else this->NewFileDownError(ev);
  
  *acquiredFile = outFile;
  return rv;
}
/*
 * Based on the security flags provided in the loadInfo of the channel,
 * doContentSecurityCheck() performs the following content security checks
 * before opening the channel:
 *
 * (1) Same Origin Policy Check (if applicable)
 * (2) Allow Cross Origin but perform sanity checks whether a principal
 *     is allowed to access the following URL.
 * (3) Perform CORS check (if applicable)
 * (4) ContentPolicy checks (Content-Security-Policy, Mixed Content, ...)
 *
 * @param aChannel
 *    The channel to perform the security checks on.
 * @param aInAndOutListener
 *    The streamListener that is passed to channel->AsyncOpen2() that is now potentially
 *    wrappend within nsCORSListenerProxy() and becomes the corsListener that now needs
 *    to be set as new streamListener on the channel.
 */
nsresult
nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
                                                 nsCOMPtr<nsIStreamListener>& aInAndOutListener)
{
  NS_ENSURE_ARG(aChannel);
  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();

  if (!loadInfo) {
    MOZ_ASSERT(false, "channel needs to have loadInfo to perform security checks");
    return NS_ERROR_UNEXPECTED;
  }

  // make sure that only one of the five security flags is set in the loadinfo
  // e.g. do not require same origin and allow cross origin at the same time
  nsresult rv = ValidateSecurityFlags(loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // lets store the initialSecurityCheckDone flag which indicates whether the channel
  // was initialy evaluated by the contentSecurityManager. Once the inital
  // asyncOpen() of the channel went through the contentSecurityManager then
  // redirects do not have perform all the security checks, e.g. no reason
  // to setup CORS again.
  bool initialSecurityCheckDone = loadInfo->GetInitialSecurityCheckDone();

  // now lets set the initalSecurityFlag for subsequent calls
  rv = loadInfo->SetInitialSecurityCheckDone(true);
  NS_ENSURE_SUCCESS(rv, rv);

  // since aChannel was openend using asyncOpen2() we have to make sure
  // that redirects of that channel also get openend using asyncOpen2()
  // please note that some implementations of ::AsyncOpen2 might already
  // have set that flag to true (e.g. nsViewSourceChannel) in which case
  // we just set the flag again.
  rv = loadInfo->SetEnforceSecurity(true);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURI> finalChannelURI;
  rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalChannelURI));
  NS_ENSURE_SUCCESS(rv, rv);

  nsSecurityFlags securityMode = loadInfo->GetSecurityMode();

  // if none of the REQUIRE_SAME_ORIGIN flags are set, then SOP does not apply
  if ((securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS) ||
      (securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED)) {
    rv = DoSOPChecks(finalChannelURI, loadInfo);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // if dealing with a redirected channel then we only enforce SOP
  // and can return at this point.
  if (initialSecurityCheckDone) {
    return NS_OK;
  }

  if ((securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS) ||
      (securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL)) {
    // Please note that DoCheckLoadURIChecks should only be enforced for
    // cross origin requests. If the flag SEC_REQUIRE_CORS_DATA_INHERITS is set
    // within the loadInfo, then then CheckLoadURIWithPrincipal is performed
    // within nsCorsListenerProxy
    rv = DoCheckLoadURIChecks(finalChannelURI, loadInfo);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
    rv = DoCORSChecks(aChannel, loadInfo, aInAndOutListener);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Perform all ContentPolicy checks (MixedContent, CSP, ...)
  rv = DoContentSecurityChecks(finalChannelURI, loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // all security checks passed - lets allow the load
  return NS_OK;
}
NS_IMETHODIMP 
nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype,
                                      nsAString& aStr)
{
  NS_ENSURE_ARG(aDoctype);
  nsresult rv;
  nsAutoString name, publicId, systemId, internalSubset;

  rv = aDoctype->GetName(name);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetPublicId(publicId);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetSystemId(systemId);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
  rv = aDoctype->GetInternalSubset(internalSubset);
  if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

  MaybeAddNewline(aStr);

  AppendToString(NS_LITERAL_STRING("<!DOCTYPE "), aStr);
  AppendToString(name, aStr);
  PRUnichar quote;
  if (!publicId.IsEmpty()) {
    AppendToString(NS_LITERAL_STRING(" PUBLIC "), aStr);
    if (publicId.FindChar(PRUnichar('"')) == -1) {
      quote = PRUnichar('"');
    }
    else {
      quote = PRUnichar('\'');
    }
    AppendToString(quote, aStr);
    AppendToString(publicId, aStr);
    AppendToString(quote, aStr);

    if (!systemId.IsEmpty()) {
      AppendToString(PRUnichar(' '), aStr);
      if (systemId.FindChar(PRUnichar('"')) == -1) {
        quote = PRUnichar('"');
      }
      else {
        quote = PRUnichar('\'');
      }
      AppendToString(quote, aStr);
      AppendToString(systemId, aStr);
      AppendToString(quote, aStr);
    }
  }
  else if (!systemId.IsEmpty()) {
    if (systemId.FindChar(PRUnichar('"')) == -1) {
      quote = PRUnichar('"');
    }
    else {
      quote = PRUnichar('\'');
    }
    AppendToString(NS_LITERAL_STRING(" SYSTEM "), aStr);
    AppendToString(quote, aStr);
    AppendToString(systemId, aStr);
    AppendToString(quote, aStr);
  }
  
  if (!internalSubset.IsEmpty()) {
    AppendToString(NS_LITERAL_STRING(" ["), aStr);
    AppendToString(internalSubset, aStr);
    AppendToString(PRUnichar(']'), aStr);
  }
    
  AppendToString(PRUnichar('>'), aStr);
  MaybeFlagNewline(aDoctype);

  return NS_OK;
}
NS_IMETHODIMP
nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
        nsIDOMElement *aOriginalElement,
        nsAString& aStr)
{
    NS_ENSURE_ARG(aElement);

    nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    if (!content) return NS_ERROR_FAILURE;

    // The _moz_dirty attribute is emitted by the editor to
    // indicate that this element should be pretty printed
    // even if we're not in pretty printing mode
    PRBool hasDirtyAttr = content->HasAttr(kNameSpaceID_None,
                                           nsGkAtoms::mozdirty);

    nsIAtom *name = content->Tag();

    if (name == nsGkAtoms::br && mPreLevel > 0
            && (mFlags & nsIDocumentEncoder::OutputNoFormattingInPre)) {
        AppendToString(mLineBreak, aStr);
        mMayIgnoreLineBreakSequence = PR_TRUE;
        mColPos = 0;
        return NS_OK;
    }

    if (name == nsGkAtoms::body) {
        mInBody = PR_TRUE;
    }

    if (LineBreakBeforeOpen(name, hasDirtyAttr)) {
        AppendToString(mLineBreak, aStr);
        mMayIgnoreLineBreakSequence = PR_TRUE;
        mColPos = 0;
        mAddSpace = PR_FALSE;
    }
    else if (mAddSpace) {
        AppendToString(PRUnichar(' '), aStr);
        mAddSpace = PR_FALSE;
    }
    else {
        MaybeAddNewline(aStr);
    }
    // Always reset to avoid false newlines in case MaybeAddNewline wasn't
    // called
    mAddNewline = PR_FALSE;

    StartIndentation(name, hasDirtyAttr, aStr);

    if (name == nsGkAtoms::pre ||
            name == nsGkAtoms::script ||
            name == nsGkAtoms::style) {
        mPreLevel++;
    }

    AppendToString(kLessThan, aStr);

    nsAutoString nameStr;
    name->ToString(nameStr);
    AppendToString(nameStr.get(), -1, aStr);

    // Need to keep track of OL and LI elements in order to get ordinal number
    // for the LI.
    if (mIsCopying && name == nsGkAtoms::ol) {
        // We are copying and current node is an OL;
        // Store it's start attribute value in olState->startVal.
        nsAutoString start;
        PRInt32 startAttrVal = 0;
        aElement->GetAttribute(NS_LITERAL_STRING("start"), start);
        if (!start.IsEmpty()) {
            PRInt32 rv = 0;
            startAttrVal = start.ToInteger(&rv);
            //If OL has "start" attribute, first LI element has to start with that value
            //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
            //In failure of ToInteger(), default StartAttrValue to 0.
            if (NS_SUCCEEDED(rv))
                startAttrVal--;
            else
                startAttrVal = 0;
        }
        olState* state = new olState(startAttrVal, PR_TRUE);
        if (state)
            mOLStateStack.AppendElement(state);
    }

    if (mIsCopying && name == nsGkAtoms::li) {
        mIsFirstChildOfOL = IsFirstChildOfOL(aOriginalElement);
        if (mIsFirstChildOfOL) {
            // If OL is parent of this LI, serialize attributes in different manner.
            SerializeLIValueAttribute(aElement, aStr);
        }
    }

    // Even LI passed above have to go through this
    // for serializing attributes other than "value".
    SerializeAttributes(content, name, aStr);

    AppendToString(kGreaterThan, aStr);

    if (LineBreakAfterOpen(name, hasDirtyAttr)) {
        AppendToString(mLineBreak, aStr);
        mMayIgnoreLineBreakSequence = PR_TRUE;
        mColPos = 0;
    }

    if (name == nsGkAtoms::script ||
            name == nsGkAtoms::style ||
            name == nsGkAtoms::noscript ||
            name == nsGkAtoms::noframes) {
        mInCDATA = PR_TRUE;
    }

    if (mIsWholeDocument && name == nsGkAtoms::head) {
        // Check if there already are any content-type meta children.
        // If there are, they will be modified to use the correct charset.
        // If there aren't, we'll insert one here.
        PRBool hasMeta = PR_FALSE;
        PRUint32 i, childCount = content->GetChildCount();
        for (i = 0; i < childCount; ++i) {
            nsIContent* child = content->GetChildAt(i);
            if (child->IsNodeOfType(nsINode::eHTML) &&
                    child->Tag() == nsGkAtoms::meta &&
                    child->HasAttr(kNameSpaceID_None, nsGkAtoms::content)) {
                nsAutoString header;
                child->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);

                if (header.LowerCaseEqualsLiteral("content-type")) {
                    hasMeta = PR_TRUE;
                    break;
                }
            }
        }

        if (!hasMeta) {
            AppendToString(mLineBreak, aStr);
            AppendToString(NS_LITERAL_STRING("<meta http-equiv=\"content-type\""),
                           aStr);
            AppendToString(NS_LITERAL_STRING(" content=\"text/html; charset="), aStr);
            AppendToString(NS_ConvertASCIItoUTF16(mCharset), aStr);
            AppendToString(NS_LITERAL_STRING("\">"), aStr);
        }
    }

    return NS_OK;
}
NS_IMETHODIMP 
nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
                                           nsIDOMElement *aOriginalElement,
                                           nsAString& aStr)
{
  NS_ENSURE_ARG(aElement);

  nsAutoString tagPrefix, tagLocalName, tagNamespaceURI;
  nsAutoString xmlnsStr;
  xmlnsStr.AssignLiteral(kXMLNS);

  nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
  if (!content) return NS_ERROR_FAILURE;

  aElement->GetPrefix(tagPrefix);
  aElement->GetLocalName(tagLocalName);
  aElement->GetNamespaceURI(tagNamespaceURI);

  PRUint32 index, count;
  nsAutoString nameStr, prefixStr, uriStr, valueStr;

  count = content->GetAttrCount();

  // First scan for namespace declarations, pushing each on the stack
  PRUint32 skipAttr = count;
  for (index = 0; index < count; index++) {
    
    const nsAttrName* name = content->GetAttrNameAt(index);
    PRInt32 namespaceID = name->NamespaceID();
    nsIAtom *attrName = name->LocalName();
    
    if (namespaceID == kNameSpaceID_XMLNS ||
        // Also push on the stack attrs named "xmlns" in the null
        // namespace... because once we serialize those out they'll look like
        // namespace decls.  :(
        // XXXbz what if we have both "xmlns" in the null namespace and "xmlns"
        // in the xmlns namespace?
        (namespaceID == kNameSpaceID_None &&
         attrName == nsGkAtoms::xmlns)) {
      content->GetAttr(namespaceID, attrName, uriStr);

      if (!name->GetPrefix()) {
        if (tagNamespaceURI.IsEmpty() && !uriStr.IsEmpty()) {
          // If the element is in no namespace we need to add a xmlns
          // attribute to declare that. That xmlns attribute must not have a
          // prefix (see http://www.w3.org/TR/REC-xml-names/#dt-prefix), ie it
          // must declare the default namespace. We just found an xmlns
          // attribute that declares the default namespace to something
          // non-empty. We're going to ignore this attribute, for children we
          // will detect that we need to add it again and attributes aren't
          // affected by the default namespace.
          skipAttr = index;
        }
        else {
          // Default NS attribute does not have prefix (and the name is "xmlns")
          PushNameSpaceDecl(EmptyString(), uriStr, aOriginalElement);
        }
      }
      else {
        attrName->ToString(nameStr);
        PushNameSpaceDecl(nameStr, uriStr, aOriginalElement);
      }
    }
  }

  PRBool addNSAttr;
    
  MaybeAddNewline(aStr);

  addNSAttr = ConfirmPrefix(tagPrefix, tagNamespaceURI, aOriginalElement,
                            PR_FALSE);
  // Serialize the qualified name of the element
  AppendToString(NS_LITERAL_STRING("<"), aStr);
  if (!tagPrefix.IsEmpty()) {
    AppendToString(tagPrefix, aStr);
    AppendToString(NS_LITERAL_STRING(":"), aStr);
  }
  AppendToString(tagLocalName, aStr);
    
  // If we had to add a new namespace declaration, serialize
  // and push it on the namespace stack
  if (addNSAttr) {
    if (tagPrefix.IsEmpty()) {
      // Serialize default namespace decl
      SerializeAttr(EmptyString(), xmlnsStr, tagNamespaceURI, aStr, PR_TRUE);
    } else {
      // Serialize namespace decl
      SerializeAttr(xmlnsStr, tagPrefix, tagNamespaceURI, aStr, PR_TRUE);
    }
    PushNameSpaceDecl(tagPrefix, tagNamespaceURI, aOriginalElement);
  }

  // Now serialize each of the attributes
  // XXX Unfortunately we need a namespace manager to get
  // attribute URIs.
  for (index = 0; index < count; index++) {
    if (skipAttr == index) {
        continue;
    }

    const nsAttrName* name = content->GetAttrNameAt(index);
    PRInt32 namespaceID = name->NamespaceID();
    nsIAtom* attrName = name->LocalName();
    nsIAtom* attrPrefix = name->GetPrefix();

    if (attrPrefix) {
      attrPrefix->ToString(prefixStr);
    }
    else {
      prefixStr.Truncate();
    }

    addNSAttr = PR_FALSE;
    if (kNameSpaceID_XMLNS != namespaceID) {
      nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
      addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, PR_TRUE);
    }
    
    content->GetAttr(namespaceID, attrName, valueStr);
    attrName->ToString(nameStr);

    // XXX Hack to get around the fact that MathML can add
    //     attributes starting with '-', which makes them
    //     invalid XML.
    if (!nameStr.IsEmpty() && nameStr.First() == '-')
      continue;

    if (namespaceID == kNameSpaceID_None) {
      if (content->GetNameSpaceID() == kNameSpaceID_XHTML) {
        if (IsShorthandAttr(attrName, content->Tag()) &&
            valueStr.IsEmpty()) {
          valueStr = nameStr;
        }
      }
    }
    SerializeAttr(prefixStr, nameStr, valueStr, aStr, PR_TRUE);
    
    if (addNSAttr) {
      NS_ASSERTION(!prefixStr.IsEmpty(),
                   "Namespaced attributes must have a prefix");
      SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, PR_TRUE);
      PushNameSpaceDecl(prefixStr, uriStr, aOriginalElement);
    }
  }

  // We don't output a separate end tag for empty element
  PRBool hasChildren;
  if (NS_FAILED(aOriginalElement->HasChildNodes(&hasChildren)) ||
      !hasChildren) {
    AppendToString(NS_LITERAL_STRING("/>"), aStr);    
    MaybeFlagNewline(aElement);
  } else {
    AppendToString(NS_LITERAL_STRING(">"), aStr);    
  }
  
  return NS_OK;
}
NS_IMETHODIMP
nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement,
        nsAString& aStr)
{
    NS_ENSURE_ARG(aElement);

    nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    if (!content) return NS_ERROR_FAILURE;

    PRBool hasDirtyAttr = content->HasAttr(kNameSpaceID_None,
                                           nsGkAtoms::mozdirty);

    nsIAtom *name = content->Tag();

    if (name == nsGkAtoms::script) {
        nsCOMPtr<nsIScriptElement> script = do_QueryInterface(aElement);

        if (script && script->IsMalformed()) {
            // We're looking at a malformed script tag. This means that the end tag
            // was missing in the source. Imitate that here by not serializing the end
            // tag.
            return NS_OK;
        }
    }

    if (name == nsGkAtoms::pre ||
            name == nsGkAtoms::script ||
            name == nsGkAtoms::style) {
        mPreLevel--;
    }

    if (mIsCopying && (name == nsGkAtoms::ol)) {
        NS_ASSERTION((mOLStateStack.Count() > 0), "Cannot have an empty OL Stack");
        /* Though at this point we must always have an state to be deleted as all
        the OL opening tags are supposed to push an olState object to the stack*/
        if (mOLStateStack.Count() > 0) {
            olState* state = (olState*)mOLStateStack.ElementAt(mOLStateStack.Count() -1);
            mOLStateStack.RemoveElementAt(mOLStateStack.Count() -1);
            delete state;
        }
    }

    nsIParserService* parserService = nsContentUtils::GetParserService();

    if (parserService && (name != nsGkAtoms::style)) {
        PRBool isContainer;

        parserService->IsContainer(parserService->HTMLAtomTagToId(name),
                                   isContainer);
        if (!isContainer) return NS_OK;
    }

    if (LineBreakBeforeClose(name, hasDirtyAttr)) {
        AppendToString(mLineBreak, aStr);
        mMayIgnoreLineBreakSequence = PR_TRUE;
        mColPos = 0;
        mAddSpace = PR_FALSE;
    }
    else if (mAddSpace) {
        AppendToString(PRUnichar(' '), aStr);
        mAddSpace = PR_FALSE;
    }

    EndIndentation(name, hasDirtyAttr, aStr);

    nsAutoString nameStr;
    name->ToString(nameStr);

    AppendToString(kEndTag, aStr);
    AppendToString(nameStr.get(), -1, aStr);
    AppendToString(kGreaterThan, aStr);

    if (LineBreakAfterClose(name, hasDirtyAttr)) {
        AppendToString(mLineBreak, aStr);
        mMayIgnoreLineBreakSequence = PR_TRUE;
        mColPos = 0;
    }
    else {
        MaybeFlagNewline(aElement);
    }

    mInCDATA = PR_FALSE;

    return NS_OK;
}
nsresult
nsPrintingPromptService::DoDialog(nsIDOMWindow *aParent,
                                  nsIDialogParamBlock *aParamBlock, 
                                  nsIWebBrowserPrint *aWebBrowserPrint, 
                                  nsIPrintSettings* aPS,
                                  const char *aChromeURL)
{
    NS_ENSURE_ARG(aParamBlock);
    NS_ENSURE_ARG(aPS);
    NS_ENSURE_ARG(aChromeURL);

    if (!mWatcher)
        return NS_ERROR_FAILURE;

    nsresult rv = NS_OK;

    // get a parent, if at all possible
    // (though we'd rather this didn't fail, it's OK if it does. so there's
    // no failure or null check.)
    nsCOMPtr<nsIDOMWindow> activeParent; // retain ownership for method lifetime
    if (!aParent) 
    {
        mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
        aParent = activeParent;
    }

    // create a nsISupportsArray of the parameters 
    // being passed to the window
    nsCOMPtr<nsISupportsArray> array;
    NS_NewISupportsArray(getter_AddRefs(array));
    if (!array) return NS_ERROR_FAILURE;

    nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
    NS_ASSERTION(psSupports, "PrintSettings must be a supports");
    array->AppendElement(psSupports);

    if (aWebBrowserPrint) {
      nsCOMPtr<nsISupports> wbpSupports(do_QueryInterface(aWebBrowserPrint));
      NS_ASSERTION(wbpSupports, "nsIWebBrowserPrint must be a supports");
      array->AppendElement(wbpSupports);
    }

    nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
    NS_ASSERTION(blkSupps, "IOBlk must be a supports");
    array->AppendElement(blkSupps);

    nsCOMPtr<nsISupports> arguments(do_QueryInterface(array));
    NS_ASSERTION(array, "array must be a supports");


    nsCOMPtr<nsIDOMWindow> dialog;
    rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
                              "centerscreen,chrome,modal,titlebar", arguments,
                              getter_AddRefs(dialog));

    // if aWebBrowserPrint is not null then we are printing
    // so we want to pass back NS_ERROR_ABORT on cancel
    if (NS_SUCCEEDED(rv) && aWebBrowserPrint) 
    {
        PRInt32 status;
        aParamBlock->GetInt(0, &status);
        return status == 0?NS_ERROR_ABORT:NS_OK;
    }

    return rv;
}
/*
    This method handles finding in a single window (aka frame).

*/
nsresult nsWebBrowserFind::SearchInFrame(nsIDOMWindow* aWindow,
                                         bool aWrapping,
                                         bool* aDidFind)
{
    NS_ENSURE_ARG(aWindow);
    NS_ENSURE_ARG_POINTER(aDidFind);

    *aDidFind = false;

    nsCOMPtr<nsIDOMDocument> domDoc;    
    nsresult rv = aWindow->GetDocument(getter_AddRefs(domDoc));
    NS_ENSURE_SUCCESS(rv, rv);
    if (!domDoc) return NS_ERROR_FAILURE;

    // Do security check, to ensure that the frame we're searching is
    // acccessible from the frame where the Find is being run.

    // get a uri for the window
    nsCOMPtr<nsIDocument> theDoc = do_QueryInterface(domDoc);
    if (!theDoc) return NS_ERROR_FAILURE;

    nsCOMPtr<nsIScriptSecurityManager> secMan =
      do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
  
    nsCOMPtr<nsIPrincipal> subject;
    rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
    NS_ENSURE_SUCCESS(rv, rv);

    if (subject) {
        bool subsumes;
        rv = subject->Subsumes(theDoc->NodePrincipal(), &subsumes);
        NS_ENSURE_SUCCESS(rv, rv);
        if (!subsumes) {
            bool hasCap = false;
            secMan->IsCapabilityEnabled("UniversalXPConnect", &hasCap);
            if (!hasCap) {
                return NS_ERROR_DOM_PROP_ACCESS_DENIED;
            }
        }
    }

    nsCOMPtr<nsIFind> find = do_CreateInstance(NS_FIND_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    (void) find->SetCaseSensitive(mMatchCase);
    (void) find->SetFindBackwards(mFindBackwards);

    // XXX Make and set a line breaker here, once that's implemented.
    (void) find->SetWordBreaker(0);

    // Now make sure the content (for actual finding) and frame (for
    // selection) models are up to date.
    theDoc->FlushPendingNotifications(Flush_Frames);

    nsCOMPtr<nsISelection> sel;
    GetFrameSelection(aWindow, getter_AddRefs(sel));
    NS_ENSURE_ARG_POINTER(sel);

    nsCOMPtr<nsIDOMRange> searchRange = nsFind::CreateRange();
    NS_ENSURE_ARG_POINTER(searchRange);
    nsCOMPtr<nsIDOMRange> startPt  = nsFind::CreateRange();
    NS_ENSURE_ARG_POINTER(startPt);
    nsCOMPtr<nsIDOMRange> endPt  = nsFind::CreateRange();
    NS_ENSURE_ARG_POINTER(endPt);

    nsCOMPtr<nsIDOMRange> foundRange;

    // If !aWrapping, search from selection to end
    if (!aWrapping)
        rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel,
                             false);

    // If aWrapping, search the part of the starting frame
    // up to the point where we left off.
    else
        rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel,
                             true);

    NS_ENSURE_SUCCESS(rv, rv);

    rv =  find->Find(mSearchString.get(), searchRange, startPt, endPt,
                     getter_AddRefs(foundRange));

    if (NS_SUCCEEDED(rv) && foundRange)
    {
        *aDidFind = true;
        sel->RemoveAllRanges();
        // Beware! This may flush notifications via synchronous
        // ScrollSelectionIntoView.
        SetSelectionAndScroll(aWindow, foundRange);
    }

    return rv;
}
/* void assign (in nsIPrintSettings aPS); */
NS_IMETHODIMP 
nsPrintSettings::Assign(nsIPrintSettings *aPS)
{
  NS_ENSURE_ARG(aPS);
  return _Assign(aPS);
}
Exemple #22
0
NS_IMETHODIMP
nsRegressionTester::DumpFrameModel(nsIDOMWindow *aWindowToDump,
                                   nsILocalFile *aDestFile,
                                   PRUint32 aFlagsMask, PRInt32 *aResult)
{
    NS_ENSURE_ARG(aWindowToDump);
    NS_ENSURE_ARG_POINTER(aResult);

    *aResult = DUMP_RESULT_ERROR;

#ifndef DEBUG
    return NS_ERROR_NOT_AVAILABLE;
#else
    nsresult    rv = NS_ERROR_NOT_AVAILABLE;
    PRUint32    busyFlags;
    bool        stillLoading;

    nsCOMPtr<nsIDocShell> docShell;
    rv = GetDocShellFromWindow(aWindowToDump, getter_AddRefs(docShell));
    if (NS_FAILED(rv)) return rv;

    // find out if the document is loaded
    docShell->GetBusyFlags(&busyFlags);
    stillLoading = busyFlags & (nsIDocShell::BUSY_FLAGS_BUSY |
                                nsIDocShell::BUSY_FLAGS_PAGE_LOADING);
    if (stillLoading)
    {
        *aResult = DUMP_RESULT_LOADING;
        return NS_OK;
    }

    nsCOMPtr<nsIPresShell> presShell;
    docShell->GetPresShell(getter_AddRefs(presShell));

    nsIFrame* root = presShell->GetRootFrame();

    FILE* fp = stdout;
    if (aDestFile)
    {
        rv = aDestFile->OpenANSIFileDesc("w", &fp);
        if (NS_FAILED(rv)) return rv;
    }
    if (aFlagsMask & DUMP_FLAGS_MASK_PRINT_MODE) {
        nsCOMPtr <nsIContentViewer> viewer;
        docShell->GetContentViewer(getter_AddRefs(viewer));
        if (viewer) {
            nsCOMPtr<nsIContentViewerFile> viewerFile = do_QueryInterface(viewer);
            if (viewerFile) {
                viewerFile->Print(PR_TRUE, fp, nsnull);
            }
        }
    }
    else {
        root->DumpRegressionData(presShell->GetPresContext(), fp, 0);
    }
    if (fp != stdout)
        fclose(fp);
    *aResult = DUMP_RESULT_COMPLETED;
    return NS_OK;
#endif
}
NS_IMETHODIMP nsAppStartupNotifier::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
{
    NS_ENSURE_ARG(aTopic);
    nsresult rv;

    // now initialize all startup listeners
    nsCOMPtr<nsICategoryManager> categoryManager =
                    do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsISimpleEnumerator> enumerator;
    rv = categoryManager->EnumerateCategory(aTopic,
                               getter_AddRefs(enumerator));
    if (NS_FAILED(rv)) return rv;

    nsCOMPtr<nsISupports> entry;
    while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) {
        nsCOMPtr<nsISupportsCString> category = do_QueryInterface(entry, &rv);

        if (NS_SUCCEEDED(rv)) {
            nsAutoCString categoryEntry;
            rv = category->GetData(categoryEntry);

            nsXPIDLCString contractId;
            categoryManager->GetCategoryEntry(aTopic, 
                                              categoryEntry.get(),
                                              getter_Copies(contractId));

            if (NS_SUCCEEDED(rv)) {

                // If we see the word "service," in the beginning
                // of the contractId then we create it as a service
                // if not we do a createInstance

                nsCOMPtr<nsISupports> startupInstance;
                if (Substring(contractId, 0, 8).EqualsLiteral("service,"))
                    startupInstance = do_GetService(contractId.get() + 8, &rv);
                else
                    startupInstance = do_CreateInstance(contractId, &rv);

                if (NS_SUCCEEDED(rv)) {
                    // Try to QI to nsIObserver
                    nsCOMPtr<nsIObserver> startupObserver =
                        do_QueryInterface(startupInstance, &rv);
                    if (NS_SUCCEEDED(rv)) {
                        rv = startupObserver->Observe(nullptr, aTopic, nullptr);
     
                        // mainly for debugging if you want to know if your observer worked.
                        NS_ASSERTION(NS_SUCCEEDED(rv), "Startup Observer failed!\n");
                    }
                }
                else {
                  #ifdef DEBUG
                    nsAutoCString warnStr("Cannot create startup observer : ");
                    warnStr += contractId.get();
                    NS_WARNING(warnStr.get());
                  #endif
                }

            }
        }
    }

    return NS_OK;
}
// Determine if any URI of the window hierarchy of aWindow is foreign with
// respect to aSecondURI. See docs for mozIThirdPartyUtil.
NS_IMETHODIMP
ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
                                   nsIURI* aURI,
                                   bool* aResult)
{
  NS_ENSURE_ARG(aWindow);
  NS_ASSERTION(aResult, "null outparam pointer");

  bool result;

  // Get the URI of the window, and its base domain.
  nsresult rv;
  nsCOMPtr<nsIURI> currentURI;
  rv = GetURIFromWindow(aWindow, getter_AddRefs(currentURI));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCString bottomDomain;
  rv = GetBaseDomain(currentURI, bottomDomain);
  if (NS_FAILED(rv))
    return rv;

  if (aURI) {
    // Determine whether aURI is foreign with respect to currentURI.
    rv = IsThirdPartyInternal(bottomDomain, aURI, &result);
    if (NS_FAILED(rv))
      return rv;

    if (result) {
      *aResult = true;
      return NS_OK;
    }
  }

  nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
  nsCOMPtr<nsIURI> parentURI;
  do {
    // We use GetScriptableParent rather than GetParent because we consider
    // <iframe mozbrowser/mozapp> to be a top-level frame.
    rv = current->GetScriptableParent(getter_AddRefs(parent));
    NS_ENSURE_SUCCESS(rv, rv);

    if (SameCOMIdentity(parent, current)) {
      // We're at the topmost content window. We already know the answer.
      *aResult = false;
      return NS_OK;
    }

    rv = GetURIFromWindow(parent, getter_AddRefs(parentURI));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = IsThirdPartyInternal(bottomDomain, parentURI, &result);
    if (NS_FAILED(rv))
      return rv;

    if (result) {
      *aResult = true;
      return NS_OK;
    }

    current = parent;
    currentURI = parentURI;
  } while (1);

  NS_NOTREACHED("should've returned");
  return NS_ERROR_UNEXPECTED;
}
Exemple #25
0
NS_IMETHODIMP
nsMovemailService::SetDefaultLocalPath(nsIFile *aPath)
{
  NS_ENSURE_ARG(aPath);
  return NS_SetPersistentFile(PREF_MAIL_ROOT_MOVEMAIL_REL, PREF_MAIL_ROOT_MOVEMAIL, aPath);
}
// Determine if the URI associated with aChannel or any URI of the window
// hierarchy associated with the channel is foreign with respect to aSecondURI.
// See docs for mozIThirdPartyUtil.
NS_IMETHODIMP 
ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
                                    nsIURI* aURI,
                                    bool* aResult)
{
  LOG(("ThirdPartyUtil::IsThirdPartyChannel [channel=%p]", aChannel));
  NS_ENSURE_ARG(aChannel);
  NS_ASSERTION(aResult, "null outparam pointer");

  nsresult rv;
  bool doForce = false;
  bool checkWindowChain = true;
  bool parentIsThird = false;
  nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
    do_QueryInterface(aChannel);
  if (httpChannelInternal) {
    uint32_t flags;
    rv = httpChannelInternal->GetThirdPartyFlags(&flags);
    NS_ENSURE_SUCCESS(rv, rv);

    doForce = (flags & nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);

    // If aURI was not supplied, and we're forcing, then we're by definition
    // not foreign. If aURI was supplied, we still want to check whether it's
    // foreign with respect to the channel URI. (The forcing only applies to
    // whatever window hierarchy exists above the channel.)
    if (doForce && !aURI) {
      *aResult = false;
      return NS_OK;
    }

    if (flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY) {
      // Check that the two PARENT_IS_{THIRD,SAME}_PARTY are mutually exclusive.
      MOZ_ASSERT(!(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY));

      // If we're not forcing and we know that the window chain of the channel
      // is third party, then we know now that we're third party.
      if (!doForce) {
        *aResult = true;
        return NS_OK;
      }

      checkWindowChain = false;
      parentIsThird = true;
    } else {
      // In e10s, we can't check the parent chain in the parent, so we do so
      // in the child and send the result to the parent.
      // Note that we only check the window chain if neither
      // THIRD_PARTY_PARENT_IS_* flag is set.
      checkWindowChain = !(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY);
      parentIsThird = false;
    }
  }

  // Obtain the URI from the channel, and its base domain.
  nsCOMPtr<nsIURI> channelURI;
  aChannel->GetURI(getter_AddRefs(channelURI));
  NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);

  nsCString channelDomain;
  rv = GetBaseDomain(channelURI, channelDomain);
  if (NS_FAILED(rv))
    return rv;

  if (aURI) {
    // Determine whether aURI is foreign with respect to channelURI.
    bool result;
    rv = IsThirdPartyInternal(channelDomain, aURI, &result);
    if (NS_FAILED(rv))
     return rv;

    // If it's foreign, or we're forcing, we're done.
    if (result || doForce) {
      *aResult = result;
      return NS_OK;
    }
  }

  // If we've already computed this in the child process, we're done.
  if (!checkWindowChain) {
    *aResult = parentIsThird;
    return NS_OK;
  }

  // Find the associated window and its parent window.
  nsCOMPtr<nsILoadContext> ctx;
  NS_QueryNotificationCallbacks(aChannel, ctx);
  if (!ctx) return NS_ERROR_INVALID_ARG;

  // If there is no window, the consumer kicking off the load didn't provide one
  // to the channel. This is limited to loads of certain types of resources. If
  // those loads require cookies, the forceAllowThirdPartyCookie property should
  // be set on the channel.
  nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
  ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
  if (!ourWin) return NS_ERROR_INVALID_ARG;

  // We use GetScriptableParent rather than GetParent because we consider
  // <iframe mozbrowser/mozapp> to be a top-level frame.
  ourWin->GetScriptableParent(getter_AddRefs(parentWin));
  NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);

  // Check whether this is the document channel for this window (representing a
  // load of a new page). In that situation we want to avoid comparing
  // channelURI to ourWin, since what's in ourWin right now will be replaced as
  // the channel loads.  This covers the case of a freshly kicked-off load
  // (e.g. the user typing something in the location bar, or clicking on a
  // bookmark), where the window's URI hasn't yet been set, and will be bogus.
  // It also covers situations where a subframe is navigated to someting that
  // is same-origin with all its ancestors.  This is a bit of a nasty hack, but
  // we will hopefully flag these channels better later.
  nsLoadFlags flags;
  rv = aChannel->GetLoadFlags(&flags);
  NS_ENSURE_SUCCESS(rv, rv);

  if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
    if (SameCOMIdentity(ourWin, parentWin)) {
      // We only need to compare aURI to the channel URI -- the window's will be
      // bogus. We already know the answer.
      *aResult = false;
      return NS_OK;
    }

    // Make sure to still compare to ourWin's ancestors
    ourWin = parentWin;
  }

  // Check the window hierarchy. This covers most cases for an ordinary page
  // load from the location bar.
  return IsThirdPartyWindow(ourWin, channelURI, aResult);
}
nsresult
nsXFormsMDGEngine::AddMIP(ModelItemPropName         aType,
                          nsIDOMNSXPathExpression  *aExpression,
                          nsCOMArray<nsIDOMNode>   *aDependencies,
                          PRBool                    aDynFunc,
                          nsIDOMNode               *aContextNode,
                          PRInt32                   aContextPos,
                          PRInt32                   aContextSize)
{
  NS_ENSURE_ARG(aContextNode);
  
#ifdef DEBUG_XF_MDG
  nsAutoString nodename;
  aContextNode->GetNodeName(nodename);
  printf("nsXFormsMDGEngine::AddMIP(aContextNode=%s, aExpression=%p, aDependencies=|%d|,\n",
         NS_ConvertUTF16toUTF8(nodename).get(),
         (void*) aExpression,
         aDependencies ? aDependencies->Count() : 0);
  printf("                          aContextPos=%d, aContextSize=%d, aType=%s, aDynFunc=%d)\n",
         aContextPos, aContextSize, gMIPNames[aType], aDynFunc);
#endif
  nsXFormsMDGNode* newnode = GetNode(aContextNode,
                                     aType,
                                     PR_TRUE);
  
  if (!newnode) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  
  if (newnode->HasExpr()) {
    // MIP already in the graph. That is, there is already a MIP of the same
    // type for this node, which is illegal.
    // Example: <bind nodeset="x" required="true()" required="false()"/>
    return NS_ERROR_ABORT;
  }

  if (aExpression) {
    newnode->SetExpression(aExpression, aDynFunc, aContextPos, aContextSize);
  }
  
  // Add dependencies
  if (aDependencies) {
    nsCOMPtr<nsIDOMNode> dep_domnode;
    nsXFormsMDGNode* dep_gnode;
    for (PRInt32 i = 0; i < aDependencies->Count(); ++i) {
      dep_domnode = aDependencies->ObjectAt(i);
      if (!dep_domnode) {
        return NS_ERROR_NULL_POINTER;
      }

#ifdef DEBUG_XF_MDG
      printf("\tDependency #%2d: %p\n", i, (void*) dep_domnode);
#endif
      
      // Get calculate graph node for the dependency (only a calculate
      // property can influence another MIP).
      dep_gnode = GetNode(dep_domnode, eModel_calculate);
      if (!dep_gnode) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
  
      if (dep_gnode->mType == aType && dep_gnode->mContextNode == aContextNode) {
        // Reference to itself, ignore
        continue;
      }
  
      // Add this node as a successor to the dependency (ie. the dependency
      // should be (re-)calculated before this node)
      dep_gnode->mSuc.AppendElement(newnode);
      newnode->mCount++;
    }
  }

  return NS_OK;
}
/*
 * Based on the security flags provided in the loadInfo of the channel,
 * doContentSecurityCheck() performs the following content security checks
 * before opening the channel:
 *
 * (1) Same Origin Policy Check (if applicable)
 * (2) Allow Cross Origin but perform sanity checks whether a principal
 *     is allowed to access the following URL.
 * (3) Perform CORS check (if applicable)
 * (4) ContentPolicy checks (Content-Security-Policy, Mixed Content, ...)
 *
 * @param aChannel
 *    The channel to perform the security checks on.
 * @param aInAndOutListener
 *    The streamListener that is passed to channel->AsyncOpen2() that is now potentially
 *    wrappend within nsCORSListenerProxy() and becomes the corsListener that now needs
 *    to be set as new streamListener on the channel.
 */
nsresult
nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
                                                 nsCOMPtr<nsIStreamListener>& aInAndOutListener)
{
  NS_ENSURE_ARG(aChannel);
  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();

  if (!loadInfo) {
    MOZ_ASSERT(false, "channel needs to have loadInfo to perform security checks");
    return NS_ERROR_UNEXPECTED;
  }

  // make sure that only one of the five security flags is set in the loadinfo
  // e.g. do not require same origin and allow cross origin at the same time
  nsresult rv = ValidateSecurityFlags(loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // lets store the initialSecurityCheckDone flag which indicates whether the channel
  // was initialy evaluated by the contentSecurityManager. Once the inital
  // asyncOpen() of the channel went through the contentSecurityManager then
  // redirects do not have perform all the security checks, e.g. no reason
  // to setup CORS again.
  bool initialSecurityCheckDone = loadInfo->GetInitialSecurityCheckDone();

  // now lets set the initalSecurityFlag for subsequent calls
  rv = loadInfo->SetInitialSecurityCheckDone(true);
  NS_ENSURE_SUCCESS(rv, rv);

  // since aChannel was openend using asyncOpen2() we have to make sure
  // that redirects of that channel also get openend using asyncOpen2()
  // please note that some implementations of ::AsyncOpen2 might already
  // have set that flag to true (e.g. nsViewSourceChannel) in which case
  // we just set the flag again.
  rv = loadInfo->SetEnforceSecurity(true);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIURI> finalChannelURI;
  rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalChannelURI));
  NS_ENSURE_SUCCESS(rv, rv);

  // Perform Same Origin Policy check
  rv = DoSOPChecks(finalChannelURI, loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // if dealing with a redirected channel then we only enforce SOP
  // and can return at this point.
  if (initialSecurityCheckDone) {
    return NS_OK;
  }

  rv = DoCheckLoadURIChecks(finalChannelURI, loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // Check if CORS needs to be set up
  rv = DoCORSChecks(aChannel, loadInfo, aInAndOutListener);
  NS_ENSURE_SUCCESS(rv, rv);

  // Perform all ContentPolicy checks (MixedContent, CSP, ...)
  rv = DoContentSecurityChecks(finalChannelURI, loadInfo);
  NS_ENSURE_SUCCESS(rv, rv);

  // all security checks passed - lets allow the load
  return NS_OK;
}
nsresult
nsXFormsMDGEngine::SetNodeContent(nsIDOMNode       *aContextNode,
                                  nsIDOMNode       *aContentEnvelope)
{
  NS_ENSURE_ARG(aContextNode);
  NS_ENSURE_ARG(aContentEnvelope);

  // ok, this is tricky.  This function will REPLACE the contents of
  // aContextNode with the a clone of the contents of aContentEnvelope.  If
  // aContentEnvelope has no contents, then any contents that aContextNode
  // has will still be removed.  

  const nsXFormsNodeState* ns = GetNodeState(aContextNode);
  NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);

  // If the node is read-only and not set by a @calculate MIP,
  // ignore the call
  if (ns->IsReadonly()) {
    ///
    /// @todo Better feedback for readonly nodes? (XXX)
    return NS_OK;
  }

  PRUint16 nodeType;
  nsresult rv = aContextNode->GetNodeType(&nodeType);
  NS_ENSURE_SUCCESS(rv, rv);

  if (nodeType != nsIDOMNode::ELEMENT_NODE) {
    // got to return something pretty unique that we can check down the road in
    // order to dispatch any error events
    return NS_ERROR_DOM_WRONG_TYPE_ERR;
  }

  // Need to determine if the contents of the context node and content envelope
  // are already the same.  If so, we can avoid some unnecessary work.

  PRBool hasChildren1, hasChildren2, contentsEqual = PR_FALSE;
  nsresult rv1 = aContextNode->HasChildNodes(&hasChildren1);
  nsresult rv2 = aContentEnvelope->HasChildNodes(&hasChildren2);
  if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && hasChildren1 == hasChildren2) {
    // First test passed.  Both have the same number of children nodes.
    if (hasChildren1) {
      nsCOMPtr<nsIDOMNodeList> children1, children2;
      PRUint32 childrenLength1, childrenLength2;
  
      rv1 = aContextNode->GetChildNodes(getter_AddRefs(children1));
      rv2 = aContentEnvelope->GetChildNodes(getter_AddRefs(children2));

      if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && children1 && children2) {

        // Both have child nodes.
        rv1 = children1->GetLength(&childrenLength1);
        rv2 = children2->GetLength(&childrenLength2);
        if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && 
            (childrenLength1 == childrenLength2)) {

          // both have the same number of child nodes.  Now checking to see if
          // each of the children are equal.
          for (PRUint32 i = 0; i < childrenLength1; ++i) {
            nsCOMPtr<nsIDOMNode> child1, child2;
      
            rv1 = children1->Item(i, getter_AddRefs(child1));
            rv2 = children2->Item(i, getter_AddRefs(child2));
            if (NS_FAILED(rv1) || NS_FAILED(rv2)) {
              // Unexpected error.  Not as many children in the list as we
              // were told.
              return NS_ERROR_UNEXPECTED;
            }
      
            contentsEqual = nsXFormsUtils::AreNodesEqual(child1, child2, PR_TRUE);
            if (!contentsEqual) {
              break;
            }
          }
        }
      }
    } else {
      // neither have children
      contentsEqual = PR_TRUE;
    }
  }

  if (contentsEqual) {
    return NS_OK;
  }

  // remove any child nodes that aContextNode already contains
  nsCOMPtr<nsIDOMNode> resultNode;
  nsCOMPtr<nsIDOMNodeList> childList;
  rv = aContextNode->GetChildNodes(getter_AddRefs(childList));
  NS_ENSURE_SUCCESS(rv, rv);
  if (childList) {
    PRUint32 length;
    rv = childList->GetLength(&length);
    NS_ENSURE_SUCCESS(rv, rv);

    for (PRInt32 i = length-1; i >= 0; i--) {
      nsCOMPtr<nsIDOMNode> childNode;
      rv = childList->Item(i, getter_AddRefs(childNode));
      NS_ENSURE_SUCCESS(rv, rv);

      rv = aContextNode->RemoveChild(childNode, getter_AddRefs(resultNode));
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  // add contents of the envelope under aContextNode
  nsCOMPtr<nsIDOMNode> childNode;
  rv = aContentEnvelope->GetFirstChild(getter_AddRefs(childNode));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDOMDocument> document;
  rv = aContextNode->GetOwnerDocument(getter_AddRefs(document));
  NS_ENSURE_STATE(document);

  while (childNode) {
    nsCOMPtr<nsIDOMNode> importedNode;
    rv = document->ImportNode(childNode, PR_TRUE, getter_AddRefs(importedNode));
    NS_ENSURE_STATE(importedNode);
    rv = aContextNode->AppendChild(importedNode, getter_AddRefs(resultNode));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = childNode->GetNextSibling(getter_AddRefs(resultNode));
    NS_ENSURE_SUCCESS(rv, rv);

    resultNode.swap(childNode);
  }

  // We already know that the contents have changed.  Mark the node so that
  // a xforms-value-changed can be dispatched.
  MarkNodeAsChanged(aContextNode);

  return NS_OK;
}
NS_IMETHODIMP nsWifiAccessPoint::GetSignal(int32_t *aSignal)
{
  NS_ENSURE_ARG(aSignal);
  *aSignal = mSignal;
  return NS_OK;
}