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; }
// // 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; }
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); }
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; }
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; }