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())); }
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(); }
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; }
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; }
/* 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; }
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; }
/********************************************************************* * * 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); }
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 {
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. */ }
// 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; }
// 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 !! }
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; }
/* 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(©); } bail: slapi_ch_free_string(©); 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; }