NS_IMETHODIMP nsCertOverrideService::ClearValidityOverride(const nsACString & aHostName, int32_t aPort) { if (aPort == 0 && aHostName.EqualsLiteral("all:temporary-certificates")) { RemoveAllTemporaryOverrides(); return NS_OK; } nsAutoCString hostPort; GetHostWithPort(aHostName, aPort, hostPort); { ReentrantMonitorAutoEnter lock(monitor); mSettingsTable.RemoveEntry(hostPort.get()); Write(); } SSL_ClearSessionCache(); return NS_OK; }
// IUDPSocketInternal interfaces // callback while error happened in UDP socket operation NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &type, const nsACString &message, const nsACString &filename, uint32_t line_number, uint32_t column_number) { ASSERT_ON_THREAD(main_thread_); MOZ_ASSERT(type.EqualsLiteral("onerror")); r_log(LOG_GENERIC, LOG_ERR, "UDP socket error:%s at %s:%d:%d", message.BeginReading(), filename.BeginReading(), line_number, column_number); ReentrantMonitorAutoEnter mon(monitor_); err_ = true; monitor_.NotifyAll(); return NS_OK; }
bool AndroidDecoderModule::SupportsMimeType(const nsACString& aMimeType) { if (jni::GetAPIVersion() < 16) { return false; } if (aMimeType.EqualsLiteral("video/mp4") || aMimeType.EqualsLiteral("video/avc")) { return true; } // When checking "audio/x-wav", CreateDecoder can cause a JNI ERROR by // Accessing a stale local reference leading to a SIGSEGV crash. // To avoid this we check for wav types here. if (aMimeType.EqualsLiteral("audio/x-wav") || aMimeType.EqualsLiteral("audio/wave; codecs=1") || aMimeType.EqualsLiteral("audio/wave; codecs=6") || aMimeType.EqualsLiteral("audio/wave; codecs=7") || aMimeType.EqualsLiteral("audio/wave; codecs=65534")) { return false; } if ((VPXDecoder::IsVPX(aMimeType, VPXDecoder::VP8) && !GetFeatureStatus(nsIGfxInfo::FEATURE_VP8_HW_DECODE)) || (VPXDecoder::IsVPX(aMimeType, VPXDecoder::VP9) && !GetFeatureStatus(nsIGfxInfo::FEATURE_VP9_HW_DECODE))) { return false; } // Prefer the gecko decoder for opus and vorbis; stagefright crashes // on content demuxed from mp4. // Not all android devices support FLAC even when they say they do. if (OpusDataDecoder::IsOpus(aMimeType) || VorbisDataDecoder::IsVorbis(aMimeType) || aMimeType.EqualsLiteral("audio/flac")) { SLOG("Rejecting audio of type %s", aMimeType.Data()); return false; } // Prefer the gecko decoder for Theora. // Not all android devices support Theora even when they say they do. if (TheoraDecoder::IsTheora(aMimeType)) { SLOG("Rejecting video of type %s", aMimeType.Data()); return false; } return java::HardwareCodecCapabilityUtils::FindDecoderCodecInfoForMimeType( TranslateMimeType(aMimeType)); }
/* static */ const Maybe<nsCString> GMPDecoderModule::PreferredGMP(const nsACString& aMimeType) { Maybe<nsCString> rv; if (aMimeType.EqualsLiteral("audio/mp4a-latm")) { switch (MediaPrefs::GMPAACPreferred()) { case 1: rv.emplace(kEMEKeySystemClearkey); break; case 2: rv.emplace(kEMEKeySystemPrimetime); break; default: break; } } if (MP4Decoder::IsH264(aMimeType)) { switch (MediaPrefs::GMPH264Preferred()) { case 1: rv.emplace(kEMEKeySystemClearkey); break; case 2: rv.emplace(kEMEKeySystemPrimetime); break; default: break; } } return rv; }
static nsresult FetcherURLDoneCallback(nsresult aStatus, const nsACString &aContentType, const nsACString &aCharset, PRInt32 totalSize, const PRUnichar* aMsg, void *tagData) { nsMsgAttachmentHandler *ma = (nsMsgAttachmentHandler *) tagData; NS_ASSERTION(ma != nsnull, "not-null mime attachment"); if (ma != nsnull) { ma->m_size = totalSize; if (!aContentType.IsEmpty()) { #ifdef XP_MACOSX //Do not change the type if we are dealing with an encoded (e.g., appledouble or zip) file if (!ma->mEncodedWorkingFile) #else // can't send appledouble on non-macs if (!aContentType.EqualsLiteral("multipart/appledouble")) #endif { PR_Free(ma->m_type); ma->m_type = ToNewCString(aContentType); } } if (!aCharset.IsEmpty()) { PR_Free(ma->m_charset); ma->m_charset = ToNewCString(aCharset); } return ma->UrlExit(aStatus, aMsg); } else return NS_OK; }
// callback while receiving UDP packet NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &type, const nsACString &host, uint16_t port, uint8_t *data, uint32_t data_length) { ASSERT_ON_THREAD(main_thread_); MOZ_ASSERT(type.EqualsLiteral("ondata")); PRNetAddr addr; memset(&addr, 0, sizeof(addr)); { ReentrantMonitorAutoEnter mon(monitor_); if (PR_SUCCESS != PR_StringToNetAddr(host.BeginReading(), &addr)) { err_ = true; MOZ_ASSERT(false, "Failed to convert remote host to PRNetAddr"); return NS_OK; } // Use PR_IpAddrNull to avoid address being reset to 0. if (PR_SUCCESS != PR_SetNetAddr(PR_IpAddrNull, addr.raw.family, port, &addr)) { err_ = true; MOZ_ASSERT(false, "Failed to set port in PRNetAddr"); return NS_OK; } } nsAutoPtr<DataBuffer> buf(new DataBuffer(data, data_length)); RefPtr<nr_udp_message> msg(new nr_udp_message(addr, buf)); RUN_ON_THREAD(sts_thread_, mozilla::WrapRunnable(nsRefPtr<NrSocketIpc>(this), &NrSocketIpc::recv_callback_s, msg), NS_DISPATCH_NORMAL); return NS_OK; }
void ConvertTextAttributeToAtkAttribute(const nsACString& aName, const nsAString& aValue, AtkAttributeSet** aAttributeSet) { // Handle attributes where atk has its own name. const char* atkName = nullptr; nsAutoString atkValue; if (aName.EqualsLiteral("color")) { // The format of the atk attribute is r,g,b and the gecko one is // rgb(r, g, b). atkValue = Substring(aValue, 4, aValue.Length() - 5); atkValue.StripWhitespace(); atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR]; } else if (aName.EqualsLiteral("background-color")) { // The format of the atk attribute is r,g,b and the gecko one is // rgb(r, g, b). atkValue = Substring(aValue, 4, aValue.Length() - 5); atkValue.StripWhitespace(); atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR]; } else if (aName.EqualsLiteral("font-family")) { atkValue = aValue; atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME]; } else if (aName.EqualsLiteral("font-size")) { // ATK wants the number of pixels without px at the end. atkValue = StringHead(aValue, aValue.Length() - 2); atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE]; } else if (aName.EqualsLiteral("font-weight")) { atkValue = aValue; atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT]; } else if (aName.EqualsLiteral("invalid")) { atkValue = aValue; atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID]; } if (atkName) { AtkAttribute* objAttr = static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute))); objAttr->name = g_strdup(atkName); objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get()); *aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr); } }
nsresult nsHtml5Parser::Parse(const nsAString& aSourceBuffer, void* aKey, const nsACString& aContentType, bool aLastCall, nsDTDMode aMode) // ignored { nsresult rv; if (NS_FAILED(rv = mExecutor->IsBroken())) { return rv; } if (aSourceBuffer.Length() > INT32_MAX) { return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY); } // Maintain a reference to ourselves so we don't go away // till we're completely done. The old parser grips itself in this method. nsCOMPtr<nsIParser> kungFuDeathGrip(this); // Gripping the other objects just in case, since the other old grip // required grips to these, too. nsRefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser()); nsRefPtr<nsHtml5TreeOpExecutor> treeOpKungFuDeathGrip(mExecutor); if (!mExecutor->HasStarted()) { NS_ASSERTION(!GetStreamParser(), "Had stream parser but document.write started life cycle."); // This is the first document.write() on a document.open()ed document mExecutor->SetParser(this); mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled()); bool isSrcdoc = false; nsCOMPtr<nsIChannel> channel; rv = GetChannel(getter_AddRefs(channel)); if (NS_SUCCEEDED(rv)) { isSrcdoc = NS_IsSrcdocChannel(channel); } mTreeBuilder->setIsSrcdocDocument(isSrcdoc); mTokenizer->start(); mExecutor->Start(); if (!aContentType.EqualsLiteral("text/html")) { mTreeBuilder->StartPlainText(); mTokenizer->StartPlainText(); } /* * If you move the following line, be very careful not to cause * WillBuildModel to be called before the document has had its * script global object set. */ rv = mExecutor->WillBuildModel(eDTDMode_unknown); NS_ENSURE_SUCCESS(rv, rv); } // Return early if the parser has processed EOF if (mExecutor->IsComplete()) { return NS_OK; } if (aLastCall && aSourceBuffer.IsEmpty() && !aKey) { // document.close() NS_ASSERTION(!GetStreamParser(), "Had stream parser but got document.close()."); if (mDocumentClosed) { // already closed return NS_OK; } mDocumentClosed = true; if (!mBlocked && !mInDocumentWrite) { return ParseUntilBlocked(); } return NS_OK; } // If we got this far, we are dealing with a document.write or // document.writeln call--not document.close(). NS_ASSERTION(IsInsertionPointDefined(), "Doc.write reached parser with undefined insertion point."); NS_ASSERTION(!(GetStreamParser() && !aKey), "Got a null key in a non-script-created parser"); // XXX is this optimization bogus? if (aSourceBuffer.IsEmpty()) { return NS_OK; } // This guard is here to prevent document.close from tokenizing synchronously // while a document.write (that wrote the script that called document.close!) // is still on the call stack. mozilla::AutoRestore<bool> guard(mInDocumentWrite); mInDocumentWrite = true; // The script is identified by aKey. If there's nothing in the buffer // chain for that key, we'll insert at the head of the queue. // When the script leaves something in the queue, a zero-length // key-holder "buffer" is inserted in the queue. If the same script // leaves something in the chain again, it will be inserted immediately // before the old key holder belonging to the same script. // // We don't do the actual data insertion yet in the hope that the data gets // tokenized and there no data or less data to copy to the heap after // tokenization. Also, this way, we avoid inserting one empty data buffer // per document.write, which matters for performance when the parser isn't // blocked and a badly-authored script calls document.write() once per // input character. (As seen in a benchmark!) // // The insertion into the input stream happens conceptually before anything // gets tokenized. To make sure multi-level document.write works right, // it's necessary to establish the location of our parser key up front // in case this is the first write with this key. // // In a document.open() case, the first write level has a null key, so that // case is handled separately, because normal buffers containing data // have null keys. // These don't need to be owning references, because they always point to // the buffer queue and buffers can't be removed from the buffer queue // before document.write() returns. The buffer queue clean-up happens the // next time ParseUntilBlocked() is called. // However, they are made owning just in case the reasoning above is flawed // and a flaw would lead to worse problems with plain pointers. If this // turns out to be a perf problem, it's worthwhile to consider making // prevSearchbuf a plain pointer again. nsRefPtr<nsHtml5OwningUTF16Buffer> prevSearchBuf; nsRefPtr<nsHtml5OwningUTF16Buffer> firstLevelMarker; if (aKey) { if (mFirstBuffer == mLastBuffer) { nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey); keyHolder->next = mLastBuffer; mFirstBuffer = keyHolder; } else if (mFirstBuffer->key != aKey) { prevSearchBuf = mFirstBuffer; for (;;) { if (prevSearchBuf->next == mLastBuffer) { // key was not found nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey); keyHolder->next = mFirstBuffer; mFirstBuffer = keyHolder; prevSearchBuf = nullptr; break; } if (prevSearchBuf->next->key == aKey) { // found a key holder break; } prevSearchBuf = prevSearchBuf->next; } } // else mFirstBuffer is the keyholder // prevSearchBuf is the previous buffer before the keyholder or null if // there isn't one. } else { // We have a first-level write in the document.open() case. We insert before // mLastBuffer, effectively, by making mLastBuffer be a new sentinel object // and redesignating the previous mLastBuffer as our firstLevelMarker. We // need to put a marker there, because otherwise additional document.writes // from nested event loops would insert in the wrong place. Sigh. mLastBuffer->next = new nsHtml5OwningUTF16Buffer((void*)nullptr); firstLevelMarker = mLastBuffer; mLastBuffer = mLastBuffer->next; } nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer); while (!mBlocked && stackBuffer.hasMore()) { stackBuffer.adjust(mLastWasCR); mLastWasCR = false; if (stackBuffer.hasMore()) { int32_t lineNumberSave; bool inRootContext = (!GetStreamParser() && !aKey); if (inRootContext) { mTokenizer->setLineNumber(mRootContextLineNumber); } else { // we aren't the root context, so save the line number on the // *stack* so that we can restore it. lineNumberSave = mTokenizer->getLineNumber(); } mLastWasCR = mTokenizer->tokenizeBuffer(&stackBuffer); if (inRootContext) { mRootContextLineNumber = mTokenizer->getLineNumber(); } else { mTokenizer->setLineNumber(lineNumberSave); } if (mTreeBuilder->HasScript()) { mTreeBuilder->Flush(); // Move ops to the executor rv = mExecutor->FlushDocumentWrite(); // run the ops NS_ENSURE_SUCCESS(rv, rv); // Flushing tree ops can cause all sorts of things. // Return early if the parser got terminated. if (mExecutor->IsComplete()) { return NS_OK; } } // Ignore suspension requests } } nsRefPtr<nsHtml5OwningUTF16Buffer> heapBuffer; if (stackBuffer.hasMore()) { // The buffer wasn't tokenized to completion. Create a copy of the tail // on the heap. heapBuffer = stackBuffer.FalliblyCopyAsOwningBuffer(); if (!heapBuffer) { // Allocation failed. The parser is now broken. return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY); } } if (heapBuffer) { // We have something to insert before the keyholder holding in the non-null // aKey case and we have something to swap into firstLevelMarker in the // null aKey case. if (aKey) { NS_ASSERTION(mFirstBuffer != mLastBuffer, "Where's the keyholder?"); // the key holder is still somewhere further down the list from // prevSearchBuf (which may be null) if (mFirstBuffer->key == aKey) { NS_ASSERTION(!prevSearchBuf, "Non-null prevSearchBuf when mFirstBuffer is the key holder?"); heapBuffer->next = mFirstBuffer; mFirstBuffer = heapBuffer; } else { if (!prevSearchBuf) { prevSearchBuf = mFirstBuffer; } // We created a key holder earlier, so we will find it without walking // past the end of the list. while (prevSearchBuf->next->key != aKey) { prevSearchBuf = prevSearchBuf->next; } heapBuffer->next = prevSearchBuf->next; prevSearchBuf->next = heapBuffer; } } else { NS_ASSERTION(firstLevelMarker, "How come we don't have a marker."); firstLevelMarker->Swap(heapBuffer); } } if (!mBlocked) { // buffer was tokenized to completion NS_ASSERTION(!stackBuffer.hasMore(), "Buffer wasn't tokenized to completion?"); // Scripting semantics require a forced tree builder flush here mTreeBuilder->Flush(); // Move ops to the executor rv = mExecutor->FlushDocumentWrite(); // run the ops NS_ENSURE_SUCCESS(rv, rv); } else if (stackBuffer.hasMore()) { // The buffer wasn't tokenized to completion. Tokenize the untokenized // content in order to preload stuff. This content will be retokenized // later for normal parsing. if (!mDocWriteSpeculatorActive) { mDocWriteSpeculatorActive = true; if (!mDocWriteSpeculativeTreeBuilder) { // Lazily initialize if uninitialized mDocWriteSpeculativeTreeBuilder = new nsHtml5TreeBuilder(nullptr, mExecutor->GetStage()); mDocWriteSpeculativeTreeBuilder->setScriptingEnabled( mTreeBuilder->isScriptingEnabled()); mDocWriteSpeculativeTokenizer = new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false); mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable); mDocWriteSpeculativeTokenizer->start(); } mDocWriteSpeculativeTokenizer->resetToDataState(); mDocWriteSpeculativeTreeBuilder->loadState(mTreeBuilder, &mAtomTable); mDocWriteSpeculativeLastWasCR = false; } // Note that with multilevel document.write if we didn't just activate the // speculator, it's possible that the speculator is now in the wrong state. // That's OK for the sake of simplicity. The worst that can happen is // that the speculative loads aren't exactly right. The content will be // reparsed anyway for non-preload purposes. // The buffer position for subsequent non-speculative parsing now lives // in heapBuffer, so it's ok to let the buffer position of stackBuffer // to be overwritten and not restored below. while (stackBuffer.hasMore()) { stackBuffer.adjust(mDocWriteSpeculativeLastWasCR); if (stackBuffer.hasMore()) { mDocWriteSpeculativeLastWasCR = mDocWriteSpeculativeTokenizer->tokenizeBuffer(&stackBuffer); } } mDocWriteSpeculativeTreeBuilder->Flush(); mDocWriteSpeculativeTreeBuilder->DropHandles(); mExecutor->FlushSpeculativeLoads(); } return NS_OK; }
/* static */ bool MP4Decoder::IsH264(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("video/mp4") || aMimeType.EqualsLiteral("video/avc"); }
bool OmxDecoderModule::SupportsMimeType(const nsACString& aMimeType) const { return aMimeType.EqualsLiteral("audio/mp4a-latm"); }
bool AppleDecoderModule::SupportsMimeType(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("audio/mpeg") || PlatformDecoderModule::SupportsMimeType(aMimeType); }
nsresult Http2Decompressor::OutputHeader(const nsACString &name, const nsACString &value) { // exclusions if (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 : %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); 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 if(*(name.BeginReading()) == ':') { LOG(("HTTP Decompressor not gatewaying %s into http/1", name.BeginReading())); return NS_OK; } mOutput->Append(name); mOutput->AppendLiteral(": "); // Special handling for set-cookie according to the spec bool isSetCookie = name.EqualsLiteral("set-cookie"); int32_t valueLen = value.Length(); nsAutoCString textValue; for (int32_t i = 0; i < valueLen; ++i) { if (value[i] == '\0') { if (isSetCookie) { LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(), textValue.get())); mOutput->Append(textValue); textValue.Truncate(0); mOutput->AppendLiteral("\r\n"); mOutput->Append(name); mOutput->AppendLiteral(": "); } else { textValue.AppendLiteral(", "); } } else { textValue.Append(value[i]); } } LOG(("Http2Decompressor::OutputHeader %s %s", name.BeginReading(), textValue.get())); mOutput->Append(textValue); mOutput->AppendLiteral("\r\n"); return NS_OK; }
// Match stock icons with names static SHSTOCKICONID GetStockIconIDForName(const nsACString& aStockName) { return aStockName.EqualsLiteral("uac-shield") ? SIID_SHIELD : SIID_INVALID; }
NS_IMETHODIMP nsDSURIContentListener::DoContent(const nsACString& aContentType, bool aIsContentPreferred, nsIRequest* aRequest, nsIStreamListener** aContentHandler, bool* aAbortProcess) { nsresult rv; NS_ENSURE_ARG_POINTER(aContentHandler); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); // Check whether X-Frame-Options permits us to load this content in an // iframe and abort the load (unless we've disabled x-frame-options // checking). if (!CheckFrameOptions(aRequest)) { *aAbortProcess = true; return NS_OK; } *aAbortProcess = false; // determine if the channel has just been retargeted to us... nsLoadFlags loadFlags = 0; nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest); if (aOpenedChannel) { aOpenedChannel->GetLoadFlags(&loadFlags); } if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { // XXX: Why does this not stop the content too? mDocShell->Stop(nsIWebNavigation::STOP_NETWORK); mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL); } // In case of multipart jpeg request (mjpeg) we don't really want to // create new viewer since the one we already have is capable of // rendering multipart jpeg correctly (see bug 625012) nsCOMPtr<nsIChannel> baseChannel; if (nsCOMPtr<nsIMultiPartChannel> mpchan = do_QueryInterface(aRequest)) { mpchan->GetBaseChannel(getter_AddRefs(baseChannel)); } bool reuseCV = baseChannel && baseChannel == mExistingJPEGRequest && aContentType.EqualsLiteral("image/jpeg"); if (mExistingJPEGStreamListener && reuseCV) { RefPtr<nsIStreamListener> copy(mExistingJPEGStreamListener); copy.forget(aContentHandler); rv = NS_OK; } else { rv = mDocShell->CreateContentViewer(aContentType, aRequest, aContentHandler); if (NS_SUCCEEDED(rv) && reuseCV) { mExistingJPEGStreamListener = *aContentHandler; } else { mExistingJPEGStreamListener = nullptr; } mExistingJPEGRequest = baseChannel; } if (rv == NS_ERROR_REMOTE_XUL) { aRequest->Cancel(rv); *aAbortProcess = true; return NS_OK; } if (NS_FAILED(rv)) { // we don't know how to handle the content *aContentHandler = nullptr; return rv; } if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { nsCOMPtr<nsPIDOMWindowOuter> domWindow = mDocShell ? mDocShell->GetWindow() : nullptr; NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); domWindow->Focus(); } return NS_OK; }
// Instantiates but does not initialize decoder. static already_AddRefed<MediaDecoder> InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner) { nsRefPtr<MediaDecoder> decoder; #ifdef MOZ_FMP4 if (IsMP4SupportedType(aType)) { decoder = new MP4Decoder(); return decoder.forget(); } #endif #ifdef MOZ_GSTREAMER if (IsGStreamerSupportedType(aType)) { decoder = new GStreamerDecoder(); return decoder.forget(); } #endif #ifdef MOZ_RAW if (IsRawType(aType)) { decoder = new RawDecoder(); return decoder.forget(); } #endif if (IsOggType(aType)) { decoder = new OggDecoder(); return decoder.forget(); } #ifdef MOZ_WAVE if (IsWaveType(aType)) { decoder = new WaveDecoder(); return decoder.forget(); } #endif #ifdef MOZ_OMX_DECODER if (IsOmxSupportedType(aType)) { // AMR audio is enabled for MMS, but we are discouraging Web and App // developers from using AMR, thus we only allow AMR to be played on WebApps. if (aType.EqualsLiteral(AUDIO_AMR) || aType.EqualsLiteral(AUDIO_3GPP)) { dom::HTMLMediaElement* element = aOwner->GetMediaElement(); if (!element) { return nullptr; } nsIPrincipal* principal = element->NodePrincipal(); if (!principal) { return nullptr; } if (principal->GetAppStatus() < nsIPrincipal::APP_STATUS_PRIVILEGED) { return nullptr; } } #if ANDROID_VERSION >= 18 decoder = MediaDecoder::IsOmxAsyncEnabled() ? static_cast<MediaDecoder*>(new MediaCodecDecoder()) : static_cast<MediaDecoder*>(new MediaOmxDecoder()); #else decoder = new MediaOmxDecoder(); #endif return decoder.forget(); } #endif #ifdef NECKO_PROTOCOL_rtsp if (IsRtspSupportedType(aType)) { #if ANDROID_VERSION >= 18 decoder = MediaDecoder::IsOmxAsyncEnabled() ? static_cast<MediaDecoder*>(new RtspMediaCodecDecoder()) : static_cast<MediaDecoder*>(new RtspOmxDecoder()); #else decoder = new RtspOmxDecoder(); #endif return decoder.forget(); } #endif #ifdef MOZ_ANDROID_OMX if (MediaDecoder::IsAndroidMediaEnabled() && GetAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) { decoder = new AndroidMediaDecoder(aType); return decoder.forget(); } #endif #ifdef MOZ_WEBM if (IsWebMType(aType)) { decoder = new WebMDecoder(); return decoder.forget(); } #endif #ifdef MOZ_DIRECTSHOW // Note: DirectShow should come before WMF, so that we prefer DirectShow's // MP3 support over WMF's. if (IsDirectShowSupportedType(aType)) { decoder = new DirectShowDecoder(); return decoder.forget(); } #endif #ifdef MOZ_WMF if (IsWMFSupportedType(aType)) { decoder = new WMFDecoder(); return decoder.forget(); } #endif #ifdef MOZ_APPLEMEDIA if (IsAppleMediaSupportedType(aType)) { decoder = new AppleDecoder(); return decoder.forget(); } #endif NS_ENSURE_TRUE(decoder != nullptr, nullptr); NS_ENSURE_TRUE(decoder->Init(aOwner), nullptr); return nullptr; }
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 */ bool VorbisDataDecoder::IsVorbis(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("audio/vorbis"); }
/* static */ bool VPXDecoder::IsVPX(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("video/webm; codecs=vp8") || aMimeType.EqualsLiteral("video/webm; codecs=vp9"); }
/* static */ bool VorbisDataDecoder::IsVorbis(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("audio/webm; codecs=vorbis") || aMimeType.EqualsLiteral("audio/ogg; codecs=vorbis"); }
/* static */ bool MP4Decoder::IsAAC(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("audio/mp4a-latm"); }