Exemple #1
0
void
nsHttpResponseHead::ParseStatusLine(const char *line)
{
    //
    // Parse Status-Line:: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
    //

    // HTTP-Version
    ParseVersion(line);

    if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) {
        mStatus = 200;
        AssignDefaultStatusText();
    }
    else {
        // Status-Code
        mStatus = (uint16_t) atoi(++line);
        if (mStatus == 0) {
            LOG(("mal-formed response status; assuming status = 200\n"));
            mStatus = 200;
        }

        // Reason-Phrase is whatever is remaining of the line
        if (!(line = PL_strchr(line, ' '))) {
            AssignDefaultStatusText();
        }
        else
            mStatusText = nsDependentCString(++line);
    }

    LOG(("Have status line [version=%u status=%u statusText=%s]\n",
        unsigned(mVersion), unsigned(mStatus), mStatusText.get()));
}
Exemple #2
0
NS_IMETHODIMP
nsCommandLine::Init(int32_t argc, const char* const* argv, nsIFile* aWorkingDir,
                    uint32_t aState)
{
  NS_ENSURE_ARG_MAX(aState, 2);

  int32_t i;

  mWorkingDir = aWorkingDir;

  // skip argv[0], we don't want it
  for (i = 1; i < argc; ++i) {
    const char* curarg = argv[i];

#ifdef DEBUG_COMMANDLINE
    printf("Testing native arg %i: '%s'\n", i, curarg);
#endif
#if defined(XP_WIN)
    if (*curarg == '/') {
      char* dup = PL_strdup(curarg);
      if (!dup) return NS_ERROR_OUT_OF_MEMORY;

      *dup = '-';
      char* colon = PL_strchr(dup, ':');
      if (colon) {
        *colon = '\0';
        appendArg(dup);
        appendArg(colon+1);
      } else {
        appendArg(dup);
      }
      PL_strfree(dup);
      continue;
    }
#endif
    if (*curarg == '-') {
      if (*(curarg+1) == '-') ++curarg;

      char* dup = PL_strdup(curarg);
      if (!dup) return NS_ERROR_OUT_OF_MEMORY;

      char* eq = PL_strchr(dup, '=');
      if (eq) {
        *eq = '\0';
        appendArg(dup);
        appendArg(eq + 1);
      } else {
        appendArg(dup);
      }
      PL_strfree(dup);
      continue;
    }

    appendArg(curarg);
  }

  mState = aState;

  return NS_OK;
}
void
nsHttpResponseHead::ParseStatusLine(const char *line)
{
    //
    // Parse Status-Line:: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
    //
 
    // HTTP-Version
    ParseVersion(line);
    
    if ((mVersion == NS_HTTP_VERSION_0_9) || !(line = PL_strchr(line, ' '))) {
        mStatus = 200;
        mStatusText.AssignLiteral("OK");
    }
    else {
        // Status-Code
        mStatus = (PRUint16) atoi(++line);
        if (mStatus == 0) {
            LOG(("mal-formed response status; assuming status = 200\n"));
            mStatus = 200;
        }

        // Reason-Phrase is whatever is remaining of the line
        if (!(line = PL_strchr(line, ' '))) {
            LOG(("mal-formed response status line; assuming statusText = 'OK'\n"));
            mStatusText.AssignLiteral("OK");
        }
        else
            mStatusText = ++line;
    }

    LOG(("Have status line [version=%u status=%u statusText=%s]\n",
        PRUintn(mVersion), PRUintn(mStatus), mStatusText.get()));
}
static void
LogHeaders(const char *lines)
{
    nsCAutoString buf;
    char *p;
    while ((p = PL_strstr(lines, "\r\n")) != nsnull) {
        buf.Assign(lines, p - lines);
        if (PL_strcasestr(buf.get(), "authorization: ") != nsnull) {
            char *p = PL_strchr(PL_strchr(buf.get(), ' ')+1, ' ');
            while (*++p) *p = '*';
        }
        LOG3(("  %s\n", buf.get()));
        lines = p + 2;
    }
}
char *nsMsgSearchAdapter::TransformSpacesToStars (const char *spaceString, msg_TransformType transformType)
{
  char *starString;

  if (transformType == kOverwrite)
  {
    if ((starString = strdup(spaceString)) != nsnull)
    {
      char *star = starString;
      while ((star = PL_strchr(star, ' ')) != nsnull)
        *star = '*';
    }
  }
  else
  {
    int i, count;

    for (i = 0, count = 0; spaceString[i]; )
    {
      if (spaceString[i++] == ' ')
      {
        count++;
        while (spaceString[i] && spaceString[i] == ' ') i++;
      }
    }

    if (transformType == kSurround)
      count *= 2;

    if (count > 0)
    {
      if ((starString = (char *)PR_Malloc(i + count + 1)) != nsnull)
      {
        int j;

        for (i = 0, j = 0; spaceString[i]; )
        {
          if (spaceString[i] == ' ')
          {
            starString[j++] = '*';
            starString[j++] = ' ';
            if (transformType == kSurround)
              starString[j++] = '*';

            i++;
            while (spaceString[i] && spaceString[i] == ' ')
              i++;
          }
          else
            starString[j++] = spaceString[i++];
        }
        starString[j] = 0;
      }
    }
    else
      starString = strdup(spaceString);
  }

  return starString;
}
// 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
nsMsgFilterList::WriteStrAttr(nsMsgFilterFileAttribValue attrib,
                              const char *aStr, nsIOutputStream *aStream)
{
  nsresult rv = NS_OK;
  if (aStr && *aStr && aStream) // only proceed if we actually have a string to write out.
  {
    char *escapedStr = nullptr;
    if (PL_strchr(aStr, '"'))
      escapedStr = nsMsgSearchTerm::EscapeQuotesInStr(aStr);

    const char *attribStr = GetStringForAttrib(attrib);
    if (attribStr)
    {
      uint32_t bytesWritten;
      nsAutoCString writeStr(attribStr);
      writeStr.AppendLiteral("=\"");
      writeStr.Append((escapedStr) ? escapedStr : aStr);
      writeStr.AppendLiteral("\"" MSG_LINEBREAK);
      rv = aStream->Write(writeStr.get(), writeStr.Length(), &bytesWritten);
    }
    PR_Free(escapedStr);
  }
  return rv;
}
static char *lexLookaheadWord() {
  /* this function can lookahead word with max size of PR_MAX_LEX_LOOKAHEAD_0
   /  and thing bigger than that will stop the lookahead and return 0;
   / leading white spaces are not recoverable.
   */
  int c;
  int len = 0;
  int curgetptr = 0;
  lexSkipWhite();
  lexClearToken();
  curgetptr = (int)lexBuf.getPtr; /* remember! */
  while (len < (PR_MAX_LEX_LOOKAHEAD_0)) {
    c = lexGetc();
    len++;
    if (c == EOF || PL_strchr("\t\n ;:=", (char)c)) {
      lexAppendc(0);
      /* restore lookahead buf. */
      lexBuf.len += len;
      lexBuf.getPtr = curgetptr;
      return lexStr();
    } else
      lexAppendc(c);
  }
  lexBuf.len += len; /* char that has been moved to lookahead buffer */
  lexBuf.getPtr = curgetptr;
  return 0;
}
static char *lexGetStrUntil(char *termset) {
  int c = lexLookahead();
  lexClearToken();
  while (c != EOF && !PL_strchr(termset, c)) {
    lexAppendc(c);
    lexSkipLookahead();
    c = lexLookahead();
  }
  lexAppendc(0);
  return c == EOF ? 0 : lexStr();
}
Exemple #10
0
static DIR_PrefId DIR_AtomizePrefName(const char *prefname)
{
  if (!prefname)
    return idNone;

  DIR_PrefId rc = idNone;

  /* Skip the "ldap_2.servers.<server-name>." portion of the string.
   */
  if (PL_strstr(prefname, PREF_LDAP_SERVER_TREE_NAME) == prefname)
  {
    prefname = PL_strchr(&prefname[PL_strlen(PREF_LDAP_SERVER_TREE_NAME) + 1], '.');
    if (!prefname)
      return idNone;
    else
      prefname = prefname + 1;
  }

  switch (prefname[0]) {
  case 'd':
    switch (prefname[1]) {
    case 'e': /* description */
      rc = idDescription;
      break;
    case 'i': /* dirType */
      rc = idType;
      break;
    }
    break;

  case 'f':
    rc = idFileName;
    break;

  case 'p':
    switch (prefname[1]) {
    case 'o':
      switch (prefname[2]) {
      case 's': /* position */
        rc = idPosition;
        break;
      }
      break;
    }
    break;

  case 'u': /* uri */
    rc = idUri;
    break;
  }

  return rc;
}
static char *lexGetWord() {
  int c;
  lexSkipWhite();
  lexClearToken();
  c = lexLookahead();
  while (c != EOF && !PL_strchr("\t\n ;:=", (char)c)) {
    lexAppendc(c);
    lexSkipLookahead();
    c = lexLookahead();
  }
  lexAppendc(0);
  return lexStr();
}
NS_IMETHODIMP
nsMIMEHeaderParamImpl::DecodeRFC2047Header(const char* aHeaderVal, 
                                           const char* aDefaultCharset, 
                                           PRBool aOverrideCharset, 
                                           PRBool aEatContinuations,
                                           nsACString& aResult)
{
  aResult.Truncate();
  if (!aHeaderVal)
    return NS_ERROR_INVALID_ARG;
  if (!*aHeaderVal)
    return NS_OK;


  // If aHeaderVal is RFC 2047 encoded or is not a UTF-8 string  but
  // aDefaultCharset is specified, decodes RFC 2047 encoding and converts
  // to UTF-8. Otherwise, just strips away CRLF. 
  if (PL_strstr(aHeaderVal, "=?") || 
      aDefaultCharset && (!IsUTF8(nsDependentCString(aHeaderVal)) || 
      Is7bitNonAsciiString(aHeaderVal, PL_strlen(aHeaderVal)))) {
    DecodeRFC2047Str(aHeaderVal, aDefaultCharset, aOverrideCharset, aResult);
  } else if (aEatContinuations && 
             (PL_strchr(aHeaderVal, '\n') || PL_strchr(aHeaderVal, '\r'))) {
    aResult = aHeaderVal;
  } else {
    aEatContinuations = PR_FALSE;
    aResult = aHeaderVal;
  }

  if (aEatContinuations) {
    nsCAutoString temp(aResult);
    temp.ReplaceSubstring("\n\t", " ");
    temp.ReplaceSubstring("\r\t", " ");
    temp.StripChars("\r\n");
    aResult = temp;
  }

  return NS_OK;
}
Exemple #13
0
void
nsHttpResponseHead::ParseVersion(const char *str)
{
    // Parse HTTP-Version:: "HTTP" "/" 1*DIGIT "." 1*DIGIT

    LOG(("nsHttpResponseHead::ParseVersion [version=%s]\n", str));

    // make sure we have HTTP at the beginning
    if (PL_strncasecmp(str, "HTTP", 4) != 0) {
        if (PL_strncasecmp(str, "ICY ", 4) == 0) {
            // ShoutCast ICY is HTTP/1.0-like. Assume it is HTTP/1.0.
            LOG(("Treating ICY as HTTP 1.0\n"));
            mVersion = NS_HTTP_VERSION_1_0;
            return;
        }
        LOG(("looks like a HTTP/0.9 response\n"));
        mVersion = NS_HTTP_VERSION_0_9;
        return;
    }
    str += 4;

    if (*str != '/') {
        LOG(("server did not send a version number; assuming HTTP/1.0\n"));
        // NCSA/1.5.2 has a bug in which it fails to send a version number
        // if the request version is HTTP/1.1, so we fall back on HTTP/1.0
        mVersion = NS_HTTP_VERSION_1_0;
        return;
    }

    char *p = PL_strchr(str, '.');
    if (p == nullptr) {
        LOG(("mal-formed server version; assuming HTTP/1.0\n"));
        mVersion = NS_HTTP_VERSION_1_0;
        return;
    }

    ++p; // let b point to the minor version

    int major = atoi(str + 1);
    int minor = atoi(p);

    if ((major > 1) || ((major == 1) && (minor >= 1)))
        // at least HTTP/1.1
        mVersion = NS_HTTP_VERSION_1_1;
    else
        // treat anything else as version 1.0
        mVersion = NS_HTTP_VERSION_1_0;
}
Exemple #14
0
/* dir_ValidateAndAddNewServer
 *
 * This function verifies that the position, serverName and description values
 * are set for the given prefName.  If they are then it adds the server to the
 * unified server list.
 */
