nsresult nsMailtoUrl::ParseUrl() { // we can get the path from the simple url..... nsCString escapedPath; m_baseURL->GetPath(escapedPath); int32_t startOfSearchPart = escapedPath.FindChar('?'); if (startOfSearchPart >= 0) { // now parse out the search field... nsAutoCString searchPart(Substring(escapedPath, startOfSearchPart)); if (!searchPart.IsEmpty()) { // now we need to strip off the search part from the // to part.... escapedPath.SetLength(startOfSearchPart); MsgUnescapeString(escapedPath, 0, m_toPart); ParseMailtoUrl(searchPart.BeginWriting()); } } else if (!escapedPath.IsEmpty()) { MsgUnescapeString(escapedPath, 0, m_toPart); } return NS_OK; }
nsresult nsNntpUrl::ParseNewsURL() { // The path here is the group/msgid portion nsAutoCString path; nsresult rv = GetFilePath(path); NS_ENSURE_SUCCESS(rv, rv); // Drop the potential beginning from the path if (path.Length() && path[0] == '/') path = Substring(path, 1); // The presence of an `@' is a sign we have a msgid if (path.Find("@") != -1 || path.Find("%40") != -1) { MsgUnescapeString(path, 0, m_messageID); // Set group, key for ?group=foo&key=123 uris nsAutoCString spec; rv = GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); int32_t groupPos = spec.Find(kNewsURIGroupQuery); // find ?group= int32_t keyPos = spec.Find(kNewsURIKeyQuery); // find &key= if (groupPos != kNotFound && keyPos != kNotFound) { // get group name and message key m_group = Substring(spec, groupPos + kNewsURIGroupQueryLen, keyPos - groupPos - kNewsURIGroupQueryLen); nsCString keyStr(Substring(spec, keyPos + kNewsURIKeyQueryLen)); m_key = keyStr.ToInteger(&rv, 10); NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI); } } else MsgUnescapeString(path, 0, m_group); return NS_OK; }
// Assumption: attribute pairs in the string are separated by '&'. char * extractAttributeValue(const char * searchString, const char * attributeName) { char * attributeValue = nullptr; if (searchString && attributeName) { // search the string for attributeName uint32_t attributeNameSize = PL_strlen(attributeName); char * startOfAttribute = PL_strcasestr(searchString, attributeName); if (startOfAttribute) { startOfAttribute += attributeNameSize; // skip over the attributeName if (startOfAttribute) // is there something after the attribute name { char * endOfAttribute = startOfAttribute ? PL_strchr(startOfAttribute, '&') : nullptr; nsDependentCString attributeValueStr; if (startOfAttribute && endOfAttribute) // is there text after attribute value attributeValueStr.Assign(startOfAttribute, endOfAttribute - startOfAttribute); else // there is nothing left so eat up rest of line. attributeValueStr.Assign(startOfAttribute); // now unescape the string... nsCString unescapedValue; MsgUnescapeString(attributeValueStr, 0, unescapedValue); attributeValue = PL_strdup(unescapedValue.get()); } // if we have a attribute value } // if we have a attribute name } // if we got non-null search string and attribute name values return attributeValue; }
NS_IMETHODIMP nsSmtpUrl::SetRecipients(const char * aRecipientsList) { NS_ENSURE_ARG(aRecipientsList); MsgUnescapeString(nsDependentCString(aRecipientsList), 0, m_toPart); return NS_OK; }
NS_IMETHODIMP nsAbManager::EscapedVCardToAbCard(const char *aEscapedVCardStr, nsIAbCard **aCard) { NS_ENSURE_ARG_POINTER(aEscapedVCardStr); NS_ENSURE_ARG_POINTER(aCard); nsCOMPtr <nsIAbCard> cardFromVCard = do_CreateInstance(NS_ABCARDPROPERTY_CONTRACTID); if (!cardFromVCard) return NS_ERROR_FAILURE; // aEscapedVCardStr will be "" the first time, before you have a vCard if (*aEscapedVCardStr != '\0') { nsCString unescapedData; MsgUnescapeString(nsDependentCString(aEscapedVCardStr), 0, unescapedData); VObject *vObj = parse_MIME(unescapedData.get(), unescapedData.Length()); if (vObj) { convertFromVObject(vObj, cardFromVCard); cleanVObject(vObj); } else NS_WARNING("Parse of vCard failed"); } NS_IF_ADDREF(*aCard = cardFromVCard); return NS_OK; }
// given rootURI and rootURI##folder, return on-disk path of folder nsresult nsLocalURI2Path(const char* rootURI, const char* uriStr, nsCString& pathResult) { nsresult rv; // verify that rootURI starts with "mailbox:/" or "mailbox-message:/" if ((PL_strcmp(rootURI, kMailboxRootURI) != 0) && (PL_strcmp(rootURI, kMailboxMessageRootURI) != 0)) { return NS_ERROR_FAILURE; } // verify that uristr starts with rooturi nsCAutoString uri(uriStr); if (uri.Find(rootURI) != 0) return NS_ERROR_FAILURE; nsCOMPtr<nsIMsgIncomingServer> server; rv = nsLocalURI2Server(uriStr, getter_AddRefs(server)); if (NS_FAILED(rv)) return rv; // now ask the server what it's root is // and begin pathResult with the mailbox root nsCOMPtr<nsIFile> localPath; rv = server->GetLocalPath(getter_AddRefs(localPath)); NS_ENSURE_SUCCESS(rv, rv); nsCString localNativePath; localPath->GetNativePath(localNativePath); nsEscapeNativePath(localNativePath); pathResult = localNativePath.get(); const char *curPos = uriStr + PL_strlen(rootURI); if (curPos) { // advance past hostname while ((*curPos)=='/') curPos++; while (*curPos && (*curPos)!='/') curPos++; nsCAutoString newPath(""); // Unescape folder name if (curPos) { nsCString unescapedStr; MsgUnescapeString(nsDependentCString(curPos), 0, unescapedStr); NS_MsgCreatePathStringFromFolderURI(unescapedStr.get(), newPath, NS_LITERAL_CSTRING("none")); } else NS_MsgCreatePathStringFromFolderURI(curPos, newPath, NS_LITERAL_CSTRING("none")); pathResult.Append('/'); pathResult.Append(newPath); } return NS_OK; }
/* parses ImapMessageURI */ nsresult nsParseImapMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key, char **part) { if(!key) return NS_ERROR_NULL_POINTER; nsCAutoString uriStr(uri); PRInt32 folderEnd = -1; // imap-message uri's can have imap:// url strings tacked on the end, // e.g., when opening/saving attachments. We don't want to look for '#' // in that part of the uri, if the attachment name contains '#', // so check for that here. if (StringBeginsWith(uriStr, NS_LITERAL_CSTRING("imap-message"))) folderEnd = uriStr.Find("imap://"); PRInt32 keySeparator = MsgRFindChar(uriStr, '#', folderEnd); if(keySeparator != -1) { PRInt32 keyEndSeparator = MsgFindCharInSet(uriStr, "/?&", keySeparator); nsAutoString folderPath; folderURI = StringHead(uriStr, keySeparator); folderURI.Cut(4, 8); // cut out the _message part of imap-message: // folder uri's don't have fully escaped usernames. PRInt32 atPos = folderURI.FindChar('@'); if (atPos != -1) { nsCString unescapedName, escapedName; PRInt32 userNamePos = folderURI.Find("//") + 2; PRUint32 origUserNameLen = atPos - userNamePos; if (NS_SUCCEEDED(MsgUnescapeString(Substring(folderURI, userNamePos, origUserNameLen), 0, unescapedName))) { // Re-escape the username, matching the way we do it in uris, not the // way necko escapes urls. See nsMsgIncomingServer::GetServerURI. MsgEscapeString(unescapedName, nsINetUtil::ESCAPE_XALPHAS, escapedName); folderURI.Replace(userNamePos, origUserNameLen, escapedName); } } nsCAutoString keyStr; if (keyEndSeparator != -1) keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1)); else keyStr = Substring(uriStr, keySeparator + 1); *key = strtoul(keyStr.get(), nsnull, 10); if (part && keyEndSeparator != -1) { PRInt32 partPos = MsgFind(uriStr, "part=", PR_FALSE, keyEndSeparator); if (partPos != -1) { *part = ToNewCString(Substring(uriStr, keyEndSeparator)); } } } return NS_OK; }
static void UnescapeAndConvert(nsIMimeConverter *mimeConverter, const nsACString &escaped, nsACString &out) { NS_ASSERTION(mimeConverter, "Set mimeConverter before calling!"); // If the string is empty, do absolutely nothing. if (escaped.IsEmpty()) return; MsgUnescapeString(escaped, 0, out); nsAutoCString decodedString; nsresult rv = mimeConverter->DecodeMimeHeaderToUTF8(out, "UTF_8", false, true, decodedString); if (NS_SUCCEEDED(rv) && !decodedString.IsEmpty()) out = decodedString; }
/* parses NewsMessageURI */ nsresult nsParseNewsMessageURI(const char* uri, nsCString& group, nsMsgKey *key) { NS_ENSURE_ARG_POINTER(uri); NS_ENSURE_ARG_POINTER(key); nsAutoCString uriStr(uri); int32_t keySeparator = uriStr.FindChar('#'); if(keySeparator != -1) { int32_t keyEndSeparator = MsgFindCharInSet(uriStr, "?&", keySeparator); // Grab between the last '/' and the '#' for the key group = StringHead(uriStr, keySeparator); int32_t groupSeparator = group.RFind("/"); if (groupSeparator == -1) return NS_ERROR_FAILURE; // Our string APIs don't let us unescape into the same buffer from earlier, // so escape into a temporary nsAutoCString unescapedGroup; MsgUnescapeString(Substring(group, groupSeparator + 1), 0, unescapedGroup); group = unescapedGroup; nsAutoCString keyStr; if (keyEndSeparator != -1) keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1)); else keyStr = Substring(uriStr, keySeparator + 1); nsresult errorCode; *key = keyStr.ToInteger(&errorCode); return errorCode; } return NS_ERROR_FAILURE; }
nsresult nsMsgAttachmentHandler::SnarfAttachment(nsMsgCompFields *compFields) { NS_ASSERTION (! m_done, "Already done"); if (!mURL) return SnarfMsgAttachment(compFields); mCompFields = compFields; // First, get as file spec and create the stream for the // temp file where we will save this data nsCOMPtr <nsIFile> tmpFile; nsresult rv = nsMsgCreateTempFile("nsmail.tmp", getter_AddRefs(tmpFile)); NS_ENSURE_SUCCESS(rv, rv); mTmpFile = do_QueryInterface(tmpFile); mDeleteFile = true; rv = MsgNewBufferedFileOutputStream(getter_AddRefs(mOutFile), mTmpFile, -1, 00600); if (NS_FAILED(rv) || !mOutFile) { if (m_mime_delivery_state) { nsCOMPtr<nsIMsgSendReport> sendReport; m_mime_delivery_state->GetSendReport(getter_AddRefs(sendReport)); if (sendReport) { nsAutoString error_msg; nsMsgBuildMessageWithTmpFile(mTmpFile, error_msg); sendReport->SetMessage(nsIMsgSendReport::process_Current, error_msg.get(), false); } } mTmpFile->Remove(false); mTmpFile = nsnull; return NS_MSG_UNABLE_TO_OPEN_TMP_FILE; } nsCString sourceURISpec; mURL->GetSpec(sourceURISpec); #ifdef XP_MACOSX if (!m_bogus_attachment && StringBeginsWith(sourceURISpec, NS_LITERAL_CSTRING("file://"))) { // Unescape the path (i.e. un-URLify it) before making a FSSpec nsCAutoString filePath; filePath.Adopt(nsMsgGetLocalFileFromURL(sourceURISpec.get())); nsCAutoString unescapedFilePath; MsgUnescapeString(filePath, 0, unescapedFilePath); nsCOMPtr<nsILocalFile> sourceFile; NS_NewNativeLocalFile(unescapedFilePath, true, getter_AddRefs(sourceFile)); if (!sourceFile) return NS_ERROR_FAILURE; // check if it is a bundle. if it is, we'll zip it. // if not, we'll apple encode it (applesingle or appledouble) nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(sourceFile)); bool isPackage; macFile->IsPackage(&isPackage); if (isPackage) rv = ConvertToZipFile(macFile); else rv = ConvertToAppleEncoding(sourceURISpec, unescapedFilePath, macFile); NS_ENSURE_SUCCESS(rv, rv); } #endif /* XP_MACOSX */ // // Ok, here we are, we need to fire the URL off and get the data // in the temp file // // Create a fetcher for the URL attachment... nsCOMPtr<nsIURLFetcher> fetcher = do_CreateInstance(NS_URLFETCHER_CONTRACTID, &rv); if (NS_FAILED(rv) || !fetcher) { if (NS_SUCCEEDED(rv)) return NS_ERROR_UNEXPECTED; else return rv; } return fetcher->FireURLRequest(mURL, mTmpFile, mOutFile, FetcherURLDoneCallback, this); }
nsresult nsMsgAttachmentHandler::UrlExit(nsresult status, const PRUnichar* aMsg) { NS_ASSERTION(m_mime_delivery_state != nsnull, "not-null m_mime_delivery_state"); // Close the file, but don't delete the disk file (or the file spec.) if (mOutFile) { mOutFile->Close(); mOutFile = nsnull; } // this silliness is because Windows nsILocalFile caches its file size // so if an output stream writes to it, it will still return the original // cached size. if (mTmpFile) { nsCOMPtr <nsIFile> tmpFile; mTmpFile->Clone(getter_AddRefs(tmpFile)); mTmpFile = do_QueryInterface(tmpFile); } mRequest = nsnull; // First things first, we are now going to see if this is an HTML // Doc and if it is, we need to see if we can determine the charset // for this part by sniffing the HTML file. // This is needed only when the charset is not set already. // (e.g. a charset may be specified in HTTP header) // if (!m_type.IsEmpty() && m_charset.IsEmpty() && m_type.LowerCaseEqualsLiteral(TEXT_HTML)) m_charset = nsMsgI18NParseMetaCharset(mTmpFile); nsresult mimeDeliveryStatus; m_mime_delivery_state->GetStatus(&mimeDeliveryStatus); if (mimeDeliveryStatus == NS_ERROR_ABORT) status = NS_ERROR_ABORT; if (NS_FAILED(status) && status != NS_ERROR_ABORT && NS_SUCCEEDED(mimeDeliveryStatus)) { // At this point, we should probably ask a question to the user // if we should continue without this attachment. // bool keepOnGoing = true; nsCString turl; nsString msg; PRUnichar *printfString = nsnull; nsresult rv; nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle)); NS_ENSURE_SUCCESS(rv, rv); nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow; m_mime_delivery_state->GetDeliveryMode(&mode); if (mode == nsIMsgSend::nsMsgSaveAsDraft || mode == nsIMsgSend::nsMsgSaveAsTemplate) bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SAVING, getter_Copies(msg)); else bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SENDING, getter_Copies(msg)); if (!m_realName.IsEmpty()) printfString = nsTextFormatter::smprintf(msg.get(), m_realName.get()); else if (NS_SUCCEEDED(mURL->GetSpec(turl)) && !turl.IsEmpty()) { nsCAutoString unescapedUrl; MsgUnescapeString(turl, 0, unescapedUrl); if (unescapedUrl.IsEmpty()) printfString = nsTextFormatter::smprintf(msg.get(), turl.get()); else printfString = nsTextFormatter::smprintf(msg.get(), unescapedUrl.get()); } else printfString = nsTextFormatter::smprintf(msg.get(), "?"); nsCOMPtr<nsIPrompt> aPrompt; if (m_mime_delivery_state) m_mime_delivery_state->GetDefaultPrompt(getter_AddRefs(aPrompt)); nsMsgAskBooleanQuestionByString(aPrompt, printfString, &keepOnGoing); PR_FREEIF(printfString); if (keepOnGoing) { status = 0; m_bogus_attachment = true; //That will cause this attachment to be ignored. } else { status = NS_ERROR_ABORT; m_mime_delivery_state->SetStatus(status); nsresult ignoreMe; m_mime_delivery_state->Fail(status, nsnull, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, 0, nsnull); SetMimeDeliveryState(nsnull); return status; } } m_done = true; // // Ok, now that we have the file here on disk, we need to see if there was // a need to do conversion to plain text...if so, the magic happens here, // otherwise, just move on to other attachments... // if (NS_SUCCEEDED(status) && !m_type.LowerCaseEqualsLiteral(TEXT_PLAIN) && m_desiredType.LowerCaseEqualsLiteral(TEXT_PLAIN)) { // // Conversion to plain text desired. // PRInt32 width = 72; nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID)); if (pPrefBranch) pPrefBranch->GetIntPref("mailnews.wraplength", &width); // Let sanity reign! if (width == 0) width = 72; else if (width < 10) width = 10; else if (width > 30000) width = 30000; // // Now use the converter service here to do the right // thing and convert this data to plain text for us! // nsAutoString conData; if (NS_SUCCEEDED(LoadDataFromFile(mTmpFile, conData, true))) { if (NS_SUCCEEDED(ConvertBufToPlainText(conData, UseFormatFlowed(m_charset.get())))) { if (mDeleteFile) mTmpFile->Remove(false); nsCOMPtr<nsIOutputStream> outputStream; nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTmpFile, PR_WRONLY | PR_CREATE_FILE, 00600); if (NS_SUCCEEDED(rv)) { nsCAutoString tData; if (NS_FAILED(ConvertFromUnicode(m_charset.get(), conData, tData))) LossyCopyUTF16toASCII(conData, tData); if (!tData.IsEmpty()) { PRUint32 bytesWritten; (void) outputStream->Write(tData.get(), tData.Length(), &bytesWritten); } outputStream->Close(); // this silliness is because Windows nsILocalFile caches its file size // so if an output stream writes to it, it will still return the original // cached size. if (mTmpFile) { nsCOMPtr <nsIFile> tmpFile; mTmpFile->Clone(getter_AddRefs(tmpFile)); mTmpFile = do_QueryInterface(tmpFile); } } } } m_type = m_desiredType; m_desiredType.Truncate(); m_encoding.Truncate(); } PRUint32 pendingAttachmentCount = 0; m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); NS_ASSERTION (pendingAttachmentCount > 0, "no more pending attachment"); m_mime_delivery_state->SetPendingAttachmentCount(pendingAttachmentCount - 1); bool processAttachmentsSynchronously = false; m_mime_delivery_state->GetProcessAttachmentsSynchronously(&processAttachmentsSynchronously); if (NS_SUCCEEDED(status) && processAttachmentsSynchronously) { /* Find the next attachment which has not yet been loaded, if any, and start it going. */ PRUint32 i; nsMsgAttachmentHandler *next = 0; nsMsgAttachmentHandler *attachments = nsnull; PRUint32 attachmentCount = 0; m_mime_delivery_state->GetAttachmentCount(&attachmentCount); if (attachmentCount) m_mime_delivery_state->GetAttachmentHandlers(&attachments); for (i = 0; i < attachmentCount; i++) { if (!attachments[i].m_done) { next = &attachments[i]; // // rhp: We need to get a little more understanding to failed URL // requests. So, at this point if most of next is NULL, then we // should just mark it fetched and move on! We probably ignored // this earlier on in the send process. // if ( (!next->mURL) && (next->m_uri.IsEmpty()) ) { attachments[i].m_done = true; m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); m_mime_delivery_state->SetPendingAttachmentCount(pendingAttachmentCount - 1); next->mPartUserOmissionOverride = true; next = nsnull; continue; } break; } } if (next) { int status = next->SnarfAttachment(mCompFields); if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, nsnull, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, 0, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } } } m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); if (pendingAttachmentCount == 0) { // If this is the last attachment, then either complete the // delivery (if successful) or report the error by calling // the exit routine and terminating the delivery. if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, aMsg, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } else { status = m_mime_delivery_state->GatherMimeAttachments (); if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, aMsg, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } } } else { // If this is not the last attachment, but it got an error, // then report that error and continue if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); } } SetMimeDeliveryState(nsnull); return NS_OK; }
NS_IMETHODIMP nsAbContentHandler::HandleContent(const char *aContentType, nsIInterfaceRequestor *aWindowContext, nsIRequest *request) { NS_ENSURE_ARG_POINTER(request); nsresult rv = NS_OK; // First of all, get the content type and make sure it is a content type we know how to handle! if (PL_strcasecmp(aContentType, "application/x-addvcard") == 0) { nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request); if (!aChannel) return NS_ERROR_FAILURE; rv = aChannel->GetURI(getter_AddRefs(uri)); if (uri) { nsCAutoString path; rv = uri->GetPath(path); NS_ENSURE_SUCCESS(rv,rv); const char *startOfVCard = strstr(path.get(), "add?vcard="); if (startOfVCard) { nsCString unescapedData; // XXX todo, explain why we is escaped twice MsgUnescapeString(nsDependentCString(startOfVCard + strlen("add?vcard=")), 0, unescapedData); if (!aWindowContext) return NS_ERROR_FAILURE; nsCOMPtr<nsIDOMWindow> parentWindow = do_GetInterface(aWindowContext); if (!parentWindow) return NS_ERROR_FAILURE; nsCOMPtr<nsIAbManager> ab = do_GetService(NS_ABMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr <nsIAbCard> cardFromVCard; rv = ab->EscapedVCardToAbCard(unescapedData.get(), getter_AddRefs(cardFromVCard)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); ifptr->SetData(cardFromVCard); ifptr->SetDataIID(&NS_GET_IID(nsIAbCard)); nsCOMPtr<nsIDOMWindow> dialogWindow; rv = parentWindow->OpenDialog( NS_LITERAL_STRING("chrome://messenger/content/addressbook/abNewCardDialog.xul"), EmptyString(), NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"), ifptr, getter_AddRefs(dialogWindow)); NS_ENSURE_SUCCESS(rv, rv); } rv = NS_OK; } } else if (PL_strcasecmp(aContentType, "text/x-vcard") == 0) { // create a vcard stream listener that can parse the data stream // and bring up the appropriate UI // (1) cancel the current load operation. We'll restart it request->Cancel(NS_ERROR_ABORT); // get the url we were trying to open nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE); rv = channel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); // create a stream loader to handle the v-card data nsCOMPtr<nsIStreamLoader> streamLoader; rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), uri, this, aWindowContext); NS_ENSURE_SUCCESS(rv, rv); } else // The content-type was not application/x-addvcard... return NS_ERROR_WONT_HANDLE_CONTENT; return rv; }
nsresult nsMailtoUrl::ParseMailtoUrl(char * searchPart) { char *rest = searchPart; nsCString escapedInReplyToPart; nsCString escapedToPart; nsCString escapedCcPart; nsCString escapedSubjectPart; nsCString escapedNewsgroupPart; nsCString escapedNewsHostPart; nsCString escapedReferencePart; nsCString escapedBodyPart; nsCString escapedBccPart; nsCString escapedFollowUpToPart; nsCString escapedFromPart; nsCString escapedHtmlPart; nsCString escapedOrganizationPart; nsCString escapedReplyToPart; nsCString escapedPriorityPart; // okay, first, free up all of our old search part state..... CleanupMailtoState(); // m_toPart has the escaped address from before the query string, copy it // over so we can add on any additional to= addresses and unescape them all. escapedToPart = m_toPart; if (rest && *rest == '?') { /* start past the '?' */ rest++; } if (rest) { char *token = NS_strtok("&", &rest); while (token && *token) { char *value = 0; char *eq = PL_strchr(token, '='); if (eq) { value = eq+1; *eq = 0; } nsCString decodedName; MsgUnescapeString(nsDependentCString(token), 0, decodedName); switch (NS_ToUpper(decodedName.First())) { /* DO NOT support attachment= in mailto urls. This poses a security fire hole!!! case 'A': if (!PL_strcasecmp (token, "attachment")) m_attachmentPart = value; break; */ case 'B': if (decodedName.LowerCaseEqualsLiteral("bcc")) { if (!escapedBccPart.IsEmpty()) { escapedBccPart += ", "; escapedBccPart += value; } else escapedBccPart = value; } else if (decodedName.LowerCaseEqualsLiteral("body")) { if (!escapedBodyPart.IsEmpty()) { escapedBodyPart +="\n"; escapedBodyPart += value; } else escapedBodyPart = value; } break; case 'C': if (decodedName.LowerCaseEqualsLiteral("cc")) { if (!escapedCcPart.IsEmpty()) { escapedCcPart += ", "; escapedCcPart += value; } else escapedCcPart = value; } break; case 'F': if (decodedName.LowerCaseEqualsLiteral("followup-to")) escapedFollowUpToPart = value; else if (decodedName.LowerCaseEqualsLiteral("from")) escapedFromPart = value; break; case 'H': if (decodedName.LowerCaseEqualsLiteral("html-part") || decodedName.LowerCaseEqualsLiteral("html-body")) { // escapedHtmlPart holds the body for both html-part and html-body. escapedHtmlPart = value; mFormat = nsIMsgCompFormat::HTML; } break; case 'I': if (decodedName.LowerCaseEqualsLiteral("in-reply-to")) escapedInReplyToPart = value; break; case 'N': if (decodedName.LowerCaseEqualsLiteral("newsgroups")) escapedNewsgroupPart = value; else if (decodedName.LowerCaseEqualsLiteral("newshost")) escapedNewsHostPart = value; break; case 'O': if (decodedName.LowerCaseEqualsLiteral("organization")) escapedOrganizationPart = value; break; case 'R': if (decodedName.LowerCaseEqualsLiteral("references")) escapedReferencePart = value; else if (decodedName.LowerCaseEqualsLiteral("reply-to")) escapedReplyToPart = value; break; case 'S': if(decodedName.LowerCaseEqualsLiteral("subject")) escapedSubjectPart = value; break; case 'P': if (decodedName.LowerCaseEqualsLiteral("priority")) escapedPriorityPart = PL_strdup(value); break; case 'T': if (decodedName.LowerCaseEqualsLiteral("to")) { if (!escapedToPart.IsEmpty()) { escapedToPart += ", "; escapedToPart += value; } else escapedToPart = value; } break; default: break; } // end of switch statement... if (eq) *eq = '='; /* put it back */ token = NS_strtok("&", &rest); } // while we still have part of the url to parse... } // if rest && *rest // Get a global converter nsCOMPtr<nsIMimeConverter> mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID); // Now unescape everything, and mime-decode the things that can be encoded. UnescapeAndConvert(mimeConverter, escapedToPart, m_toPart); UnescapeAndConvert(mimeConverter, escapedCcPart, m_ccPart); UnescapeAndConvert(mimeConverter, escapedBccPart, m_bccPart); UnescapeAndConvert(mimeConverter, escapedSubjectPart, m_subjectPart); UnescapeAndConvert(mimeConverter, escapedNewsgroupPart, m_newsgroupPart); UnescapeAndConvert(mimeConverter, escapedReferencePart, m_referencePart); if (!escapedBodyPart.IsEmpty()) MsgUnescapeString(escapedBodyPart, 0, m_bodyPart); if (!escapedHtmlPart.IsEmpty()) MsgUnescapeString(escapedHtmlPart, 0, m_htmlPart); UnescapeAndConvert(mimeConverter, escapedNewsHostPart, m_newsHostPart); UnescapeAndConvert(mimeConverter, escapedFollowUpToPart, m_followUpToPart); UnescapeAndConvert(mimeConverter, escapedFromPart, m_fromPart); UnescapeAndConvert(mimeConverter, escapedOrganizationPart, m_organizationPart); UnescapeAndConvert(mimeConverter, escapedReplyToPart, m_replyToPart); UnescapeAndConvert(mimeConverter, escapedPriorityPart, m_priorityPart); nsCString inReplyToPart; // Not a member like the others... UnescapeAndConvert(mimeConverter, escapedInReplyToPart, inReplyToPart); if (!inReplyToPart.IsEmpty()) { // Ensure that References and In-Reply-To are consistent... The last // reference will be used as In-Reply-To header. if (m_referencePart.IsEmpty()) { // If References is not set, set it to be the In-Reply-To. m_referencePart = inReplyToPart; } else { // References is set. Add the In-Reply-To as last header unless it's // set as last reference already. int32_t lastRefStart = m_referencePart.RFindChar('<'); nsAutoCString lastReference; if (lastRefStart != -1) lastReference = StringTail(m_referencePart, lastRefStart); else lastReference = m_referencePart; if (lastReference != inReplyToPart) { m_referencePart += " "; m_referencePart += inReplyToPart; } } } return NS_OK; }