Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
nsresult nsMailtoUrl::ParseMailtoUrl(char * searchPart)
{
	char *rest = searchPart;
        nsCAutoString inReplyToPart;
	// okay, first, free up all of our old search part state.....
	CleanupMailtoState();

	if (rest && *rest == '?')
	{
 		/* start past the '?' */
		rest++;
	}

	if (rest)
	{
    char *token = nsCRT::strtok(rest, "&", &rest);
		while (token && *token)
		{
			char *value = 0;
      char *eq = PL_strchr(token, '=');
			if (eq)
			{
				value = eq+1;
				*eq = 0;
			}
			
			switch (nsCRT::ToUpper(*token))
			{
/* DO NOT support attachment= in mailto urls. This poses a security fire hole!!! 
				case 'A':
          if (!nsCRT::strcasecmp (token, "attachment"))
					  m_attachmentPart = value;
				  break;
*/
				case 'B':
				  if (!nsCRT::strcasecmp (token, "bcc"))
				  {
					  if (!m_bccPart.IsEmpty())
            {
               m_bccPart += ", ";
               m_bccPart += value;
            }
            else
					    m_bccPart = value; 
          }
					else if (!nsCRT::strcasecmp (token, "body"))
					{
            if (!m_bodyPart.IsEmpty())
            {
              m_bodyPart +="\n";
              m_bodyPart += value;
            }
            else
              m_bodyPart = value;
          }
          break;
        case 'C': 
					if (!nsCRT::strcasecmp  (token, "cc"))
					{
						if (!m_ccPart.IsEmpty())
						{
              m_ccPart += ", ";
              m_ccPart += value;
						}
						else
							m_ccPart = value;
					}
          break;
        case 'F': 
					if (!nsCRT::strcasecmp (token, "followup-to"))
						m_followUpToPart = value;
					else if (!nsCRT::strcasecmp (token, "from"))
						m_fromPart = value;
					break;
        case 'H':
          if (!nsCRT::strcasecmp(token, "html-part") || !nsCRT::strcasecmp (token, "html-body"))
          {
            // m_htmlPart holds the body for both html-part and html-body.
            m_htmlPart = value;
            mFormat = nsIMsgCompFormat::HTML;
          }
          break;
                                case 'I':
                                        if (!nsCRT::strcasecmp (token, "in-reply-to"))
                                                inReplyToPart = value;
                                        break;

				case 'N':
					if (!nsCRT::strcasecmp (token, "newsgroups"))
						m_newsgroupPart = value;
					else if (!nsCRT::strcasecmp (token, "newshost"))
						m_newsHostPart = value;
				  break;
				case 'O':
					if (!nsCRT::strcasecmp (token, "organization"))
						m_organizationPart = value;
					break;
        case 'R':
					if (!nsCRT::strcasecmp (token, "references"))
						m_referencePart = value;
					else if (!nsCRT::strcasecmp (token, "reply-to"))
						m_replyToPart = value;
					break;
				case 'S':
					if(!nsCRT::strcasecmp (token, "subject"))
						m_subjectPart = value;
					break;
				case 'P':
					if (!nsCRT::strcasecmp (token, "priority"))
						m_priorityPart = PL_strdup(value);
					break;
				case 'T':
					if (!nsCRT::strcasecmp (token, "to"))
				  {
						if (!m_toPart.IsEmpty())
						{
              m_toPart += ", ";
              m_toPart += value;
						}
						else
							m_toPart = value;
					}
					break;
        default:
          break;
      } // end of switch statement...
			
			if (eq)
				  *eq = '='; /* put it back */
				token = nsCRT::strtok(rest, "&", &rest);
		} // while we still have part of the url to parse...
	} // if rest && *rest

  // Ensure that References and In-Reply-To are consistent...
  if (!inReplyToPart.IsEmpty())
  {
    if (m_referencePart.IsEmpty())
      m_referencePart = inReplyToPart;
    else
    {
      const char * lastRef = strrchr(m_referencePart.get(), '<');
      nsCAutoString lastReference;
      lastReference = lastRef ? lastRef : m_referencePart.get();
      if (lastReference != inReplyToPart)
      {
        m_referencePart += " ";
        m_referencePart += inReplyToPart;
      }
    }
  }

  nsCOMPtr<nsIMimeConverter> mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID);
  char *decodedString;

  // Now unescape any fields that need escaped...
	if (!m_toPart.IsEmpty())
  {
		nsUnescape(m_toPart.BeginWriting());
    if (mimeConverter)
    {
      if (NS_SUCCEEDED(mimeConverter->DecodeMimeHeader(m_toPart.get(),
                                                       &decodedString,
                                                       "UTF-8", PR_FALSE))
                                                       && decodedString)
        m_toPart.Adopt(decodedString);
    }
  }
	if (!m_ccPart.IsEmpty())
  {
		nsUnescape(m_ccPart.BeginWriting());
    if (mimeConverter)
    {
      if (NS_SUCCEEDED(mimeConverter->DecodeMimeHeader(m_ccPart.get(),
                                                       &decodedString,
                                                       "UTF-8", PR_FALSE))
                                                       && decodedString)
        m_ccPart.Adopt(decodedString);
    }
  }
	if (!m_subjectPart.IsEmpty())
  {
    nsUnescape(m_subjectPart.BeginWriting());
    if (mimeConverter)
    {
      if (NS_SUCCEEDED(mimeConverter->DecodeMimeHeader(m_subjectPart.get(),
                                                       &decodedString,
                                                       "UTF-8", PR_FALSE))
                                                       && decodedString)
        m_subjectPart.Adopt(decodedString);
    }
  }
	if (!m_newsgroupPart.IsEmpty())
		nsUnescape(m_newsgroupPart.BeginWriting());
	if (!m_referencePart.IsEmpty())
		nsUnescape(m_referencePart.BeginWriting());
	if (!m_bodyPart.IsEmpty())
  {
		nsUnescape(m_bodyPart.BeginWriting());
    if (mimeConverter)
    {
      if (NS_SUCCEEDED(mimeConverter->DecodeMimeHeader(m_bodyPart.get(),
                                                       &decodedString,
                                                       "UTF-8", PR_FALSE,
                                                       PR_FALSE))
                                                       && decodedString)
        m_bodyPart.Adopt(decodedString);
    }
  }
	if (!m_newsHostPart.IsEmpty())
		nsUnescape(m_newsHostPart.BeginWriting());

	return NS_OK;
}