nsresult nsResProtocolHandler::SetSubstitution(const nsACString& aRoot, nsIURI* aBaseURI) { MOZ_ASSERT(!aRoot.Equals("")); MOZ_ASSERT(!aRoot.Equals(kAPP)); MOZ_ASSERT(!aRoot.Equals(kGRE)); return SubstitutingProtocolHandler::SetSubstitution(aRoot, aBaseURI); }
nsresult _OldStorage::AssembleCacheKey(nsIURI *aURI, nsACString const & aIdExtension, nsACString & aCacheKey, nsACString & aScheme) { // Copied from nsHttpChannel::AssembleCacheKey aCacheKey.Truncate(); nsresult rv; rv = aURI->GetScheme(aScheme); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString uriSpec; if (aScheme.Equals(NS_LITERAL_CSTRING("http")) || aScheme.Equals(NS_LITERAL_CSTRING("https"))) { if (mLoadInfo->IsAnonymous()) { aCacheKey.AssignLiteral("anon&"); } if (!aIdExtension.IsEmpty()) { aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading()); } nsCOMPtr<nsIURI> noRefURI; rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI)); NS_ENSURE_SUCCESS(rv, rv); rv = noRefURI->GetAsciiSpec(uriSpec); NS_ENSURE_SUCCESS(rv, rv); if (!aCacheKey.IsEmpty()) { aCacheKey.AppendLiteral("uri="); } } else if (aScheme.Equals(NS_LITERAL_CSTRING("wyciwyg"))) { rv = aURI->GetSpec(uriSpec); NS_ENSURE_SUCCESS(rv, rv); } else { rv = aURI->GetAsciiSpec(uriSpec); NS_ENSURE_SUCCESS(rv, rv); } aCacheKey.Append(uriSpec); return NS_OK; }
NS_IMETHODIMP nsLDAPURL::SetScheme(const nsACString &aScheme) { if (!mBaseURL) return NS_ERROR_NOT_INITIALIZED; if (aScheme.Equals(LDAP_SCHEME, nsCaseInsensitiveCStringComparator())) mOptions &= !OPT_SECURE; else if (aScheme.Equals(LDAP_SSL_SCHEME, nsCaseInsensitiveCStringComparator())) mOptions |= OPT_SECURE; else return NS_ERROR_MALFORMED_URI; return mBaseURL->SetScheme(aScheme); }
bool nsResProtocolHandler::ResolveSpecialCases(const nsACString& aHost, const nsACString& aPath, nsACString& aResult) { if (aHost.Equals("") || aHost.Equals(kAPP)) { aResult.Assign(mAppURI); } else if (aHost.Equals(kGRE)) { aResult.Assign(mGREURI); } else { return false; } aResult.Append(aPath); return true; }
//-------------------------------------------------------------- // static nsresult nsCharsetAlias::Equals(const nsACString& aCharset1, const nsACString& aCharset2, bool* oResult) { nsresult res = NS_OK; if(aCharset1.Equals(aCharset2, nsCaseInsensitiveCStringComparator())) { *oResult = true; return res; } if(aCharset1.IsEmpty() || aCharset2.IsEmpty()) { *oResult = false; return res; } *oResult = false; nsCAutoString name1; res = GetPreferredInternal(aCharset1, name1); if (NS_FAILED(res)) return res; nsCAutoString name2; res = GetPreferredInternal(aCharset2, name2); if (NS_FAILED(res)) return res; *oResult = name1.Equals(name2); return NS_OK; }
//-------------------------------------------------------------- NS_IMETHODIMP nsCharsetAlias2::Equals(const nsACString& aCharset1, const nsACString& aCharset2, PRBool* oResult) { nsresult res = NS_OK; if(aCharset1.Equals(aCharset2, nsCaseInsensitiveCStringComparator())) { *oResult = PR_TRUE; return res; } if(aCharset1.IsEmpty() || aCharset2.IsEmpty()) { *oResult = PR_FALSE; return res; } *oResult = PR_FALSE; nsCAutoString name1; nsCAutoString name2; res = this->GetPreferred(aCharset1, name1); if(NS_SUCCEEDED(res)) { res = this->GetPreferred(aCharset2, name2); if(NS_SUCCEEDED(res)) { *oResult = name1.Equals(name2, nsCaseInsensitiveCStringComparator()); } } return res; }
NS_IMETHODIMP calIcalComponent::GetNextProperty(const nsACString &kind, calIIcalProperty **prop) { NS_ENSURE_ARG_POINTER(prop); icalproperty_kind propkind = icalproperty_string_to_kind(PromiseFlatCString(kind).get()); if (propkind == ICAL_NO_PROPERTY) return NS_ERROR_INVALID_ARG; icalproperty *icalprop = nullptr; if (propkind == ICAL_X_PROPERTY) { for (icalprop = icalcomponent_get_next_property(mComponent, ICAL_X_PROPERTY); icalprop; icalprop = icalcomponent_get_next_property(mComponent, ICAL_X_PROPERTY)) { if (kind.Equals(icalproperty_get_x_name(icalprop))) break; } } else { icalprop = icalcomponent_get_next_property(mComponent, propkind); } if (!icalprop) { *prop = nullptr; return NS_OK; } *prop = new calIcalProperty(icalprop, this); CAL_ENSURE_MEMORY(*prop); NS_ADDREF(*prop); return NS_OK; }
nsresult SpdyInformation::GetNPNVersionIndex(const nsACString &npnString, uint8_t *result) { if (npnString.IsEmpty()) return NS_ERROR_FAILURE; if (npnString.Equals(VersionString[0])) *result = Version[0]; else if (npnString.Equals(VersionString[1])) *result = Version[1]; else return NS_ERROR_FAILURE; return NS_OK; }
// Synchronously consume the given input stream and validate the resulting data // against the given string of expected values. void ConsumeAndValidateStream(nsIInputStream* aStream, const nsACString& aExpectedData) { nsAutoCString outputData; nsresult rv = NS_ConsumeStream(aStream, UINT32_MAX, outputData); ASSERT_TRUE(NS_SUCCEEDED(rv)); ASSERT_EQ(aExpectedData.Length(), outputData.Length()); ASSERT_TRUE(aExpectedData.Equals(outputData)); }
// searches against the short queue name PRInt32 tmTransactionService::GetQueueID(const nsACString & aDomainName) { PRUint32 size = mQueueMaps.Size(); tm_queue_mapping *qmap = nsnull; for (PRUint32 index = 0; index < size; index++) { qmap = (tm_queue_mapping*) mQueueMaps[index]; if (qmap && aDomainName.Equals(qmap->domainName)) return qmap->queueID; } return TM_NO_ID; }
NS_IMETHODIMP nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader, nsACString & aValue) { aValue.Truncate(); if (!mHttpChannel) return NS_ERROR_NULL_POINTER; if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"), nsCaseInsensitiveCStringComparator()) && !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"), nsCaseInsensitiveCStringComparator()) && !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"), nsCaseInsensitiveCStringComparator()) && !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"), nsCaseInsensitiveCStringComparator())) { return NS_OK; } return mHttpChannel->GetResponseHeader(aHeader, aValue); }
bool nsGSettingsCollection::KeyExists(const nsACString& aKey) { if (!mKeys) mKeys = g_settings_list_keys(mSettings); for (PRUint32 i = 0; mKeys[i] != NULL; i++) { if (aKey.Equals(mKeys[i])) return true; } return false; }
nsresult SpdyInformation::GetNPNVersionIndex(const nsACString &npnString, uint8_t *result) { if (npnString.IsEmpty()) return NS_ERROR_FAILURE; for (uint32_t index = 0; index < kCount; ++index) { if (npnString.Equals(VersionString[index])) { *result = Version[index]; return NS_OK; } } return NS_ERROR_FAILURE; }
nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &originHost, int32_t originPort, const nsACString &npnToken, const nsACString &username, nsProxyInfo *proxyInfo, const NeckoOriginAttributes &originAttributes, const nsACString &routedHost, int32_t routedPort) { mEndToEndSSL = true; // so DefaultPort() works mRoutedPort = routedPort == -1 ? DefaultPort() : routedPort; if (!originHost.Equals(routedHost) || (originPort != routedPort)) { mRoutedHost = routedHost; } Init(originHost, originPort, npnToken, username, proxyInfo, originAttributes, true); }
NS_IMETHODIMP nsGSettingsService::GetCollectionForSchema(const nsACString& schema, nsIGSettingsCollection** collection) { NS_ENSURE_ARG_POINTER(collection); const char * const *schemas = g_settings_list_schemas(); for (PRUint32 i = 0; schemas[i] != NULL; i++) { if (schema.Equals(schemas[i])) { GSettings *settings = g_settings_new(PromiseFlatCString(schema).get()); nsGSettingsCollection *mozGSettings = new nsGSettingsCollection(settings); NS_ADDREF(*collection = mozGSettings); return NS_OK; } } return NS_ERROR_FAILURE; }
static bool HostIgnoredByProxy(const nsACString& aIgnore, const nsACString& aHost) { if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator())) return true; if (aIgnore.First() == '*' && StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1), nsCaseInsensitiveCStringComparator())) return true; int32_t mask = 128; nsReadingIterator<char> start; nsReadingIterator<char> slash; nsReadingIterator<char> end; aIgnore.BeginReading(start); aIgnore.BeginReading(slash); aIgnore.EndReading(end); if (FindCharInReadable('/', slash, end)) { ++slash; nsDependentCSubstring maskStr(slash, end); nsAutoCString maskStr2(maskStr); nsresult err; mask = maskStr2.ToInteger(&err); if (NS_FAILED(err)) { mask = 128; } --slash; } else { slash = end; } nsDependentCSubstring ignoreStripped(start, slash); PRIPv6Addr ignoreAddr, hostAddr; if (!ConvertToIPV6Addr(ignoreStripped, &ignoreAddr, &mask) || !ConvertToIPV6Addr(aHost, &hostAddr, nullptr)) return false; proxy_MaskIPv6Addr(ignoreAddr, mask); proxy_MaskIPv6Addr(hostAddr, mask); return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0; }
static PRBool GConfIgnoreHost(const nsACString& aIgnore, const nsACString& aHost) { if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator())) return PR_TRUE; if (aIgnore.First() == '*' && StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1), nsCaseInsensitiveCStringComparator())) return PR_TRUE; PRInt32 mask = 128; nsReadingIterator<char> start; nsReadingIterator<char> slash; nsReadingIterator<char> end; aIgnore.BeginReading(start); aIgnore.BeginReading(slash); aIgnore.EndReading(end); if (FindCharInReadable('/', slash, end)) { ++slash; nsDependentCSubstring maskStr(slash, end); nsCAutoString maskStr2(maskStr); PRInt32 err; mask = maskStr2.ToInteger(&err); if (err != 0) { mask = 128; } --slash; } else { slash = end; } PRIPv6Addr ignoreAddr, hostAddr; if (!ConvertToIPV6Addr(aIgnore, &ignoreAddr) || !ConvertToIPV6Addr(aHost, &hostAddr)) return PR_FALSE; proxy_MaskIPv6Addr(ignoreAddr, mask); proxy_MaskIPv6Addr(hostAddr, mask); return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0; }
nsresult nsHttpHeaderArray::SetHeader_internal(nsHttpAtom header, const nsACString &headerName, const nsACString &value, nsHttpHeaderArray::HeaderVariety variety) { nsEntry *entry = mHeaders.AppendElement(); if (!entry) { return NS_ERROR_OUT_OF_MEMORY; } entry->header = header; // Only save original form of a header if it is different than the header // atom string. if (!headerName.Equals(header.get())) { entry->headerNameOriginal = headerName; } entry->value = value; entry->variety = variety; return NS_OK; }
// Child-side API bool SetRemoteExceptionHandler(const nsACString& crashPipe) { // crash reporting is disabled if (crashPipe.Equals(kNullNotifyPipe)) return true; NS_ABORT_IF_FALSE(!gExceptionHandler, "crash client already init'd"); gExceptionHandler = new google_breakpad:: ExceptionHandler(L"", NULL, // no filter callback NULL, // no minidump callback NULL, // no callback context google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, NS_ConvertASCIItoUTF16(crashPipe).BeginReading(), NULL); // we either do remote or nothing, no fallback to regular crash reporting return gExceptionHandler->IsOutOfProcess(); }
static bool HasGMPFor(const nsACString& aAPI, const nsACString& aCodec, const nsACString& aGMP) { #ifdef XP_WIN // gmp-clearkey uses WMF for decoding, so if we're using clearkey we must // verify that WMF works before continuing. if (aGMP.Equals(kEMEKeySystemClearkey)) { RefPtr<WMFDecoderModule> pdm(new WMFDecoderModule()); if (aCodec.EqualsLiteral("aac") && !pdm->SupportsMimeType(NS_LITERAL_CSTRING("audio/mp4a-latm"), /* DecoderDoctorDiagnostics* */ nullptr)) { return false; } if (aCodec.EqualsLiteral("h264") && !pdm->SupportsMimeType(NS_LITERAL_CSTRING("video/avc"), /* DecoderDoctorDiagnostics* */ nullptr)) { return false; } } #endif MOZ_ASSERT(NS_IsMainThread(), "HasPluginForAPI must be called on the main thread"); nsTArray<nsCString> tags; tags.AppendElement(aCodec); tags.AppendElement(aGMP); nsCOMPtr<mozIGeckoMediaPluginService> mps = do_GetService("@mozilla.org/gecko-media-plugin-service;1"); if (NS_WARN_IF(!mps)) { return false; } bool hasPlugin = false; if (NS_FAILED(mps->HasPluginForAPI(aAPI, &tags, &hasPlugin))) { return false; } return hasPlugin; }
nsresult nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header, const nsACString &headerNameOriginal, const nsACString &value, nsHttpHeaderArray::HeaderVariety variety) { MOZ_ASSERT((variety == eVarietyResponse) || (variety == eVarietyResponseNetOriginal), "Headers from cache can only be eVarietyResponse and " "eVarietyResponseNetOriginal"); if (variety == eVarietyResponseNetOriginal) { return SetHeader_internal(header, headerNameOriginal, value, eVarietyResponseNetOriginal); } else { nsTArray<nsEntry>::index_type index = 0; do { index = mHeaders.IndexOf(header, index, nsEntry::MatchHeader()); if (index != mHeaders.NoIndex) { nsEntry &entry = mHeaders[index]; if (value.Equals(entry.value)) { MOZ_ASSERT((entry.variety == eVarietyResponseNetOriginal) || (entry.variety == eVarietyResponseNetOriginalAndResponse), "This array must contain only eVarietyResponseNetOriginal" " and eVarietyResponseNetOriginalAndRespons headers!"); entry.variety = eVarietyResponseNetOriginalAndResponse; return NS_OK; } index++; } } while (index != mHeaders.NoIndex); // If we are here, we have not found an entry so add a new one. return SetHeader_internal(header, headerNameOriginal, value, eVarietyResponse); } }
nsresult Http2Decompressor::OutputHeader(const nsACString &name, const nsACString &value) { // exclusions if (name.Equals(NS_LITERAL_CSTRING("connection")) || name.Equals(NS_LITERAL_CSTRING("host")) || name.Equals(NS_LITERAL_CSTRING("keep-alive")) || name.Equals(NS_LITERAL_CSTRING("proxy-connection")) || name.Equals(NS_LITERAL_CSTRING("te")) || name.Equals(NS_LITERAL_CSTRING("transfer-encoding")) || name.Equals(NS_LITERAL_CSTRING("upgrade")) || name.Equals(("accept-encoding"))) { nsCString toLog(name); LOG3(("HTTP Decompressor illegal response header found : %s", toLog.get())); return NS_ERROR_ILLEGAL_VALUE; } // Look for upper case characters in the name. for (const char *cPtr = name.BeginReading(); cPtr && cPtr < name.EndReading(); ++cPtr) { if (*cPtr <= 'Z' && *cPtr >= 'A') { nsCString toLog(name); LOG3(("HTTP Decompressor upper case response header found. [%s]\n", toLog.get())); return NS_ERROR_ILLEGAL_VALUE; } } // Look for CR OR LF in value - could be smuggling Sec 10.3 // can map to space safely for (const char *cPtr = value.BeginReading(); cPtr && cPtr < value.EndReading(); ++cPtr) { if (*cPtr == '\r' || *cPtr== '\n') { char *wPtr = const_cast<char *>(cPtr); *wPtr = ' '; } } // Status comes first if (name.Equals(NS_LITERAL_CSTRING(":status"))) { nsAutoCString status(NS_LITERAL_CSTRING("HTTP/2.0 ")); status.Append(value); status.Append(NS_LITERAL_CSTRING("\r\n")); mOutput->Insert(status, 0); mHeaderStatus = value; } else if (name.Equals(NS_LITERAL_CSTRING(":authority"))) { mHeaderHost = value; } else if (name.Equals(NS_LITERAL_CSTRING(":scheme"))) { mHeaderScheme = value; } else if (name.Equals(NS_LITERAL_CSTRING(":path"))) { mHeaderPath = value; } else if (name.Equals(NS_LITERAL_CSTRING(":method"))) { mHeaderMethod = value; } // http/2 transport level headers shouldn't be gatewayed into http/1 if(*(name.BeginReading()) == ':') { LOG3(("HTTP Decompressor not gatewaying %s into http/1", name.BeginReading())); return NS_OK; } mOutput->Append(name); mOutput->Append(NS_LITERAL_CSTRING(": ")); // Special handling for set-cookie according to the spec bool isSetCookie = name.Equals(NS_LITERAL_CSTRING("set-cookie")); int32_t valueLen = value.Length(); for (int32_t i = 0; i < valueLen; ++i) { if (value[i] == '\0') { if (isSetCookie) { mOutput->Append(NS_LITERAL_CSTRING("\r\n")); mOutput->Append(name); mOutput->Append(NS_LITERAL_CSTRING(": ")); } else { mOutput->Append(NS_LITERAL_CSTRING(", ")); } } else { mOutput->Append(value[i]); } } mOutput->Append(NS_LITERAL_CSTRING("\r\n")); return NS_OK; }
static bool CompareWebGLExtensionName(const nsACString& name, const char* other) { return name.Equals(other, nsCaseInsensitiveCStringComparator()); }
// static PRBool nsDOMStorageList::CanAccessDomain(const nsACString& aRequestedDomain, const nsACString& aCurrentDomain) { return aRequestedDomain.Equals(aCurrentDomain); }
// aOffset should be added to aCharsetStart and aCharsetEnd if this // function sets them. static void net_ParseMediaType(const nsACString &aMediaTypeStr, nsACString &aContentType, nsACString &aContentCharset, PRInt32 aOffset, bool *aHadCharset, PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd) { const nsCString& flatStr = PromiseFlatCString(aMediaTypeStr); const char* start = flatStr.get(); const char* end = start + flatStr.Length(); // Trim LWS leading and trailing whitespace from type. We include '(' in // the trailing trim set to catch media-type comments, which are not at all // standard, but may occur in rare cases. const char* type = net_FindCharNotInSet(start, end, HTTP_LWS); const char* typeEnd = net_FindCharInSet(type, end, HTTP_LWS ";("); const char* charset = ""; const char* charsetEnd = charset; PRInt32 charsetParamStart = 0; PRInt32 charsetParamEnd = 0; // Iterate over parameters bool typeHasCharset = false; PRUint32 paramStart = flatStr.FindChar(';', typeEnd - start); if (paramStart != PRUint32(kNotFound)) { // We have parameters. Iterate over them. PRUint32 curParamStart = paramStart + 1; do { PRUint32 curParamEnd = net_FindMediaDelimiter(flatStr, curParamStart, ';'); const char* paramName = net_FindCharNotInSet(start + curParamStart, start + curParamEnd, HTTP_LWS); static const char charsetStr[] = "charset="; if (PL_strncasecmp(paramName, charsetStr, sizeof(charsetStr) - 1) == 0) { charset = paramName + sizeof(charsetStr) - 1; charsetEnd = start + curParamEnd; typeHasCharset = true; charsetParamStart = curParamStart - 1; charsetParamEnd = curParamEnd; } curParamStart = curParamEnd + 1; } while (curParamStart < flatStr.Length()); } bool charsetNeedsQuotedStringUnescaping = false; if (typeHasCharset) { // Trim LWS leading and trailing whitespace from charset. We include // '(' in the trailing trim set to catch media-type comments, which are // not at all standard, but may occur in rare cases. charset = net_FindCharNotInSet(charset, charsetEnd, HTTP_LWS); if (*charset == '"') { charsetNeedsQuotedStringUnescaping = true; charsetEnd = start + net_FindStringEnd(flatStr, charset - start, *charset); charset++; NS_ASSERTION(charsetEnd >= charset, "Bad charset parsing"); } else { charsetEnd = net_FindCharInSet(charset, charsetEnd, HTTP_LWS ";("); } } // if the server sent "*/*", it is meaningless, so do not store it. // also, if type is the same as aContentType, then just update the // charset. however, if charset is empty and aContentType hasn't // changed, then don't wipe-out an existing aContentCharset. We // also want to reject a mime-type if it does not include a slash. // some servers give junk after the charset parameter, which may // include a comma, so this check makes us a bit more tolerant. if (type != typeEnd && strncmp(type, "*/*", typeEnd - type) != 0 && memchr(type, '/', typeEnd - type) != NULL) { // Common case here is that aContentType is empty bool eq = !aContentType.IsEmpty() && aContentType.Equals(Substring(type, typeEnd), nsCaseInsensitiveCStringComparator()); if (!eq) { aContentType.Assign(type, typeEnd - type); ToLowerCase(aContentType); } if ((!eq && *aHadCharset) || typeHasCharset) { *aHadCharset = true; if (charsetNeedsQuotedStringUnescaping) { // parameters using the "quoted-string" syntax need // backslash-escapes to be unescaped (see RFC 2616 Section 2.2) aContentCharset.Truncate(); for (const char *c = charset; c != charsetEnd; c++) { if (*c == '\\' && c + 1 != charsetEnd) { // eat escape c++; } aContentCharset.Append(*c); } } else { aContentCharset.Assign(charset, charsetEnd - charset); } if (typeHasCharset) { *aCharsetStart = charsetParamStart + aOffset; *aCharsetEnd = charsetParamEnd + aOffset; } } // Only set a new charset position if this is a different type // from the last one we had and it doesn't already have a // charset param. If this is the same type, we probably want // to leave the charset position on its first occurrence. if (!eq && !typeHasCharset) { PRInt32 charsetStart = PRInt32(paramStart); if (charsetStart == kNotFound) charsetStart = flatStr.Length(); *aCharsetEnd = *aCharsetStart = charsetStart + aOffset; } } }
nsresult Http2Decompressor::OutputHeader(const nsACString &name, const nsACString &value) { // exclusions if (!mIsPush && (name.EqualsLiteral("connection") || name.EqualsLiteral("host") || name.EqualsLiteral("keep-alive") || name.EqualsLiteral("proxy-connection") || name.EqualsLiteral("te") || name.EqualsLiteral("transfer-encoding") || name.EqualsLiteral("upgrade") || name.Equals(("accept-encoding")))) { nsCString toLog(name); LOG(("HTTP Decompressor illegal response header found, not gatewaying: %s", toLog.get())); return NS_OK; } // Look for upper case characters in the name. for (const char *cPtr = name.BeginReading(); cPtr && cPtr < name.EndReading(); ++cPtr) { if (*cPtr <= 'Z' && *cPtr >= 'A') { nsCString toLog(name); LOG(("HTTP Decompressor upper case response header found. [%s]\n", toLog.get())); return NS_ERROR_ILLEGAL_VALUE; } } // Look for CR OR LF in value - could be smuggling Sec 10.3 // can map to space safely for (const char *cPtr = value.BeginReading(); cPtr && cPtr < value.EndReading(); ++cPtr) { if (*cPtr == '\r' || *cPtr== '\n') { char *wPtr = const_cast<char *>(cPtr); *wPtr = ' '; } } // Status comes first if (name.EqualsLiteral(":status")) { nsAutoCString status(NS_LITERAL_CSTRING("HTTP/2.0 ")); status.Append(value); status.AppendLiteral("\r\n"); mOutput->Insert(status, 0); mHeaderStatus = value; } else if (name.EqualsLiteral(":authority")) { mHeaderHost = value; } else if (name.EqualsLiteral(":scheme")) { mHeaderScheme = value; } else if (name.EqualsLiteral(":path")) { mHeaderPath = value; } else if (name.EqualsLiteral(":method")) { mHeaderMethod = value; } // http/2 transport level headers shouldn't be gatewayed into http/1 bool isColonHeader = false; for (const char *cPtr = name.BeginReading(); cPtr && cPtr < name.EndReading(); ++cPtr) { if (*cPtr == ':') { isColonHeader = true; break; } else if (*cPtr != ' ' && *cPtr != '\t') { isColonHeader = false; break; } } if(isColonHeader) { // :status is the only pseudo-header field allowed in received HEADERS frames, PUSH_PROMISE allows the other pseudo-header fields if (!name.EqualsLiteral(":status") && !mIsPush) { LOG(("HTTP Decompressor found illegal response pseudo-header %s", name.BeginReading())); return NS_ERROR_ILLEGAL_VALUE; } if (mSeenNonColonHeader) { LOG(("HTTP Decompressor found illegal : header %s", name.BeginReading())); return NS_ERROR_ILLEGAL_VALUE; } LOG(("HTTP Decompressor not gatewaying %s into http/1", name.BeginReading())); return NS_OK; } LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(), value.BeginReading())); mSeenNonColonHeader = true; mOutput->Append(name); mOutput->AppendLiteral(": "); mOutput->Append(value); mOutput->AppendLiteral("\r\n"); return NS_OK; }
/* static */ nsresult sbURIChecker::CheckDomain( nsACString &aDomain, nsIURI *aSiteURI ) { NS_ENSURE_ARG_POINTER(aSiteURI); LOG(( "sbURIChecker::CheckDomain(%s)", aDomain.BeginReading() )); // get host from URI nsCString host; nsresult rv = aSiteURI->GetHost(host); NS_ENSURE_SUCCESS( rv, rv ); nsCString fixedHost; rv = sbURIChecker::FixupDomain( host, fixedHost ); NS_ENSURE_SUCCESS( rv, rv ); host.Assign(fixedHost); if ( !aDomain.IsEmpty() ) { LOG(("sbURIChecker::CheckDomain() -- Have a domain from the user")); // remove trailing dots, lowercase it nsCString fixedDomain; rv = sbURIChecker::FixupDomain( aDomain, fixedDomain ); NS_ENSURE_SUCCESS( rv, rv ); aDomain.Assign(fixedDomain); // Deal first with numerical ip addresses PRNetAddr addr; if ( PR_StringToNetAddr( host.get(), &addr ) == PR_SUCCESS ) { // numerical ip address LOG(("sbURIChecker::CheckDomain() -- Numerical Address ")); if ( !aDomain.Equals(host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED ip address check")); return NS_ERROR_FAILURE; } } else { // domain based host, check it against host from URI LOG(("sbURIChecker::CheckDomain() -- Domain based host ")); // make sure the domain wasn't '.com' - it should have a dot in it // we need to skip this check if the host is localhost PRInt32 dot = aDomain.FindChar('.'); if ( dot < 0 && !host.Equals("localhost")) { LOG(("sbURIChecker::CheckDomain() -- FAILED dot test ")); return NS_ERROR_FAILURE; } // prepend a dot so bar.com doesn't match foobar.com but does foo.bar.com aDomain.Insert( NS_LITERAL_CSTRING("."), 0 ); PRInt32 domainLength = aDomain.Length(); PRInt32 lengthDiff = host.Length() - domainLength; if ( lengthDiff == -1 ) { LOG(("sbURIChecker::CheckDomain() -- long domain check")); // special case: from user: .bar.com vs. from URI: bar.com // XXXredfive - I actually think we'll see this most often because // of the prepending of the dot to the user supplied domain if ( !StringEndsWith(aDomain, host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED long domain check")); return NS_ERROR_FAILURE; } } else if ( lengthDiff == 0 ) { LOG(("sbURIChecker::CheckDomain() -- same length check")); // same length better be the same strings if ( !aDomain.Equals(host) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED same length check")); return NS_ERROR_FAILURE; } } else if ( lengthDiff > 0 ) { LOG(("sbURIChecker::CheckDomain() -- parent domain check")); // normal case URI host is longer that host from user // from user: .bar.com from URI: foo.bar.com if ( !StringEndsWith(host, aDomain) ) { LOG(("sbURIChecker::CheckDomain() -- FAILED parent domain check")); return NS_ERROR_FAILURE; } } else { // domains are WAY off, the user domain is more than 1 char longer than // the URI domain. ie: user: jgaunt.com URI: "" LOG(("sbURIChecker::CheckDomain() -- FAILED, user domain is superset")); return NS_ERROR_FAILURE; } // remove the leading dot we added aDomain.Cut( 0, 1 ); } } else { LOG(( "sbURIChecker::CheckDomain() -- NO domain from the user")); // If the user didn't specify a host // if the URI host is empty, make sure we're file:// if ( host.IsEmpty() ) { PRBool isFileURI; rv = aSiteURI->SchemeIs( "file", &isFileURI ); NS_ENSURE_SUCCESS( rv, rv ); if (!isFileURI) { // non-file URI without a host!!! LOG(("sbURIChecker::CheckDomain() -- FAILED file scheme check")); return NS_ERROR_FAILURE; } // clear the isVoid flag if set aDomain.Truncate(); } else { // no domain from the user but there is a domain from the URI aDomain.Assign(host); } } LOG(("sbURIChecker::CheckDomain() -- PASSED match test")); return NS_OK; }