static PRBool dir_ValidateAndAddNewServer(nsVoidArray *wholeList, const char *fullprefname)
{
  PRBool rc = PR_FALSE;

  const char *endname = PL_strchr(&fullprefname[PL_strlen(PREF_LDAP_SERVER_TREE_NAME) + 1], '.');
  if (endname)
  {
    char *prefname = (char *)PR_Malloc(endname - fullprefname + 1);
    if (prefname)
    {
      PRInt32 dirType;
      char *t1 = nsnull, *t2 = nsnull;

      PL_strncpyz(prefname, fullprefname, endname - fullprefname + 1);

      dirType = DIR_GetIntPref(prefname, "dirType", -1);
      if (dirType != -1 &&
          DIR_GetIntPref(prefname, "position", 0) != 0 &&
          (t1 = DIR_GetStringPref(prefname, "description", nsnull)) != nsnull)
      {
        if (dirType == PABDirectory || dirType == IMDirectory ||
           (t2 = DIR_GetStringPref(prefname, "serverName",  nsnull)) != nsnull)
        {
          DIR_Server *server = (DIR_Server *)PR_Malloc(sizeof(DIR_Server));
          if (server)
          {
            DIR_InitServer(server, (DirectoryType)dirType);
            server->prefName = prefname;
            DIR_GetPrefsForOneServer(server);
            DIR_SetServerPosition(wholeList, server, server->position);
            rc = PR_TRUE;
          }
          PR_FREEIF(t2);
        }
        PR_Free(t1);
      }
      else
        PR_Free(prefname);
    }
  }

  return rc;
}
Exemple #15
0
OSErr ConvertMacPathToUnixPath(const char *macPath, char **unixPath)
{
  PRIntn len;
  char *cursor;
  
  len = PL_strlen(macPath);
  cursor = (char*)PR_Malloc(len+2);
  if (!cursor)
    return memFullErr;
    
  memcpy(cursor+1, macPath, len+1);
  *unixPath = cursor;
  *cursor = '/';
  while ((cursor = PL_strchr(cursor, ':')) != NULL) {
    *cursor = '/';
    cursor++;
  }
  return noErr;
}
// We use an rdf attribute to mark if this is a container or not.
// Note that we still have to do string comparisons as a fallback
// because stuff like the personal toolbar and bookmarks check whether
// a URL is a container, and we have no attribute in that case.
PRBool
nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r)
{
  nsCOMPtr<nsIRDFNode> node;
  GetTarget(r, kNC_IsContainer, PR_TRUE, getter_AddRefs(node));

  PRBool isContainerFlag = PR_FALSE;

  if (node && NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag))) {
    return isContainerFlag;
  } else {
    nsXPIDLCString uri;
    
    // For gopher, we need to follow the URL attribute to get the
    // real destination
    GetDestination(r,uri);

    if ((uri.get()) && (!strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1))) {
      if (uri.Last() == '/') {
        isContainerFlag = PR_TRUE;
      }
    }

    // A gopher url is of the form:
    // gopher://example.com/xFileNameToGet
    // where x is a single character representing the type of file
    // 1 is a directory, and 7 is a search.
    // Searches will cause a dialog to be popped up (asking the user what
    // to search for), and so even though searches return a directory as a
    // result, don't treat it as a directory here.

    // The isContainerFlag test above will correctly handle this when a
    // search url is passed in as the baseuri
    if ((uri.get()) &&
        (!strncmp(uri,kGopherProtocol, sizeof(kGopherProtocol)-1))) {
      char* pos = PL_strchr(uri+sizeof(kGopherProtocol)-1, '/');
      if (!pos || pos[1] == '\0' || pos[1] == '1')
        isContainerFlag = PR_TRUE;
    }
  }
  return isContainerFlag;
}
nsresult 
nsMIMEHeaderParamImpl::DoParameterInternal(const char *aHeaderValue, 
                                           const char *aParamName,
                                           ParamDecoding aDecoding,
                                           char **aCharset,
                                           char **aLang,
                                           char **aResult)
{

  if (!aHeaderValue ||  !*aHeaderValue || !aResult)
    return NS_ERROR_INVALID_ARG;

  *aResult = nullptr;

  if (aCharset) *aCharset = nullptr;
  if (aLang) *aLang = nullptr;

  nsCAutoString charset;

  bool acceptContinuations = (aDecoding != RFC_5987_DECODING);

  const char *str = aHeaderValue;

  // skip leading white space.
  for (; *str &&  nsCRT::IsAsciiSpace(*str); ++str)
    ;
  const char *start = str;
  
  // aParamName is empty. return the first (possibly) _unnamed_ 'parameter'
  // For instance, return 'inline' in the following case:
  // Content-Disposition: inline; filename=.....
  if (!aParamName || !*aParamName) 
    {
      for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str)
        ;
      if (str == start)
        return NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY;

      *aResult = (char *) nsMemory::Clone(start, (str - start) + 1);
      NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
      (*aResult)[str - start] = '\0';  // null-terminate
      return NS_OK;
    }

  /* Skip forward to first ';' */
  for (; *str && *str != ';' && *str != ','; ++str)
    ;
  if (*str)
    str++;
  /* Skip over following whitespace */
  for (; *str && nsCRT::IsAsciiSpace(*str); ++str)
    ;

  // Some broken http servers just specify parameters
  // like 'filename' without specifying disposition
  // method. Rewind to the first non-white-space
  // character.
  
  if (!*str)
    str = start;

  // RFC2231 - The legitimate parm format can be:
  // A. title=ThisIsTitle 
  // B. title*=us-ascii'en-us'This%20is%20wierd.
  // C. title*0*=us-ascii'en'This%20is%20wierd.%20We
  //    title*1*=have%20to%20support%20this.
  //    title*2="Else..."
  // D. title*0="Hey, what you think you are doing?"
  //    title*1="There is no charset and lang info."
  // RFC5987: only A and B
  
  // collect results for the different algorithms (plain filename,
  // RFC5987/2231-encoded filename, + continuations) separately and decide
  // which to use at the end
  char *caseAResult = NULL;
  char *caseBResult = NULL;
  char *caseCDResult = NULL;

  // collect continuation segments
  nsTArray<Continuation> segments;


  // our copies of the charset parameter, kept separately as they might
  // differ for the two formats
  nsDependentCSubstring charsetB, charsetCD;

  nsDependentCSubstring lang;

  PRInt32 paramLen = strlen(aParamName);

  while (*str) {
    // find name/value

    const char *nameStart = str;
    const char *nameEnd = NULL;
    const char *valueStart = str;
    const char *valueEnd = NULL;
    bool isQuotedString = false;

    NS_ASSERTION(!nsCRT::IsAsciiSpace(*str), "should be after whitespace.");

    // Skip forward to the end of this token. 
    for (; *str && !nsCRT::IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++)
      ;
    nameEnd = str;

    PRInt32 nameLen = nameEnd - nameStart;

    // Skip over whitespace, '=', and whitespace
    while (nsCRT::IsAsciiSpace(*str)) ++str;
    if (!*str) {
      break;
    }
    if (*str++ != '=') {
      // don't accept parameters without "="
      goto increment_str;
    }
    while (nsCRT::IsAsciiSpace(*str)) ++str;

    if (*str != '"') {
      // The value is a token, not a quoted string.
      valueStart = str;
      for (valueEnd = str;
           *valueEnd && !nsCRT::IsAsciiSpace (*valueEnd) && *valueEnd != ';';
           valueEnd++)
        ;
      str = valueEnd;
    } else {
      isQuotedString = true;
      
      ++str;
      valueStart = str;
      for (valueEnd = str; *valueEnd; ++valueEnd) {
        if (*valueEnd == '\\')
          ++valueEnd;
        else if (*valueEnd == '"')
          break;
      }
      str = valueEnd;
      // *valueEnd != null means that *valueEnd is quote character.
      if (*valueEnd)
        str++;
    }

    // See if this is the simplest case (case A above),
    // a 'single' line value with no charset and lang.
    // If so, copy it and return.
    if (nameLen == paramLen &&
        !nsCRT::strncasecmp(nameStart, aParamName, paramLen)) {

      if (caseAResult) {
        // we already have one caseA result, ignore subsequent ones
        goto increment_str;
      }

      // if the parameter spans across multiple lines we have to strip out the
      //     line continuation -- jht 4/29/98 
      nsCAutoString tempStr(valueStart, valueEnd - valueStart);
      tempStr.StripChars("\r\n");
      char *res = ToNewCString(tempStr);
      NS_ENSURE_TRUE(res, NS_ERROR_OUT_OF_MEMORY);
      
      if (isQuotedString)
        RemoveQuotedStringEscapes(res);

      caseAResult = res;
      // keep going, we may find a RFC 2231/5987 encoded alternative
    }
    // case B, C, and D
    else if (nameLen > paramLen &&
             !nsCRT::strncasecmp(nameStart, aParamName, paramLen) &&
             *(nameStart + paramLen) == '*') {

      // 1st char past '*'       
      const char *cp = nameStart + paramLen + 1; 

      // if param name ends in "*" we need do to RFC5987 "ext-value" decoding
      bool needExtDecoding = *(nameEnd - 1) == '*';      

      bool caseB = nameLen == paramLen + 1;
      bool caseCStart = (*cp == '0') && needExtDecoding;

      // parse the segment number
      PRInt32 segmentNumber = -1;
      if (!caseB) {
        PRInt32 segLen = (nameEnd - cp) - (needExtDecoding ? 1 : 0);
        segmentNumber = parseSegmentNumber(cp, segLen);

        if (segmentNumber == -1) {
          acceptContinuations = false;
          goto increment_str;
        }
      }

      // CaseB and start of CaseC: requires charset and optional language
      // in quotes (quotes required even if lang is blank)
      if (caseB || (caseCStart && acceptContinuations)) {
        // look for single quotation mark(')
        const char *sQuote1 = PL_strchr(valueStart, 0x27);
        const char *sQuote2 = sQuote1 ? PL_strchr(sQuote1 + 1, 0x27) : nullptr;

        // Two single quotation marks must be present even in
        // absence of charset and lang. 
        if (!sQuote1 || !sQuote2) {
          NS_WARNING("Mandatory two single quotes are missing in header parameter\n");
        }

        const char *charsetStart = NULL;
        PRInt32 charsetLength = 0;
        const char *langStart = NULL;
        PRInt32 langLength = 0;
        const char *rawValStart = NULL;
        PRInt32 rawValLength = 0;

        if (sQuote2 && sQuote1) {
          // both delimiters present: charSet'lang'rawVal
          rawValStart = sQuote2 + 1;
          rawValLength = valueEnd - rawValStart;

          langStart = sQuote1 + 1;
          langLength = sQuote2 - langStart;

          charsetStart = valueStart;
          charsetLength = sQuote1 - charsetStart;
        }
        else if (sQuote1) {
          // one delimiter; assume charset'rawVal
          rawValStart = sQuote1 + 1;
          rawValLength = valueEnd - rawValStart;

          charsetStart = valueStart;
          charsetLength = sQuote1 - valueStart;
        }
        else {
          // no delimiter: just rawVal
          rawValStart = valueStart;
          rawValLength = valueEnd - valueStart;
        }

        if (langLength != 0) {
          lang.Assign(langStart, langLength);
        }

        // keep the charset for later
        if (caseB) {
          charsetB.Assign(charsetStart, charsetLength);
        } else {
          // if caseCorD
          charsetCD.Assign(charsetStart, charsetLength);
        }

        // non-empty value part
        if (rawValLength > 0) {
          if (!caseBResult && caseB) {
            // allocate buffer for the raw value
            char *tmpResult = (char *) nsMemory::Clone(rawValStart, rawValLength + 1);
            if (!tmpResult) {
              goto increment_str;
            }
            *(tmpResult + rawValLength) = 0;

            nsUnescape(tmpResult);
            caseBResult = tmpResult;
          } else {
            // caseC
            bool added = addContinuation(segments, 0, rawValStart,
                                         rawValLength, needExtDecoding,
                                         isQuotedString);

            if (!added) {
              // continuation not added, stop processing them
              acceptContinuations = false;
            }
          }
        }
      }  // end of if-block :  title*0*=  or  title*= 
      // caseD: a line of multiline param with no need for unescaping : title*[0-9]=
      // or 2nd or later lines of a caseC param : title*[1-9]*= 
      else if (acceptContinuations && segmentNumber != -1) {
        PRUint32 valueLength = valueEnd - valueStart;

        bool added = addContinuation(segments, segmentNumber, valueStart,
                                     valueLength, needExtDecoding,
                                     isQuotedString);

        if (!added) {
          // continuation not added, stop processing them
          acceptContinuations = false;
        }
      } // end of if-block :  title*[0-9]= or title*[1-9]*=
    }

    // str now points after the end of the value.
    //   skip over whitespace, ';', whitespace.
increment_str:      
    while (nsCRT::IsAsciiSpace(*str)) ++str;
    if (*str == ';') {
      ++str;
    } else {
      // stop processing the header field; either we are done or the
      // separator was missing
      break;
    }
    while (nsCRT::IsAsciiSpace(*str)) ++str;
  }

  caseCDResult = combineContinuations(segments);

  if (caseBResult && !charsetB.IsEmpty()) {
    // check that the 2231/5987 result decodes properly given the
    // specified character set
    if (!IsValidOctetSequenceForCharset(charsetB, caseBResult))
      caseBResult = NULL;
  }

  if (caseCDResult && !charsetCD.IsEmpty()) {
    // check that the 2231/5987 result decodes properly given the
    // specified character set
    if (!IsValidOctetSequenceForCharset(charsetCD, caseCDResult))
      caseCDResult = NULL;
  }

  if (caseBResult) {
    // prefer simple 5987 format over 2231 with continuations
    *aResult = caseBResult;
    caseBResult = NULL;
    charset.Assign(charsetB);
  }
  else if (caseCDResult) {
    // prefer 2231/5987 with or without continuations over plain format
    *aResult = caseCDResult;
    caseCDResult = NULL;
    charset.Assign(charsetCD);
  }
  else if (caseAResult) {
    *aResult = caseAResult;
    caseAResult = NULL;
  }

  // free unused stuff
  nsMemory::Free(caseAResult);
  nsMemory::Free(caseBResult);
  nsMemory::Free(caseCDResult);

  // if we have a result
  if (*aResult) {
    // then return charset and lang as well
    if (aLang && !lang.IsEmpty()) {
      PRUint32 len = lang.Length();
      *aLang = (char *) nsMemory::Clone(lang.BeginReading(), len + 1);
      if (*aLang) {
        *(*aLang + len) = 0;
      }
   }
    if (aCharset && !charset.IsEmpty()) {
      PRUint32 len = charset.Length();
      *aCharset = (char *) nsMemory::Clone(charset.BeginReading(), len + 1);
      if (*aCharset) {
        *(*aCharset + len) = 0;
      }
    }
  }

  return *aResult ? NS_OK : NS_ERROR_INVALID_ARG;
}
Exemple #18
0
/*********************************************************************
 *
 * P r o c e s s C o m m a n d F i l e
 */
