nsresult nsDataHandler::ParseURI(nsCString& spec, nsCString& contentType, nsCString& contentCharset, bool& isBase64, nsCString& dataBuffer, nsCString& hashRef) { isBase64 = false; // move past "data:" char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:"); if (!buffer) { // malformed uri return NS_ERROR_MALFORMED_URI; } buffer += 5; // First, find the start of the data char *comma = strchr(buffer, ','); char *hash = strchr(buffer, '#'); if (!comma || (hash && hash < comma)) return NS_ERROR_MALFORMED_URI; *comma = '\0'; // determine if the data is base64 encoded. char *base64 = PL_strcasestr(buffer, BASE64_EXTENSION); if (base64) { char *beyond = base64 + strlen(BASE64_EXTENSION); // per the RFC 2397 grammar, "base64" MUST be followed by a comma // previously substituted by '\0', but we also allow it in between // parameters so a subsequent ";" is ok as well (this deals with // *broken* data URIs, see bug 781693 for an example) if (*beyond == '\0' || *beyond == ';') { isBase64 = true; *base64 = '\0'; } } if (comma == buffer) { // nothing but data contentType.AssignLiteral("text/plain"); contentCharset.AssignLiteral("US-ASCII"); } else { // everything else is content type char *semiColon = (char *) strchr(buffer, ';'); if (semiColon) *semiColon = '\0'; if (semiColon == buffer || base64 == buffer) { // there is no content type, but there are other parameters contentType.AssignLiteral("text/plain"); } else { contentType = buffer; ToLowerCase(contentType); } if (semiColon) { char *charset = PL_strcasestr(semiColon + 1, "charset="); if (charset) contentCharset = charset + sizeof("charset=") - 1; *semiColon = ';'; } } *comma = ','; if (isBase64) *base64 = ';'; contentType.StripWhitespace(); contentCharset.StripWhitespace(); // Split encoded data from terminal "#ref" (if present) char *data = comma + 1; if (!hash) { dataBuffer.Assign(data); hashRef.Truncate(); } else { dataBuffer.Assign(data, hash - data); hashRef.Assign(hash); } return NS_OK; }
nsHtml5Parser::GetCommand(nsCString& aCommand) { aCommand.Assign("view"); }
// Determine if this line meets Eudora standards for a separator line // This logic is based on Eudora 1.3.1's strict requirements for what // makes a valid separator line. This may need to be relaxed for newer // versions of Eudora. // A sample from line: // From [email protected] Wed Jan 14 12:36:18 1989 PRInt32 nsEudoraMailbox::IsEudoraFromSeparator( const char *pChar, PRInt32 maxLen, nsCString& defaultDate) { if (maxLen < 12) return( -1); PRInt32 len = 0; if ((*pChar != 'F') || (*(pChar + 1) != 'r') || (*(pChar + 2) != 'o') || (*(pChar + 3) != 'm')) return( -1); pChar += 4; len += 4; // According to Eudora the next char MUST be a space, and there can only be 1 space // before the return mail address. // I'll be nicer and allow any amount of whitespace while (((*pChar == ' ') || (*pChar == '\t')) && (len < maxLen)) { pChar++; len++; } if (len == maxLen) return( -1); // Determine the length of the line PRInt32 lineLen = len; const char * pTok = pChar; while ((lineLen < maxLen) && (*pTok != 0x0D) && (*pTok != 0x0A)) { lineLen++; pTok++; } if (len >= lineLen) return( -1); // Eudora allows the return address to be double quoted or not at all.. // I'll allow single or double quote, but other than that, just skip // the return address until you hit a space char (I allow tab as well) char quote = *pChar; if ((quote == '"') || (quote == '\'')) { pChar++; len++; while ((len < lineLen) && (*pChar != quote)) { pChar++; len++; } if (len == lineLen) return( -1); len++; pChar++; } else { while ((len < lineLen) && (*pChar != ' ') && (*pChar != '\t')) { pChar++; len++; } } while (((*pChar == ' ') || (*pChar == '\t')) && (len < lineLen)) { pChar++; len++; } if (len == lineLen) return( -1); // we've passed the address, now check for the remaining data // Now it gets really funky! // In no particular order, with token separators space, tab, comma, newline // a - the phrase "remote from", remote must be first, from is optional. 2 froms or 2 remotes fails // b - one and only one time value xx:xx or xx:xx:xx // c - one and only one day, 1 to 31 // d - one and only one year, 2 digit anything or 4 digit > 1900 // e - one and only one weekday, 3 letter abreviation // f - one and only one month, 3 letter abreviation // 2 allowable "other" tokens // to be valid, day, year, month, & tym must exist and other must be less than 3 int day = 0; int month = 0; int year = 0; int weekDay = 0; int other = 0; int result; char tymStr[9]; // Make it a null terminated string (used in PR_snprintf() call()). PRBool tym = PR_FALSE; PRBool remote = PR_FALSE; PRBool from = PR_FALSE; PRInt32 tokLen; PRInt32 tokStart; PRInt32 num; while ((len < lineLen) && (other < 3)) { pTok = pChar; tokStart = len; while ((len < lineLen) && (*pChar != ' ') && (*pChar != '\t') && (*pChar != ',')) { pChar++; len++; } tokLen = len - tokStart; if (tokLen) { num = AsciiToLong( pTok, tokLen); if ((tokLen == 3) && ((result = IsWeekDayStr( pTok)) != 0)) { if (weekDay) return( -1); weekDay = result; } else if ((tokLen == 3) && ((result = IsMonthStr( pTok)) != 0)) { if (month) return( -1); month = result; } else if ((tokLen == 6) && !PL_strncasecmp( pTok, "remote", 6)) { if (remote || from) return( -1); remote = PR_TRUE; } else if ((tokLen == 4) && !PL_strncasecmp( pTok, "from", 4)) { if (!remote || from) return( -1); from = PR_TRUE; } else if ((tokLen == 4) && ((num > 1900) || !strncmp( pTok, "0000", 4))) { if (year) return( -1); year = (int)num; if (!year) year = 1900; } else if (!year && day && (tokLen == 2) && (*(pTok + 1) >= '0') && (*(pTok + 1) <= '9')) { if (num < 65) num += 1900; else num += 2000; year = (int) num; } else if ((tokLen <= 2) && (*pTok >= '0') && (*pTok <= '9')) { day = (int) num; if ((day < 1) || (day > 31)) day = 1; } else if ((tokLen >= 5) && (pTok[2] == ':') && ((tokLen == 5) || ((tokLen == 8) && (pTok[5] == ':')))) { // looks like the tym... for (result = 0; result < (int)tokLen; result++) { if ((result != 2) && (result != 5)) { if ((pTok[result] < '0') || (pTok[result] > '9')) { break; } } } if (result == tokLen) { if (tym) return( -1); tym = PR_TRUE; // for future use, get the time value memcpy( tymStr, pTok, tokLen); if (tokLen == 5) { tymStr[5] = ':'; tymStr[6] = '0'; tymStr[7] = '0'; } tymStr[8] = 0; } else { other++; } } else other++; } // Skip the space chars... while ((len < lineLen) && ((*pChar == ' ') || (*pChar == '\t') || (*pChar == ','))) { pChar++; len++; } } // end while (len < lineLen) token loop // Now let's see what we found on the line if (day && year && month && tym && (other < 3)) { // Now we need to make sure the next line // isn't blank! while (len < lineLen) { len++; pChar++; } if (len == maxLen) return( -1); if (*pChar == 0x0D) { len++; pChar++; if (*pChar == 0x0A) { len++; pChar++; } } else if (*pChar == 0x0A) { len++; pChar++; } else return( -1); if (len >= maxLen) return( -1); while (len < maxLen) { if ((*pChar == 0x0D) || (*pChar == 0x0A)) return( -1); if ((*pChar != ' ') && (*pChar != '\t')) break; pChar++; len++; } // Whew!, the next line isn't blank. // Generate the default date header in case the date header is missing when we // write out headers later. The header looks like "Date: Tue, 5 Feb 2002 23:05:04" char date_header_str[DATE_STR_LEN]; PR_snprintf(date_header_str, DATE_STR_LEN, "Date: %s, %2d %s %4d %s", eudoraWeekDays[weekDay-1], day, eudoraMonths[month-1], year, tymStr); defaultDate.Assign(date_header_str); return( lineLen); } return( -1); }
nsresult nsAboutCacheEntry::Channel::ParseURI(nsIURI *uri, nsACString &storageName, nsILoadContextInfo **loadInfo, nsCString &enahnceID, nsIURI **cacheUri) { // // about:cache-entry?storage=[string]&contenxt=[string]&eid=[string]&uri=[string] // nsresult rv; nsAutoCString path; rv = uri->GetPath(path); if (NS_FAILED(rv)) return rv; nsACString::const_iterator keyBegin, keyEnd, valBegin, begin, end; path.BeginReading(begin); path.EndReading(end); keyBegin = begin; keyEnd = end; if (!FindInReadable(NS_LITERAL_CSTRING("?storage="), keyBegin, keyEnd)) return NS_ERROR_FAILURE; valBegin = keyEnd; // the value of the storage key starts after the key keyBegin = keyEnd; keyEnd = end; if (!FindInReadable(NS_LITERAL_CSTRING("&context="), keyBegin, keyEnd)) return NS_ERROR_FAILURE; storageName.Assign(Substring(valBegin, keyBegin)); valBegin = keyEnd; // the value of the context key starts after the key keyBegin = keyEnd; keyEnd = end; if (!FindInReadable(NS_LITERAL_CSTRING("&eid="), keyBegin, keyEnd)) return NS_ERROR_FAILURE; nsAutoCString contextKey(Substring(valBegin, keyBegin)); valBegin = keyEnd; // the value of the eid key starts after the key keyBegin = keyEnd; keyEnd = end; if (!FindInReadable(NS_LITERAL_CSTRING("&uri="), keyBegin, keyEnd)) return NS_ERROR_FAILURE; enahnceID.Assign(Substring(valBegin, keyBegin)); valBegin = keyEnd; // the value of the uri key starts after the key nsAutoCString uriSpec(Substring(valBegin, end)); // uri is the last one // Uf... parsing done, now get some objects from it... nsCOMPtr<nsILoadContextInfo> info = CacheFileUtils::ParseKey(contextKey); if (!info) return NS_ERROR_FAILURE; info.forget(loadInfo); rv = NS_NewURI(cacheUri, uriSpec); if (NS_FAILED(rv)) return rv; return NS_OK; }
/** * This method applies a sequence of transformations to the line. * * It applies the following sequences in order * * Removes headers if the searcher doesn't want them * (sets m_pastHeaders) * * Determines the current MIME type. * (via SniffPossibleMIMEHeader) * * Strips any HTML if the searcher doesn't want it * * Strips non-text parts * * Decodes any base64 part * (resetting part variables: m_base64part, m_pastHeaders, m_partIsHtml, * m_partIsText) * * @param line (in) the current line * @param length (in) the length of said line * @param eatThisLine (out) whether or not to ignore this line * @param buf (inout) if m_base64part, the current part as needed for * decoding; else, it is treated as an out param (a * redundant version of line). * @return the length of the line after applying transformations */ PRInt32 nsMsgBodyHandler::ApplyTransformations (const nsCString &line, PRInt32 length, bool &eatThisLine, nsCString &buf) { PRInt32 newLength = length; eatThisLine = PR_FALSE; if (!m_pastHeaders) // line is a line from the message headers { if (m_stripHeaders) eatThisLine = PR_TRUE; // We have already grabbed all worthwhile information from the headers, // so there is no need to keep track of the current lines buf.Assign(line); SniffPossibleMIMEHeader(buf); m_pastHeaders = buf.IsEmpty() || buf.First() == '\r' || buf.First() == '\n'; return length; } // Check to see if this is the boundary string if (m_isMultipart && StringBeginsWith(line, boundary)) { if (m_base64part && m_partIsText) { Base64Decode(buf); // Work on the parsed string if (!buf.Length()) { NS_WARNING("Trying to transform an empty buffer"); eatThisLine = PR_TRUE; } else { ApplyTransformations(buf, buf.Length(), eatThisLine, buf); // Avoid spurious failures eatThisLine = PR_FALSE; } } else { buf.Truncate(); eatThisLine = PR_TRUE; // We have no content... } // Reset all assumed headers m_base64part = PR_FALSE; m_pastHeaders = PR_FALSE; m_partIsHtml = PR_FALSE; m_partIsText = PR_TRUE; return buf.Length(); } if (!m_partIsText) { // Ignore non-text parts buf.Truncate(); eatThisLine = PR_TRUE; return 0; } if (m_base64part) { // We need to keep track of all lines to parse base64encoded... buf.Append(line.get()); eatThisLine = PR_TRUE; return buf.Length(); } // ... but there's no point if we're not parsing base64. buf.Assign(line); if (m_stripHtml && m_partIsHtml) { StripHtml (buf); newLength = buf.Length(); } return newLength; }
GnomeVFSResult nsGnomeVFSInputStream::DoRead(char *aBuf, PRUint32 aCount, PRUint32 *aCountRead) { GnomeVFSResult rv; if (mHandle) { GnomeVFSFileSize bytesRead; rv = gnome_vfs_read(mHandle, aBuf, aCount, &bytesRead); if (rv == GNOME_VFS_OK) { // XXX 64-bit here *aCountRead = (PRUint32) bytesRead; mBytesRemaining -= *aCountRead; } } else if (mDirOpen) { rv = GNOME_VFS_OK; while (aCount && rv != GNOME_VFS_ERROR_EOF) { // Copy data out of our buffer PRUint32 bufLen = mDirBuf.Length() - mDirBufCursor; if (bufLen) { PRUint32 n = PR_MIN(bufLen, aCount); memcpy(aBuf, mDirBuf.get() + mDirBufCursor, n); *aCountRead += n; aBuf += n; aCount -= n; mDirBufCursor += n; } if (!mDirListPtr) // Are we at the end of the directory list? { rv = GNOME_VFS_ERROR_EOF; } else if (aCount) // Do we need more data? { GnomeVFSFileInfo *info = (GnomeVFSFileInfo *) mDirListPtr->data; // Prune '.' and '..' from directory listing. if (info->name[0] == '.' && (info->name[1] == '\0' || (info->name[1] == '.' && info->name[2] == '\0'))) { mDirListPtr = mDirListPtr->next; continue; } mDirBuf.Assign("201: "); // The "filename" field nsCString escName; nsCOMPtr<nsINetUtil> nu = do_GetService(NS_NETUTIL_CONTRACTID); if (nu) { nu->EscapeString(nsDependentCString(info->name), nsINetUtil::ESCAPE_URL_PATH, escName); mDirBuf.Append(escName); mDirBuf.Append(' '); } // The "content-length" field // XXX truncates size from 64-bit to 32-bit mDirBuf.AppendInt(PRInt32(info->size)); mDirBuf.Append(' '); // The "last-modified" field // // NSPR promises: PRTime is compatible with time_t // we just need to convert from seconds to microseconds PRExplodedTime tm; PRTime pt = ((PRTime) info->mtime) * 1000000; PR_ExplodeTime(pt, PR_GMTParameters, &tm); { char buf[64]; PR_FormatTimeUSEnglish(buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm); mDirBuf.Append(buf); } // The "file-type" field switch (info->type) { case GNOME_VFS_FILE_TYPE_REGULAR: mDirBuf.Append("FILE "); break; case GNOME_VFS_FILE_TYPE_DIRECTORY: mDirBuf.Append("DIRECTORY "); break; case GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK: mDirBuf.Append("SYMBOLIC-LINK "); break; default: break; } mDirBuf.Append('\n'); mDirBufCursor = 0; mDirListPtr = mDirListPtr->next; } } } else { NS_NOTREACHED("reading from what?"); rv = GNOME_VFS_ERROR_GENERIC; } return rv; }
void ConfigWebRtcLog(mozilla::LogLevel level, uint32_t trace_mask, nsCString &aLogFile, bool multi_log) { if (gWebRtcTraceLoggingOn) { return; } #if defined(ANDROID) // Special case: use callback to pipe to NSPR logging. aLogFile.Assign(default_log_name); #else rtc::LoggingSeverity log_level; switch (level) { case mozilla::LogLevel::Verbose: log_level = rtc::LoggingSeverity::LS_VERBOSE; break; case mozilla::LogLevel::Debug: case mozilla::LogLevel::Info: log_level = rtc::LoggingSeverity::LS_INFO; break; case mozilla::LogLevel::Warning: log_level = rtc::LoggingSeverity::LS_WARNING; break; case mozilla::LogLevel::Error: log_level = rtc::LoggingSeverity::LS_ERROR; break; case mozilla::LogLevel::Disabled: log_level = rtc::LoggingSeverity::LS_NONE; break; default: MOZ_ASSERT(false); break; } rtc::LogMessage::LogToDebug(log_level); if (level != mozilla::LogLevel::Disabled) { // always capture LOG(...) << ... logging in webrtc.org code to nspr logs if (!sSink) { sSink = new LogSinkImpl(); rtc::LogMessage::AddLogToStream(sSink, log_level); // it's ok if this leaks to program end } } else if (sSink) { rtc::LogMessage::RemoveLogToStream(sSink); sSink = nullptr; } webrtc::Trace::set_level_filter(trace_mask); if (trace_mask != 0) { // default WEBRTC_TRACE logs to a rotating file, but allow redirecting to nspr // XXX always redirect in e10s if the sandbox blocks file access, or somehow proxy if (aLogFile.EqualsLiteral("nspr") || aLogFile.EqualsLiteral("moz_log")) { rtc::LogMessage::SetLogToStderr(false); webrtc::Trace::SetTraceCallback(&gWebRtcCallback); } else { rtc::LogMessage::SetLogToStderr(true); webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log); } } else { rtc::LogMessage::SetLogToStderr(false); } if (aLogFile.IsEmpty()) { nsCOMPtr<nsIFile> tempDir; nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir)); if (NS_SUCCEEDED(rv)) { tempDir->AppendNative(default_log_name); #ifdef XP_WIN // WebRTC wants a path encoded in the native charset, not UTF-8. nsAutoString logFile; tempDir->GetPath(logFile); NS_CopyUnicodeToNative(logFile, aLogFile); #else tempDir->GetNativePath(aLogFile); #endif } } #endif if (XRE_IsParentProcess()) { // Capture the final choice for the trace setting. mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile); } }
/** * Read content of file or create file list from directory * @param aBuf read destination buffer * @param aCount length of destination buffer * @param aCountRead number of read characters * @return NS_OK when read successfully, NS_BASE_STREAM_CLOSED when end of file, * error code otherwise */ nsresult nsGIOInputStream::DoRead(char *aBuf, PRUint32 aCount, PRUint32 *aCountRead) { nsresult rv = NS_ERROR_NOT_AVAILABLE; if (mStream) { // file read GError *error = NULL; PRUint32 bytes_read = g_input_stream_read(G_INPUT_STREAM(mStream), aBuf, aCount, NULL, &error); if (error) { rv = MapGIOResult(error); *aCountRead = 0; g_warning("Cannot read from file: %s", error->message); g_error_free(error); return rv; } *aCountRead = bytes_read; mBytesRemaining -= *aCountRead; return NS_OK; } else if (mDirOpen) { // directory read while (aCount && rv != NS_BASE_STREAM_CLOSED) { // Copy data out of our buffer PRUint32 bufLen = mDirBuf.Length() - mDirBufCursor; if (bufLen) { PRUint32 n = NS_MIN(bufLen, aCount); memcpy(aBuf, mDirBuf.get() + mDirBufCursor, n); *aCountRead += n; aBuf += n; aCount -= n; mDirBufCursor += n; } if (!mDirListPtr) // Are we at the end of the directory list? { rv = NS_BASE_STREAM_CLOSED; } else if (aCount) // Do we need more data? { GFileInfo *info = (GFileInfo *) mDirListPtr->data; // Prune '.' and '..' from directory listing. const char * fname = g_file_info_get_name(info); if (fname && fname[0] == '.' && (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0'))) { mDirListPtr = mDirListPtr->next; continue; } mDirBuf.Assign("201: "); // The "filename" field nsCString escName; nsCOMPtr<nsINetUtil> nu = do_GetService(NS_NETUTIL_CONTRACTID); if (nu && fname) { nu->EscapeString(nsDependentCString(fname), nsINetUtil::ESCAPE_URL_PATH, escName); mDirBuf.Append(escName); mDirBuf.Append(' '); } // The "content-length" field // XXX truncates size from 64-bit to 32-bit mDirBuf.AppendInt(PRInt32(g_file_info_get_size(info))); mDirBuf.Append(' '); // The "last-modified" field // // NSPR promises: PRTime is compatible with time_t // we just need to convert from seconds to microseconds GTimeVal gtime; g_file_info_get_modification_time(info, >ime); PRExplodedTime tm; PRTime pt = ((PRTime) gtime.tv_sec) * 1000000; PR_ExplodeTime(pt, PR_GMTParameters, &tm); { char buf[64]; PR_FormatTimeUSEnglish(buf, sizeof(buf), "%a,%%20%d%%20%b%%20%Y%%20%H:%M:%S%%20GMT ", &tm); mDirBuf.Append(buf); } // The "file-type" field switch (g_file_info_get_file_type(info)) { case G_FILE_TYPE_REGULAR: mDirBuf.Append("FILE "); break; case G_FILE_TYPE_DIRECTORY: mDirBuf.Append("DIRECTORY "); break; case G_FILE_TYPE_SYMBOLIC_LINK: mDirBuf.Append("SYMBOLIC-LINK "); break; default: break; } mDirBuf.Append('\n'); mDirBufCursor = 0; mDirListPtr = mDirListPtr->next; } } } return rv; }