int
ProcessCommandFile()
{
    PRFileDesc *fd;
#define CMD_FILE_BUFSIZE 1024
    char buf[CMD_FILE_BUFSIZE];
    char *equals;
    int linenum = 0;
    int retval = -1;
    OPT_TYPE type;

    fd = PR_Open(cmdFile, PR_RDONLY, 0777);
    if (!fd) {
        PR_fprintf(errorFD, "ERROR: Unable to open command file %s.\n");
        errorCount++;
        return -1;
    }

    while (pr_fgets(buf, CMD_FILE_BUFSIZE, fd)) {
        char *eol;
        linenum++;

        /* Chop off final newline */
        eol = PL_strchr(buf, '\r');
        if (!eol) {
            eol = PL_strchr(buf, '\n');
        }
        if (eol)
            *eol = '\0';

        equals = PL_strchr(buf, '=');
        if (!equals) {
            continue;
        }

        *equals = '\0';
        equals++;

        /* Now buf points to the attribute, and equals points to the value. */

        /* This is pretty straightforward, just deal with whatever attribute
         * this is */
        if (!PL_strcasecmp(buf, "basename")) {
            type = BASE_OPT;
        } else if (!PL_strcasecmp(buf, "compression")) {
            type = COMPRESSION_OPT;
        } else if (!PL_strcasecmp(buf, "certdir")) {
            type = CERT_DIR_OPT;
        } else if (!PL_strcasecmp(buf, "extension")) {
            type = EXTENSION_OPT;
        } else if (!PL_strcasecmp(buf, "generate")) {
            type = GENKEY_OPT;
        } else if (!PL_strcasecmp(buf, "installScript")) {
            type = INSTALL_SCRIPT_OPT;
        } else if (!PL_strcasecmp(buf, "javascriptdir")) {
            type = SCRIPTDIR_OPT;
        } else if (!PL_strcasecmp(buf, "htmldir")) {
            type = JAVASCRIPT_OPT;
            if (jartree) {
                PR_fprintf(errorFD,
                           "warning: directory to be signed specified more than once."
                           " Only last specification will be used.\n");
                warningCount++;
                PR_Free(jartree);
                jartree = NULL;
            }
            jartree = PL_strdup(equals);
        } else if (!PL_strcasecmp(buf, "certname")) {
            type = CERTNAME_OPT;
        } else if (!PL_strcasecmp(buf, "signdir")) {
            type = SIGNDIR_OPT;
        } else if (!PL_strcasecmp(buf, "list")) {
            type = LIST_OBJSIGN_CERTS_OPT;
        } else if (!PL_strcasecmp(buf, "listall")) {
            type = LIST_ALL_CERTS_OPT;
        } else if (!PL_strcasecmp(buf, "metafile")) {
            type = METAFILE_OPT;
        } else if (!PL_strcasecmp(buf, "modules")) {
            type = MODULES_OPT;
        } else if (!PL_strcasecmp(buf, "optimize")) {
            type = OPTIMIZE_OPT;
        } else if (!PL_strcasecmp(buf, "ocsp")) {
            type = ENABLE_OCSP_OPT;
        } else if (!PL_strcasecmp(buf, "password")) {
            type = PASSWORD_OPT;
        } else if (!PL_strcasecmp(buf, "verify")) {
            type = VERIFY_OPT;
        } else if (!PL_strcasecmp(buf, "who")) {
            type = WHO_OPT;
        } else if (!PL_strcasecmp(buf, "exclude")) {
            type = EXCLUDE_OPT;
        } else if (!PL_strcasecmp(buf, "notime")) {
            type = NO_TIME_OPT;
        } else if (!PL_strcasecmp(buf, "jarfile")) {
            type = ZIPFILE_OPT;
        } else if (!PL_strcasecmp(buf, "outfile")) {
            type = OUTFILE_OPT;
        } else if (!PL_strcasecmp(buf, "leavearc")) {
            type = LEAVE_ARC_OPT;
        } else if (!PL_strcasecmp(buf, "verbosity")) {
            type = VERBOSITY_OPT;
        } else if (!PL_strcasecmp(buf, "keysize")) {
            type = KEYSIZE_OPT;
        } else if (!PL_strcasecmp(buf, "token")) {
            type = TOKEN_OPT;
        } else if (!PL_strcasecmp(buf, "xpi")) {
            type = XPI_ARC_OPT;
        } else {
            PR_fprintf(errorFD,
                       "warning: unknown attribute \"%s\" in command file, line %d.\n",
                       buf, linenum);
            warningCount++;
            type = UNKNOWN_OPT;
        }

        /* Process the option, whatever it is */
        if (type != UNKNOWN_OPT) {
            if (ProcessOneOpt(type, equals) == -1) {
                goto finish;
            }
        }
    }

    retval = 0;

finish:
    PR_Close(fd);
    return retval;
}
NS_IMETHODIMP nsMsgSaveAsListener::OnDataAvailable(nsIRequest* request, 
                                  nsISupports* aSupport,
                                  nsIInputStream* inStream, 
                                  uint64_t srcOffset,
                                  uint32_t count)
{
  nsresult rv;
  uint64_t available;
  rv = inStream->Available(&available);
  if (!m_writtenData)
  {
    m_writtenData = true;
    rv = SetupMsgWriteStream(m_outputFile, m_addDummyEnvelope);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  bool useCanonicalEnding = false;
  nsCOMPtr <nsIMsgMessageUrl> msgUrl = do_QueryInterface(aSupport);
  if (msgUrl)
    msgUrl->GetCanonicalLineEnding(&useCanonicalEnding);
  
  const char *lineEnding = (useCanonicalEnding) ? CRLF : MSG_LINEBREAK;
  uint32_t lineEndingLength = (useCanonicalEnding) ? 2 : MSG_LINEBREAK_LEN;
  
  uint32_t readCount, maxReadCount = SAVE_BUF_SIZE - m_leftOver;
  uint32_t writeCount;
  char *start, *end, lastCharInPrevBuf = '\0';
  uint32_t linebreak_len = 0;

  while (count > 0)
  {
      if (count < maxReadCount)
          maxReadCount = count;
      rv = inStream->Read(m_dataBuffer + m_leftOver,
                          maxReadCount,
                          &readCount);
      if (NS_FAILED(rv)) return rv;

      m_leftOver += readCount;
      m_dataBuffer[m_leftOver] = '\0';

      start = m_dataBuffer;
      // make sure we don't insert another LF, accidentally, by ignoring
      // second half of CRLF spanning blocks.
      if (lastCharInPrevBuf == '\r' && *start == '\n')
        start++;

      end = PL_strchr(start, '\r');
      if (!end)
          end = PL_strchr(start, '\n');
      else if (*(end+1) == '\n' && linebreak_len == 0)
          linebreak_len = 2;

      if (linebreak_len == 0) // not initialize yet
          linebreak_len = 1;

      count -= readCount;
      maxReadCount = SAVE_BUF_SIZE - m_leftOver;

      if (!end && count > maxReadCount)
          // must be a very very long line; sorry cannot handle it
          return NS_ERROR_FAILURE;

      while (start && end)
      {
          if (m_outputStream &&
              PL_strncasecmp(start, "X-Mozilla-Status:", 17) &&
              PL_strncasecmp(start, "X-Mozilla-Status2:", 18) &&
              PL_strncmp(start, "From - ", 7))
          {
              rv = m_outputStream->Write(start, end-start, &writeCount);
              nsresult tmp = m_outputStream->Write(lineEnding, lineEndingLength, &writeCount);
              if (NS_FAILED(tmp)) {
                rv = tmp;
              }
          }
          start = end+linebreak_len;
          if (start >= m_dataBuffer + m_leftOver)
          {
              maxReadCount = SAVE_BUF_SIZE;
              m_leftOver = 0;
              break;
          }
          end = PL_strchr(start, '\r');
          if (!end)
              end = PL_strchr(start, '\n');
          if (start && !end)
          {
              m_leftOver -= (start - m_dataBuffer);
              memcpy(m_dataBuffer, start,
                            m_leftOver+1); // including null
              maxReadCount = SAVE_BUF_SIZE - m_leftOver;
          }
      }
      if (NS_FAILED(rv)) return rv;
      if (end)
          lastCharInPrevBuf = *end;
  }
  return rv;
  
  //  rv = m_outputStream->WriteFrom(inStream, std::min(available, count), &bytesWritten);
}
static void LoadExtraSharedLibs()
{
    // check out if user's prefs.js has libs name
    nsresult res;
    nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &res));
    if (NS_SUCCEEDED(res) && (prefs != nsnull)) {
        char *sonameList = NULL;
        PRBool prefSonameListIsSet = PR_TRUE;
        res = prefs->GetCharPref(PREF_PLUGINS_SONAME, &sonameList);
        if (!sonameList) {
            // pref is not set, lets use hardcoded list
            prefSonameListIsSet = PR_FALSE;
            sonameList = PL_strdup(DEFAULT_EXTRA_LIBS_LIST);
        }
        if (sonameList) {
            char *arrayOfLibs[PLUGIN_MAX_NUMBER_OF_EXTRA_LIBS] = {0};
            int numOfLibs = 0;
            char *nextToken;
            char *p = nsCRT::strtok(sonameList,":",&nextToken);
            if (p) {
                while (p && numOfLibs < PLUGIN_MAX_NUMBER_OF_EXTRA_LIBS) {
                    arrayOfLibs[numOfLibs++] = p;
                    p = nsCRT::strtok(nextToken,":",&nextToken);
                }
            } else // there is just one lib
                arrayOfLibs[numOfLibs++] = sonameList;

            char sonameListToSave[PLUGIN_MAX_LEN_OF_TMP_ARR] = "";
            for (int i=0; i<numOfLibs; i++) {
                // trim out head/tail white spaces (just in case)
                PRBool head = PR_TRUE;
                p = arrayOfLibs[i];
                while (*p) {
                    if (*p == ' ' || *p == '\t') {
                        if (head) {
                            arrayOfLibs[i] = ++p;
                        } else {
                            *p = 0;
                        }
                    } else {
                        head = PR_FALSE;
                        p++;
                    }
                }
                if (!arrayOfLibs[i][0]) {
                    continue; // null string
                }
                PRBool tryToGetSoname = PR_TRUE;
                if (PL_strchr(arrayOfLibs[i], '/')) {
                    //assuming it's real name, try to stat it
                    struct stat st;
                    if (stat((const char*) arrayOfLibs[i], &st)) {
                        //get just a file name
                        arrayOfLibs[i] = PL_strrchr(arrayOfLibs[i], '/') + 1;
                    } else
                        tryToGetSoname = PR_FALSE;
                }
                char *soname = NULL;
                if (LoadExtraSharedLib(arrayOfLibs[i], &soname, tryToGetSoname)) {
                    //construct soname's list to save in prefs
                    p = soname ? soname : arrayOfLibs[i];
                    int n = PLUGIN_MAX_LEN_OF_TMP_ARR -
                        (PL_strlen(sonameListToSave) + PL_strlen(p));
                    if (n > 0) {
                        PL_strcat(sonameListToSave, p);
                        PL_strcat(sonameListToSave,":");
                    }
                    if (soname) {
                        PL_strfree(soname); // it's from strdup
                    }
                    if (numOfLibs > 1)
                        arrayOfLibs[i][PL_strlen(arrayOfLibs[i])] = ':'; //restore ":" in sonameList
                }
            }

            // Check whether sonameListToSave is a empty String, Bug: 329205
            if (sonameListToSave[0]) 
                for (p = &sonameListToSave[PL_strlen(sonameListToSave) - 1]; *p == ':'; p--)
                    *p = 0; //delete tail ":" delimiters

            if (!prefSonameListIsSet || PL_strcmp(sonameList, sonameListToSave)) {
                // if user specified some bogus soname I overwrite it here,
                // otherwise it'll decrease performance by calling popen() in SearchForSoname
                // every time for each bogus name
                prefs->SetCharPref(PREF_PLUGINS_SONAME, (const char *)sonameListToSave);
            }
            PL_strfree(sonameList);
        }
    }
}
NS_IMETHODIMP nsMsgSaveAsListener::OnDataAvailable(nsIRequest* request, 
                                  nsISupports* aSupport,
                                  nsIInputStream* inStream, 
                                  PRUint32 srcOffset,
                                  PRUint32 count)
{
  nsresult rv;
  PRUint32 available;
  rv = inStream->Available(&available);
  if (!m_writtenData)
  {
    m_writtenData = PR_TRUE;
    rv = SetupMsgWriteStream(m_outputFile, m_addDummyEnvelope);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  PRBool useCanonicalEnding = PR_FALSE;
  nsCOMPtr <nsIMsgMessageUrl> msgUrl = do_QueryInterface(aSupport);
  if (msgUrl)
    msgUrl->GetCanonicalLineEnding(&useCanonicalEnding);
  
  const char *lineEnding = (useCanonicalEnding) ? CRLF : MSG_LINEBREAK;
  PRUint32 lineEndingLength = (useCanonicalEnding) ? 2 : MSG_LINEBREAK_LEN;
  
  PRUint32 readCount, maxReadCount = SAVE_BUF_SIZE - m_leftOver;
  PRUint32 writeCount;
  char *start, *end;
  PRUint32 linebreak_len = 0;

  while (count > 0)
  {
      if (count < maxReadCount)
          maxReadCount = count;
      rv = inStream->Read(m_dataBuffer + m_leftOver,
                          maxReadCount,
                          &readCount);
      if (NS_FAILED(rv)) return rv;

      m_leftOver += readCount;
      m_dataBuffer[m_leftOver] = '\0';

      start = m_dataBuffer;
      end = PL_strchr(start, '\r');
      if (!end)
          end = PL_strchr(start, '\n');
      else if (*(end+1) == '\n' && linebreak_len == 0)
          linebreak_len = 2;

      if (linebreak_len == 0) // not initialize yet
          linebreak_len = 1;

      count -= readCount;
      maxReadCount = SAVE_BUF_SIZE - m_leftOver;

      if (!end && count > maxReadCount)
          // must be a very very long line; sorry cannot handle it
          return NS_ERROR_FAILURE;

      while (start && end)
      {
          if (PL_strncasecmp(start, "X-Mozilla-Status:", 17) &&
              PL_strncasecmp(start, "X-Mozilla-Status2:", 18) &&
              PL_strncmp(start, "From - ", 7))
          {
              rv = m_outputStream->Write(start, end-start, &writeCount);
              rv = m_outputStream->Write(lineEnding, lineEndingLength, &writeCount);
          }
          start = end+linebreak_len;
          if (start >= m_dataBuffer + m_leftOver)
          {
              maxReadCount = SAVE_BUF_SIZE;
              m_leftOver = 0;
              break;
          }
          end = PL_strchr(start, '\r');
          if (!end)
              end = PL_strchr(start, '\n');
          if (start && !end)
          {
              m_leftOver -= (start - m_dataBuffer);
              memcpy(m_dataBuffer, start,
                            m_leftOver+1); // including null
              maxReadCount = SAVE_BUF_SIZE - m_leftOver;
          }
      }
      if (NS_FAILED(rv)) return rv;
  }
  return rv;
  
  //  rv = m_outputStream->WriteFrom(inStream, PR_MIN(available, count), &bytesWritten);
}
Exemple #22
0
nsresult nsAbLDIFService::str_parse_line(char *line, char **type, char **value, int *vlen) const
{
  char    *p, *s, *d, *byte, *stop;
  char    nib;
  int    i, b64;

  /* skip any leading space */
  while ( isspace( *line ) ) {
    line++;
  }
  *type = line;

  for ( s = line; *s && *s != ':'; s++ )
    ;    /* NULL */
  if ( *s == '\0' ) {
    return NS_ERROR_FAILURE;
  }

  /* trim any space between type and : */
  for ( p = s - 1; p > line && isspace( *p ); p-- ) {
    *p = '\0';
  }
  *s++ = '\0';

  /* check for double : - indicates base 64 encoded value */
  if ( *s == ':' ) {
    s++;
    b64 = 1;
  /* single : - normally encoded value */
  } else {
    b64 = 0;
  }

  /* skip space between : and value */
  while ( isspace( *s ) ) {
    s++;
  }

  /* if no value is present, error out */
  if ( *s == '\0' ) {
    return NS_ERROR_FAILURE;
  }

  /* check for continued line markers that should be deleted */
  for ( p = s, d = s; *p; p++ ) {
    if ( *p != CONTINUED_LINE_MARKER )
      *d++ = *p;
  }
  *d = '\0';

  *value = s;
  if ( b64 ) {
    stop = PL_strchr( s, '\0' );
    byte = s;
    for ( p = s, *vlen = 0; p < stop; p += 4, *vlen += 3 ) {
      for ( i = 0; i < 3; i++ ) {
        if ( p[i] != '=' && (p[i] & 0x80 ||
             b642nib[ p[i] & 0x7f ] > 0x3f) ) {
          return NS_ERROR_FAILURE;
        }
      }

      /* first digit */
      nib = b642nib[ p[0] & 0x7f ];
      byte[0] = nib << 2;
      /* second digit */
      nib = b642nib[ p[1] & 0x7f ];
      byte[0] |= nib >> 4;
      byte[1] = (nib & RIGHT4) << 4;
      /* third digit */
      if ( p[2] == '=' ) {
        *vlen += 1;
        break;
      }
      nib = b642nib[ p[2] & 0x7f ];
      byte[1] |= nib >> 2;
      byte[2] = (nib & RIGHT2) << 6;
      /* fourth digit */
      if ( p[3] == '=' ) {
        *vlen += 2;
        break;
      }
      nib = b642nib[ p[3] & 0x7f ];
      byte[2] |= nib;

      byte += 3;
    }
    s[ *vlen ] = '\0';
  } else {
Exemple #23
0
static bool
MimeMultipartRelated_output_child_p(MimeObject *obj, MimeObject* child)
{
  MimeMultipartRelated *relobj = (MimeMultipartRelated *) obj;

  /* rhp - Changed from "if (relobj->head_loaded)" alone to support the
           start parameter
   */
  if (
       (relobj->head_loaded) ||
       (MimeStartParamExists(obj, child) && !MimeThisIsStartPart(obj, child))
     )
  {
    /* This is a child part.  Just remember the mapping between the URL
       it represents and the part-URL to get it back. */

    char* location = MimeHeaders_get(child->headers, HEADER_CONTENT_LOCATION,
                     false, false);
    if (!location) {
      char* tmp = MimeHeaders_get(child->headers, HEADER_CONTENT_ID,
                    false, false);
      if (tmp) {
        char* tmp2 = tmp;
        if (*tmp2 == '<') {
          int length;
          tmp2++;
          length = strlen(tmp2);
          if (length > 0 && tmp2[length - 1] == '>') {
            tmp2[length - 1] = '\0';
          }
        }
        location = PR_smprintf("cid:%s", tmp2);
        PR_Free(tmp);
      }
    }

    if (location) {
      char *absolute;
      char *base_url = MimeHeaders_get(child->headers, HEADER_CONTENT_BASE,
                       false, false);
      absolute = MakeAbsoluteURL(base_url ? base_url : relobj->base_url, location);

      PR_FREEIF(base_url);
      PR_Free(location);
      if (absolute) {
        nsCAutoString partnum;
        nsCAutoString imappartnum;
        partnum.Adopt(mime_part_address(child));
        if (!partnum.IsEmpty()) {
          if (obj->options->missing_parts)
          {
            char * imappart = mime_imap_part_address(child);
            if (imappart)
              imappartnum.Adopt(imappart);
          }

          /*
            AppleDouble part need special care: we need to output only the data fork part of it.
            The problem at this point is that we haven't yet decoded the children of the AppleDouble
            part therfore we will have to hope the datafork is the second one!
          */
          if (mime_typep(child, (MimeObjectClass *) &mimeMultipartAppleDoubleClass))
            partnum.Append(".2");

          char* part;
          if (!imappartnum.IsEmpty())
            part = mime_set_url_imap_part(obj->options->url, imappartnum.get(), partnum.get());
          else
          {
            char *no_part_url = nullptr;
            if (obj->options->part_to_load && obj->options->format_out == nsMimeOutput::nsMimeMessageBodyDisplay)
              no_part_url = mime_get_base_url(obj->options->url);
            if (no_part_url)
            {
              part = mime_set_url_part(no_part_url, partnum.get(), false);
              PR_Free(no_part_url);
            }
            else
              part = mime_set_url_part(obj->options->url, partnum.get(), false);
          }
          if (part)
          {
            char *name = MimeHeaders_get_name(child->headers, child->options);
            // let's stick the filename in the part so save as will work.
            if (name)
            {
              //char *savePart = part;
              //part = PR_smprintf("%s&filename=%s", savePart, name);
              //PR_Free(savePart);
              PR_Free(name);
            }
            char *temp = part;
            /* If there's a space in the url, escape the url.
               (This happens primarily on Windows and Unix.) */
            if (PL_strchr(part, ' ') || PL_strchr(part, '>') || PL_strchr(part, '%'))
              temp = escape_for_mrel_subst(part);
              MimeHashValue * value = new MimeHashValue(child, temp);
              PL_HashTableAdd(relobj->hash, absolute, value);

            /* rhp - If this part ALSO has a Content-ID we need to put that into
                     the hash table and this is what this code does
             */
            {
              char *tloc;
              char *tmp = MimeHeaders_get(child->headers, HEADER_CONTENT_ID, false, false);
              if (tmp)
              {
                char* tmp2 = tmp;
                if (*tmp2 == '<')
                {
                  int length;
                  tmp2++;
                  length = strlen(tmp2);
                  if (length > 0 && tmp2[length - 1] == '>')
                  {
                    tmp2[length - 1] = '\0';
                  }
                }

                tloc = PR_smprintf("cid:%s", tmp2);
                PR_Free(tmp);
                if (tloc)
                {
                  MimeHashValue *value;
                  value = (MimeHashValue*)PL_HashTableLookup(relobj->hash, tloc);

                  if (!value)
                  {
                    value = new MimeHashValue(child, temp);
                    PL_HashTableAdd(relobj->hash, tloc, value);
                  }
                  else
                    PR_smprintf_free(tloc);
                }
              }
            }
            /*  rhp - End of putting more stuff into the hash table */

              /* it's possible that temp pointer is the same than the part pointer,
                 therefore be carefull to not freeing twice the same pointer */
              if (temp && temp != part)
                PR_Free(temp);
              PR_Free(part);
            }
          }
        }
      }
  } else {
    /* Ah-hah!  We're the head object.  */
    char* base_url;
    relobj->head_loaded = true;
    relobj->headobj = child;
    relobj->buffered_hdrs = MimeHeaders_copy(child->headers);
    base_url = MimeHeaders_get(child->headers, HEADER_CONTENT_BASE,
                   false, false);
    /* rhp: need this for supporting Content-Location */
    if (!base_url)
    {
      base_url = MimeHeaders_get(child->headers, HEADER_CONTENT_LOCATION, false, false);
    }
    /* rhp: need this for supporting Content-Location */

    if (base_url) {
      /* If the head object has a base_url associated with it, use
         that instead of any base_url that may have been associated
         with the multipart/related. */
      PR_FREEIF(relobj->base_url);
      relobj->base_url = base_url;
    }
  }
  if (obj->options && !obj->options->write_html_p
#ifdef MIME_DRAFTS
    && !obj->options->decompose_file_p
#endif /* MIME_DRAFTS */
    )
    {
    return true;
    }

  return false;      /* Don't actually parse this child; we'll handle
                 all that at eof time. */
}
Exemple #24
0
// parse condition like "(subject, contains, fred) AND (body, isn't, "foo)")"
// values with close parens will be quoted.
// what about values with close parens and quotes? e.g., (body, isn't, "foo")")
// I guess interior quotes will need to be escaped - ("foo\")")
// which will get written out as (\"foo\\")\") and read in as ("foo\")"
// ALL means match all messages.
NS_IMETHODIMP nsMsgFilterList::ParseCondition(nsIMsgFilter *aFilter, const char *aCondition)
{
  NS_ENSURE_ARG_POINTER(aFilter);

  bool    done = false;
  nsresult  err = NS_OK;
  const char *curPtr = aCondition;
  if (!strcmp(aCondition, "ALL"))
  {
    nsMsgSearchTerm *newTerm = new nsMsgSearchTerm;

    if (newTerm)
    {
      newTerm->m_matchAll = true;
      aFilter->AppendTerm(newTerm);
    }
    return (newTerm) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
  }

  while (!done)
  {
    // insert code to save the boolean operator if there is one for this search term....
    const char *openParen = PL_strchr(curPtr, '(');
    const char *orTermPos = PL_strchr(curPtr, 'O');    // determine if an "OR" appears b4 the openParen...
    bool ANDTerm = true;
    if (orTermPos && orTermPos < openParen) // make sure OR term falls before the '('
      ANDTerm = false;

    char *termDup = nullptr;
    if (openParen)
    {
      bool foundEndTerm = false;
      bool inQuote = false;
      for (curPtr = openParen +1; *curPtr; curPtr++)
      {
        if (*curPtr == '\\' && *(curPtr + 1) == '"')
          curPtr++;
        else if (*curPtr == ')' && !inQuote)
        {
          foundEndTerm = true;
          break;
        }
        else if (*curPtr == '"')
          inQuote = !inQuote;
      }
      if (foundEndTerm)
      {
        int termLen = curPtr - openParen - 1;
        termDup = (char *) PR_Malloc(termLen + 1);
        if (termDup)
        {
          PL_strncpy(termDup, openParen + 1, termLen + 1);
          termDup[termLen] = '\0';
        }
        else
        {
          err = NS_ERROR_OUT_OF_MEMORY;
          break;
        }
      }
    }
    else
      break;
    if (termDup)
    {
      nsMsgSearchTerm  *newTerm = new nsMsgSearchTerm;

      if (newTerm)
      {
        /* Invert nsMsgSearchTerm::EscapeQuotesInStr() */
        for (char *to = termDup, *from = termDup;;)
        {
          if (*from == '\\' && from[1] == '"') from++;
          if (!(*to++ = *from++)) break;
        }
        newTerm->m_booleanOp = (ANDTerm) ? nsMsgSearchBooleanOp::BooleanAND
                                         : nsMsgSearchBooleanOp::BooleanOR;

        err = newTerm->DeStreamNew(termDup, PL_strlen(termDup));
        NS_ENSURE_SUCCESS(err, err);
        aFilter->AppendTerm(newTerm);
      }
      PR_FREEIF(termDup);
    }
    else
      break;
  }
  return err;
}
// |decode_mime_part2_str| taken from comi18n.c
// Decode RFC2047-encoded words in the input and convert the result to UTF-8.
// If aOverrideCharset is true, charset in RFC2047-encoded words is 
// ignored and aDefaultCharset is assumed, instead. aDefaultCharset
// is also used to convert raw octets (without RFC 2047 encoding) to UTF-8.
//static
nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset, 
                          PRBool aOverrideCharset, nsACString &aResult)
{
  const char *p, *q, *r;
  char *decodedText;
  const char *begin; // tracking pointer for where we are in the input buffer
  PRInt32 isLastEncodedWord = 0;
  const char *charsetStart, *charsetEnd;
  char charset[80];

  // initialize charset name to an empty string
  charset[0] = '\0';

  begin = aHeader;

  // To avoid buffer realloc, if possible, set capacity in advance. No 
  // matter what,  more than 3x expansion can never happen for all charsets
  // supported by Mozilla. SCSU/BCSU with the sliding window set to a
  // non-BMP block may be exceptions, but Mozilla does not support them. 
  // Neither any known mail/news program use them. Even if there's, we're
  // safe because we don't use a raw *char any more.
  aResult.SetCapacity(3 * strlen(aHeader));

  while ((p = PL_strstr(begin, "=?")) != 0) {
    if (isLastEncodedWord) {
      // See if it's all whitespace.
      for (q = begin; q < p; ++q) {
        if (!PL_strchr(" \t\r\n", *q)) break;
      }
    }

    if (!isLastEncodedWord || q < p) {
      // copy the part before the encoded-word
      CopyRawHeader(begin, p - begin, aDefaultCharset, aResult);
      begin = p;
    }

    p += 2;

    // Get charset info
    charsetStart = p;
    charsetEnd = 0;
    for (q = p; *q != '?'; q++) {
      if (*q <= ' ' || PL_strchr(especials, *q)) {
        goto badsyntax;
      }

      // RFC 2231 section 5
      if (!charsetEnd && *q == '*') {
        charsetEnd = q; 
      }
    }
    if (!charsetEnd) {
      charsetEnd = q;
    }

    // Check for too-long charset name
    if (PRUint32(charsetEnd - charsetStart) >= sizeof(charset)) 
      goto badsyntax;
    
    memcpy(charset, charsetStart, charsetEnd - charsetStart);
    charset[charsetEnd - charsetStart] = 0;

    q++;
    if (*q != 'Q' && *q != 'q' && *q != 'B' && *q != 'b')
      goto badsyntax;

    if (q[1] != '?')
      goto badsyntax;

    r = q;
    for (r = q + 2; *r != '?'; r++) {
      if (*r < ' ') goto badsyntax;
    }
    if (r[1] != '=')
        goto badsyntax;
    else if (r == q + 2) {
        // it's empty, skip
        begin = r + 2;
        isLastEncodedWord = 1;
        continue;
    }

    if(*q == 'Q' || *q == 'q')
      decodedText = DecodeQ(q + 2, r - (q + 2));
    else {
      // bug 227290. ignore an extraneous '=' at the end.
      // (# of characters in B-encoded part has to be a multiple of 4)
      PRInt32 n = r - (q + 2);
      n -= (n % 4 == 1 && !PL_strncmp(r - 3, "===", 3)) ? 1 : 0;
      decodedText = PL_Base64Decode(q + 2, n, nsnull);
    }

    if (decodedText == nsnull)
      goto badsyntax;

    // Override charset if requested.  Never override labeled UTF-8.
    // Use default charset instead of UNKNOWN-8BIT
    if ((aOverrideCharset && 0 != nsCRT::strcasecmp(charset, "UTF-8")) ||
        (aDefaultCharset && 0 == nsCRT::strcasecmp(charset, "UNKNOWN-8BIT"))) {
      PL_strncpy(charset, aDefaultCharset, sizeof(charset) - 1);
      charset[sizeof(charset) - 1] = '\0';
    }

    {
      nsCOMPtr<nsIUTF8ConverterService> 
        cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID));
      nsCAutoString utf8Text;
      // skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset.
      if (cvtUTF8 &&
          NS_SUCCEEDED(
            cvtUTF8->ConvertStringToUTF8(nsDependentCString(decodedText),
            charset, IS_7BIT_NON_ASCII_CHARSET(charset), utf8Text))) {
        aResult.Append(utf8Text);
      } else {
        aResult.Append(REPLACEMENT_CHAR);
      }
    }
    PR_Free(decodedText);
    begin = r + 2;
    isLastEncodedWord = 1;
    continue;

  badsyntax:
    // copy the part before the encoded-word
    aResult.Append(begin, p - begin);
    begin = p;
    isLastEncodedWord = 0;
  }

  // put the tail back
  CopyRawHeader(begin, strlen(begin), aDefaultCharset, aResult);

  nsCAutoString tempStr(aResult);
  tempStr.ReplaceChar('\t', ' ');
  aResult = tempStr;

  return NS_OK;
}
Exemple #26
0
// Simple parser to parse META charset. 
// It only supports the case when the description is within one line. 
const char * 
nsMsgI18NParseMetaCharset(nsIFile* file) 
{ 
  static char charset[nsIMimeConverter::MAX_CHARSET_NAME_LENGTH+1];

  *charset = '\0'; 

  bool isDirectory = false;
  file->IsDirectory(&isDirectory);
  if (isDirectory) {
    NS_ERROR("file is a directory");
    return charset; 
  }

  nsresult rv;
  nsCOMPtr <nsIFileInputStream> fileStream = do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, charset);
  
  rv = fileStream->Init(file, PR_RDONLY, 0664, false);
  nsCOMPtr <nsILineInputStream> lineStream = do_QueryInterface(fileStream, &rv);

  nsCString curLine;
  bool more = true;
  while (NS_SUCCEEDED(rv) && more) { 
    rv = lineStream->ReadLine(curLine, &more); 
    if (curLine.IsEmpty()) 
      continue; 

    ToUpperCase(curLine);

    if (curLine.Find("/HEAD") != -1) 
      break; 

    if (curLine.Find("META") != -1 && 
       curLine.Find("HTTP-EQUIV") != -1 && 
        curLine.Find("CONTENT-TYPE") != -1 && 
       curLine.Find("CHARSET") != -1) { 
      char *cp = (char *) PL_strchr(PL_strstr(curLine.get(), "CHARSET"), '=');
      char *token = nullptr;
      if (cp)
      {
        char *newStr = cp + 1;
        token = NS_strtok(" \"\'", &newStr);
      }
      if (token) { 
        PL_strncpy(charset, token, sizeof(charset));
        charset[sizeof(charset)-1] = '\0';

        // this function cannot parse a file if it is really
        // encoded by one of the following charsets
        // so we can say that the charset label must be incorrect for
        // the .html if we actually see those charsets parsed
        // and we should ignore them
        if (!PL_strncasecmp("UTF-16", charset, sizeof("UTF-16")-1) || 
            !PL_strncasecmp("UTF-32", charset, sizeof("UTF-32")-1))
          charset[0] = '\0';

        break;
      } 
    } 
  } 

  return charset; 
} 
// moved almost verbatim from mimehdrs.cpp
// char *
// MimeHeaders_get_parameter (const char *header_value, const char *parm_name,
//                            char **charset, char **language)
//
// The format of these header lines  is
// <token> [ ';' <token> '=' <token-or-quoted-string> ]*
NS_IMETHODIMP 
nsMIMEHeaderParamImpl::GetParameterInternal(const char *aHeaderValue, 
                                            const char *aParamName,
                                            char **aCharset,
                                            char **aLang,
                                            char **aResult)
{
  if (!aHeaderValue ||  !*aHeaderValue || !aResult)
    return NS_ERROR_INVALID_ARG;

  *aResult = nsnull;

  if (aCharset) *aCharset = nsnull;
  if (aLang) *aLang = nsnull;

  const char *str = aHeaderValue;

  // skip leading white space.
  for (; *str &&  nsCRT::IsAsciiSpace(*str); ++str)
    ;
  const char *start = str;
  
  // aParamName is empty. return the first (possibly) _unnamed_ 'parameter'
  // For instance, return 'inline' in the following case:
  // Content-Disposition: inline; filename=.....
  if (!aParamName || !*aParamName) 
    {
      for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str)
        ;
      if (str == start)
        return NS_ERROR_UNEXPECTED;
      *aResult = (char *) nsMemory::Clone(start, (str - start) + 1);
      NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
      (*aResult)[str - start] = '\0';  // null-terminate
      return NS_OK;
    }

  /* Skip forward to first ';' */
  for (; *str && *str != ';' && *str != ','; ++str)
    ;
  if (*str)
    str++;
  /* Skip over following whitespace */
  for (; *str && nsCRT::IsAsciiSpace(*str); ++str)
    ;

  // Some broken http servers just specify parameters
  // like 'filename' without specifying disposition
  // method. Rewind to the first non-white-space
  // character.
  
  if (!*str)
    str = start;

  // RFC2231 - The legitimate parm format can be:
  // A. title=ThisIsTitle 
  // B. title*=us-ascii'en-us'This%20is%20wierd.
  // C. title*0*=us-ascii'en'This%20is%20wierd.%20We
  //    title*1*=have%20to%20support%20this.
  //    title*2="Else..."
  // D. title*0="Hey, what you think you are doing?"
  //    title*1="There is no charset and lang info."

  PRInt32 paramLen = strlen(aParamName);

  while (*str) {
    const char *tokenStart = str;
    const char *tokenEnd = 0;
    const char *valueStart = str;
    const char *valueEnd = 0;

    NS_ASSERTION(!nsCRT::IsAsciiSpace(*str), "should be after whitespace.");

    // Skip forward to the end of this token. 
    for (; *str && !nsCRT::IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++)
      ;
    tokenEnd = str;

    // Skip over whitespace, '=', and whitespace
    while (nsCRT::IsAsciiSpace(*str)) ++str;
    if (*str == '=') ++str;
    while (nsCRT::IsAsciiSpace(*str)) ++str;

    if (*str != '"')
    {
      // The value is a token, not a quoted string.
      valueStart = str;
      for (valueEnd = str;
           *valueEnd && !nsCRT::IsAsciiSpace (*valueEnd) && *valueEnd != ';';
           valueEnd++)
        ;
      str = valueEnd;
    }
    else
    {
      // The value is a quoted string. 
      ++str;
      valueStart = str;
      for (valueEnd = str; *valueEnd; ++valueEnd)
      {
        if (*valueEnd == '\\')
          ++valueEnd;
        else if (*valueEnd == '"')
          break;
      }
      str = valueEnd + 1;
    }

    // See if this is the simplest case (case A above),
    // a 'single' line value with no charset and lang.
    // If so, copy it and return.
    if (tokenEnd - tokenStart == paramLen &&
        !nsCRT::strncasecmp(tokenStart, aParamName, paramLen))
    {
      // if the parameter spans across multiple lines we have to strip out the
      //     line continuation -- jht 4/29/98 
      nsCAutoString tempStr(valueStart, valueEnd - valueStart);
      tempStr.StripChars("\r\n");
      *aResult = ToNewCString(tempStr);
      NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
      return NS_OK;
    }
    // case B, C, and D
    else if (tokenEnd - tokenStart > paramLen &&
             !nsCRT::strncasecmp(tokenStart, aParamName, paramLen) &&
             *(tokenStart + paramLen) == '*')
    {
      const char *cp = tokenStart + paramLen + 1; // 1st char pass '*'
      PRBool needUnescape = *(tokenEnd - 1) == '*';
      // the 1st line of a multi-line parameter or a single line  that needs 
      // unescaping. ( title*0*=  or  title*= )
      if ((*cp == '0' && needUnescape) || (tokenEnd - tokenStart == paramLen + 1))
      {
        // look for single quotation mark(')
        const char *sQuote1 = PL_strchr(valueStart, 0x27);
        const char *sQuote2 = (char *) (sQuote1 ? PL_strchr(sQuote1 + 1, 0x27) : nsnull);

        // Two single quotation marks must be present even in
        // absence of charset and lang. 
        if (!sQuote1 || !sQuote2)
          NS_WARNING("Mandatory two single quotes are missing in header parameter\n");
        if (aCharset && sQuote1 > valueStart && sQuote1 < valueEnd)
        {
          *aCharset = (char *) nsMemory::Clone(valueStart, sQuote1 - valueStart + 1);
          if (*aCharset) 
            *(*aCharset + (sQuote1 - valueStart)) = 0;
        }
        if (aLang && sQuote1 && sQuote2 && sQuote2 > sQuote1 + 1 &&
            sQuote2 < valueEnd)
        {
          *aLang = (char *) nsMemory::Clone(sQuote1 + 1, sQuote2 - (sQuote1 + 1) + 1);
          if (*aLang) 
            *(*aLang + (sQuote2 - (sQuote1 + 1))) = 0;
        }

        // Be generous and handle gracefully when required 
        // single quotes are absent.
        if (sQuote1)
        {
          if(!sQuote2)
            sQuote2 = sQuote1;
        }
        else
          sQuote2 = valueStart - 1;

        if (sQuote2 && sQuote2 + 1 < valueEnd)
        {
          NS_ASSERTION(!*aResult, "This is the 1st line. result buffer should be null.");
          *aResult = (char *) nsMemory::Alloc(valueEnd - (sQuote2 + 1) + 1);
          if (*aResult)
          {
            memcpy(*aResult, sQuote2 + 1, valueEnd - (sQuote2 + 1));
            *(*aResult + (valueEnd - (sQuote2 + 1))) = 0;
            if (needUnescape)
            {
              nsUnescape(*aResult);
              if (tokenEnd - tokenStart == paramLen + 1)
                // we're done; this is case B 
                return NS_OK; 
            }
          }
        }
      }  // end of if-block :  title*0*=  or  title*= 
      // a line of multiline param with no need for unescaping : title*[0-9]=
      // or 2nd or later lines of a multiline param : title*[1-9]*= 
      else if (nsCRT::IsAsciiDigit(PRUnichar(*cp)))
      {
        PRInt32 len = 0;
        if (*aResult) // 2nd or later lines of multiline parameter
        {
          len = strlen(*aResult);
          char *ns = (char *) nsMemory::Realloc(*aResult, len + (valueEnd - valueStart) + 1);
          if (!ns)
          {
            nsMemory::Free(*aResult);
          }
          *aResult = ns;
        }
        else if (*cp == '0') // must be; 1st line :  title*0=
        {
          *aResult = (char *) nsMemory::Alloc(valueEnd - valueStart + 1);
        }
        // else {} something is really wrong; out of memory
        if (*aResult)
        {
          // append a partial value
          memcpy(*aResult + len, valueStart, valueEnd - valueStart);
          *(*aResult + len + (valueEnd - valueStart)) = 0;
          if (needUnescape)
            nsUnescape(*aResult + len);
        }
        else 
          return NS_ERROR_OUT_OF_MEMORY;
      } // end of if-block :  title*[0-9]= or title*[1-9]*=
    }

    // str now points after the end of the value.
    //   skip over whitespace, ';', whitespace.
      
    while (nsCRT::IsAsciiSpace(*str)) ++str;
    if (*str == ';') ++str;
    while (nsCRT::IsAsciiSpace(*str)) ++str;
  }

  if (*aResult) 
    return NS_OK;
  else
    return NS_ERROR_INVALID_ARG; // aParameter not found !!
}
Exemple #28
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;
}
Exemple #29
0
/* caller is responsible to release "valuearray" */
int
get_values_from_string(const char *string, char *type, char ***valuearray)
{
    int rc = -1;
    size_t typelen = 0;
    char *ptr = NULL;
    char *copy = NULL;
    char *tmpptr = NULL;
    char *startptr = NULL;
    struct berval tmptype = {0, NULL};
    struct berval bvvalue = {0, NULL};
    int freeval = 0;
    char *value = NULL;
    int idx = 0;
#define get_values_INITIALMAXCNT 1
    int maxcnt = get_values_INITIALMAXCNT;

    if (NULL == string || NULL == type || NULL == valuearray) {
        return rc;
    }
    *valuearray = NULL;
    tmpptr = (char *)string;
    ptr = PL_strcasestr(tmpptr, type);
    if (NULL == ptr) {
        return rc;
    }

    typelen = strlen(type);
    startptr = tmpptr;
    while (NULL != (ptr = ldif_getline(&tmpptr))) {
        if ((0 != PL_strncasecmp(ptr, type, typelen)) ||
            (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) {
            /* did not match */
            ldif_getline_fixline(startptr, tmpptr);
            startptr = tmpptr;
            continue;
        }
        /* matched */
        copy = slapi_ch_strdup(ptr);
        ldif_getline_fixline(startptr, tmpptr);
        startptr = tmpptr;
        rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval);
        if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
            continue;
        }
        if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) {
            char *p = PL_strchr(tmptype.bv_val, ';'); /* subtype ? */
            if (p) {
                if (0 != strncasecmp(type, tmptype.bv_val, p - tmptype.bv_val)) {
                    slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
                                    "type does not match: %s != %s\n", 
                                    type, tmptype.bv_val);
                    if (freeval) {
                        slapi_ch_free_string(&bvvalue.bv_val);
                    }
                    goto bail;
                }
            } else {
                slapi_log_error(SLAPI_LOG_FATAL, "get_values_from_string", 
                                "type does not match: %s != %s\n", 
                                type, tmptype.bv_val);
                if (freeval) {
                    slapi_ch_free_string(&bvvalue.bv_val);
                }
                goto bail;
            }
        }
        if (freeval) {
            value = bvvalue.bv_val; /* just hand off memory */
            bvvalue.bv_val = NULL;
        } else { /* copy */
            value = (char *)slapi_ch_malloc(bvvalue.bv_len + 1);
            memcpy(value, bvvalue.bv_val, bvvalue.bv_len);
            *(value + bvvalue.bv_len) = '\0';
        }
        if ((get_values_INITIALMAXCNT == maxcnt) || !valuearray || 
            (idx + 1 >= maxcnt)) {
            maxcnt *= 2;
            *valuearray = (char **)slapi_ch_realloc((char *)*valuearray, 
                                                    sizeof(char *) * maxcnt);
        }
        (*valuearray)[idx++] = value;
        (*valuearray)[idx] = NULL;
        slapi_ch_free_string(&copy);
    }
bail:
    slapi_ch_free_string(&copy);
    return rc;
}
char *
nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) {
    char *line = aBuffer;
    char *eol;
    bool cr = false;

    list_state state;
    state.magic = 0;

    // while we have new lines, parse 'em into application/http-index-format.
    while ( line && (eol = PL_strchr(line, nsCRT::LF)) ) {
        // yank any carriage returns too.
        if (eol > line && *(eol-1) == nsCRT::CR) {
            eol--;
            *eol = '\0';
            cr = true;
        } else {
            *eol = '\0';
            cr = false;
        }

        list_result result;

        int type = ParseFTPList(line, &state, &result );

        // if it is other than a directory, file, or link -OR- if it is a 
        // directory named . or .., skip over this line.
        if ((type != 'd' && type != 'f' && type != 'l') || 
            (result.fe_type == 'd' && result.fe_fname[0] == '.' &&
            (result.fe_fnlen == 1 || (result.fe_fnlen == 2 &&  result.fe_fname[1] == '.'))) )
        {
            if (cr)
                line = eol+2;
            else
                line = eol+1;
            
            continue;
        }

        // blast the index entry into the indexFormat buffer as a 201: line.
        aString.AppendLiteral("201: ");
        // FILENAME

        // parsers for styles 'U' and 'W' handle sequence " -> " themself
	if (state.lstyle != 'U' && state.lstyle != 'W') {
            const char* offset = strstr(result.fe_fname, " -> ");
            if (offset) {
                result.fe_fnlen = offset - result.fe_fname;
            }
        }

        nsCAutoString buf;
        aString.Append('\"');
        aString.Append(NS_EscapeURL(Substring(result.fe_fname, 
                                              result.fe_fname+result.fe_fnlen),
                                    esc_Minimal|esc_OnlyASCII|esc_Forced,buf));
        aString.AppendLiteral("\" ");
 
        // CONTENT LENGTH
        
        if (type != 'd') 
        {
            for (int i = 0; i < int(sizeof(result.fe_size)); ++i)
            {
                if (result.fe_size[i] != '\0')
                    aString.Append((const char*)&result.fe_size[i], 1);
            }
            
            aString.Append(' ');
        }
        else
            aString.AppendLiteral("0 ");


        // MODIFIED DATE
        char buffer[256] = "";
        // Note: The below is the RFC822/1123 format, as required by
        // the application/http-index-format specs
        // viewers of such a format can then reformat this into the
        // current locale (or anything else they choose)
        PR_FormatTimeUSEnglish(buffer, sizeof(buffer),
                               "%a, %d %b %Y %H:%M:%S", &result.fe_time );

        char *escapedDate = nsEscape(buffer, url_Path);
        aString.Append(escapedDate);
        nsMemory::Free(escapedDate);
        aString.Append(' ');

        // ENTRY TYPE
        if (type == 'd')
            aString.AppendLiteral("DIRECTORY");
        else if (type == 'l')
            aString.AppendLiteral("SYMBOLIC-LINK");
        else
            aString.AppendLiteral("FILE");
        
        aString.Append(' ');

        aString.Append(char(nsCRT::LF)); // complete this line
        // END 201:

        if (cr)
            line = eol+2;
        else
            line = eol+1;
    } // end while(eol)

    return line;
}