/*static*/ already_AddRefed<Response> Response::Constructor(const GlobalObject& aGlobal, const Optional<Nullable<fetch::ResponseBodyInit>>& aBody, const ResponseInit& aInit, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); if (aInit.mStatus < 200 || aInit.mStatus > 599) { aRv.ThrowRangeError<MSG_INVALID_RESPONSE_STATUSCODE_ERROR>(); return nullptr; } // Check if the status text contains illegal characters nsACString::const_iterator start, end; aInit.mStatusText.BeginReading(start); aInit.mStatusText.EndReading(end); if (FindCharInReadable('\r', start, end)) { aRv.ThrowTypeError<MSG_RESPONSE_INVALID_STATUSTEXT_ERROR>(); return nullptr; } // Reset iterator since FindCharInReadable advances it. aInit.mStatusText.BeginReading(start); if (FindCharInReadable('\n', start, end)) { aRv.ThrowTypeError<MSG_RESPONSE_INVALID_STATUSTEXT_ERROR>(); return nullptr; } RefPtr<InternalResponse> internalResponse = new InternalResponse(aInit.mStatus, aInit.mStatusText); // Grab a valid channel info from the global so this response is 'valid' for // interception. if (NS_IsMainThread()) { ChannelInfo info; nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global); if (window) { nsIDocument* doc = window->GetExtantDoc(); MOZ_ASSERT(doc); info.InitFromDocument(doc); } else { info.InitFromChromeGlobal(global); } internalResponse->InitChannelInfo(info); } else { WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(worker); internalResponse->InitChannelInfo(worker->GetChannelInfo()); } RefPtr<Response> r = new Response(global, internalResponse, nullptr); if (aInit.mHeaders.WasPassed()) { internalResponse->Headers()->Clear(); // Instead of using Fill, create an object to allow the constructor to // unwrap the HeadersInit. RefPtr<Headers> headers = Headers::Create(global, aInit.mHeaders.Value(), aRv); if (aRv.Failed()) { return nullptr; } internalResponse->Headers()->Fill(*headers->GetInternalHeaders(), aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } if (aBody.WasPassed() && !aBody.Value().IsNull()) { if (aInit.mStatus == 204 || aInit.mStatus == 205 || aInit.mStatus == 304) { aRv.ThrowTypeError<MSG_RESPONSE_NULL_STATUS_WITH_BODY>(); return nullptr; } nsCString contentTypeWithCharset; nsCOMPtr<nsIInputStream> bodyStream; int64_t bodySize = InternalResponse::UNKNOWN_BODY_SIZE; const fetch::ResponseBodyInit& body = aBody.Value().Value(); if (body.IsReadableStream()) { aRv.MightThrowJSException(); JSContext* cx = aGlobal.Context(); const ReadableStream& readableStream = body.GetAsReadableStream(); JS::Rooted<JSObject*> readableStreamObj(cx, readableStream.Obj()); bool disturbed; bool locked; if (!JS::ReadableStreamIsDisturbed(cx, readableStreamObj, &disturbed) || !JS::ReadableStreamIsLocked(cx, readableStreamObj, &locked)) { aRv.StealExceptionFromJSContext(cx); return nullptr; } if (disturbed || locked) { aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>(); return nullptr; } r->SetReadableStreamBody(cx, readableStreamObj); JS::ReadableStreamMode streamMode; if (!JS::ReadableStreamGetMode(cx, readableStreamObj, &streamMode)) { aRv.StealExceptionFromJSContext(cx); return nullptr; } if (streamMode == JS::ReadableStreamMode::ExternalSource) { // If this is a DOM generated ReadableStream, we can extract the // inputStream directly. void* underlyingSource = nullptr; if (!JS::ReadableStreamGetExternalUnderlyingSource(cx, readableStreamObj, &underlyingSource)) { aRv.StealExceptionFromJSContext(cx); return nullptr; } MOZ_ASSERT(underlyingSource); aRv = FetchStream::RetrieveInputStream(underlyingSource, getter_AddRefs(bodyStream)); // The releasing of the external source is needed in order to avoid an // extra stream lock. if (!JS::ReadableStreamReleaseExternalUnderlyingSource(cx, readableStreamObj)) { aRv.StealExceptionFromJSContext(cx); return nullptr; } if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } else { // If this is a JS-created ReadableStream, let's create a // FetchStreamReader. aRv = FetchStreamReader::Create(aGlobal.Context(), global, getter_AddRefs(r->mFetchStreamReader), getter_AddRefs(bodyStream)); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } } else { uint64_t size = 0; aRv = ExtractByteStreamFromBody(body, getter_AddRefs(bodyStream), contentTypeWithCharset, size); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } bodySize = size; } internalResponse->SetBody(bodyStream, bodySize); if (!contentTypeWithCharset.IsVoid() && !internalResponse->Headers()->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) { // Ignore Append() failing here. ErrorResult error; internalResponse->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentTypeWithCharset, error); error.SuppressException(); } if (aRv.Failed()) { return nullptr; } } r->SetMimeType(); return r.forget(); }
// Automatically import functions in Module \p DestModule based on the summaries // index. // bool FunctionImporter::importFunctions( Module &DestModule, const FunctionImporter::ImportMapTy &ImportList) { DEBUG(dbgs() << "Starting import for Module " << DestModule.getModuleIdentifier() << "\n"); unsigned ImportedCount = 0; // Linker that will be used for importing function Linker TheLinker(DestModule); // Do the actual import of functions now, one Module at a time std::set<StringRef> ModuleNameOrderedList; for (auto &FunctionsToImportPerModule : ImportList) { ModuleNameOrderedList.insert(FunctionsToImportPerModule.first()); } for (auto &Name : ModuleNameOrderedList) { // Get the module for the import const auto &FunctionsToImportPerModule = ImportList.find(Name); assert(FunctionsToImportPerModule != ImportList.end()); std::unique_ptr<Module> SrcModule = ModuleLoader(Name); assert(&DestModule.getContext() == &SrcModule->getContext() && "Context mismatch"); // If modules were created with lazy metadata loading, materialize it // now, before linking it (otherwise this will be a noop). SrcModule->materializeMetadata(); UpgradeDebugInfo(*SrcModule); auto &ImportGUIDs = FunctionsToImportPerModule->second; // Find the globals to import DenseSet<const GlobalValue *> GlobalsToImport; for (auto &GV : *SrcModule) { if (!GV.hasName()) continue; auto GUID = GV.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing " << GUID << " " << GV.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { GV.materialize(); GlobalsToImport.insert(&GV); } } for (auto &GV : SrcModule->globals()) { if (!GV.hasName()) continue; auto GUID = GV.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing " << GUID << " " << GV.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { GV.materialize(); GlobalsToImport.insert(&GV); } } for (auto &GV : SrcModule->aliases()) { if (!GV.hasName()) continue; auto GUID = GV.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing " << GUID << " " << GV.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { // Alias can't point to "available_externally". However when we import // linkOnceODR the linkage does not change. So we import the alias // and aliasee only in this case. GlobalObject *GO = GV.getBaseObject(); if (!GO->hasLinkOnceODRLinkage()) continue; #ifndef NDEBUG if (!GlobalsToImport.count(GO)) DEBUG(dbgs() << " alias triggers importing aliasee " << GO->getGUID() << " " << GO->getName() << " from " << SrcModule->getSourceFileName() << "\n"); #endif GO->materialize(); GlobalsToImport.insert(GO); GV.materialize(); GlobalsToImport.insert(&GV); } } // Link in the specified functions. if (renameModuleForThinLTO(*SrcModule, Index, &GlobalsToImport)) return true; if (PrintImports) { for (const auto *GV : GlobalsToImport) dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName() << " from " << SrcModule->getSourceFileName() << "\n"; } if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None, &GlobalsToImport)) report_fatal_error("Function Import: link error"); ImportedCount += GlobalsToImport.size(); } NumImported += ImportedCount; DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module " << DestModule.getModuleIdentifier() << "\n"); return ImportedCount; }
/*static*/ already_AddRefed<Response> Response::Constructor(const GlobalObject& aGlobal, const Optional<ArrayBufferOrArrayBufferViewOrBlobOrScalarValueStringOrURLSearchParams>& aBody, const ResponseInit& aInit, ErrorResult& aRv) { if (aInit.mStatus < 200 || aInit.mStatus > 599) { aRv.Throw(NS_ERROR_RANGE_ERR); return nullptr; } nsCString statusText; if (aInit.mStatusText.WasPassed()) { statusText = aInit.mStatusText.Value(); nsACString::const_iterator start, end; statusText.BeginReading(start); statusText.EndReading(end); if (FindCharInReadable('\r', start, end)) { aRv.ThrowTypeError(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR); return nullptr; } // Reset iterator since FindCharInReadable advances it. statusText.BeginReading(start); if (FindCharInReadable('\n', start, end)) { aRv.ThrowTypeError(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR); return nullptr; } } else { // Since we don't support default values for ByteString. statusText = NS_LITERAL_CSTRING("OK"); } nsRefPtr<InternalResponse> internalResponse = new InternalResponse(aInit.mStatus, statusText); nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); nsRefPtr<Response> r = new Response(global, internalResponse); if (aInit.mHeaders.WasPassed()) { internalResponse->Headers()->Clear(); // Instead of using Fill, create an object to allow the constructor to // unwrap the HeadersInit. nsRefPtr<Headers> headers = Headers::Constructor(aGlobal, aInit.mHeaders.Value(), aRv); if (aRv.Failed()) { return nullptr; } internalResponse->Headers()->Fill(*headers->GetInternalHeaders(), aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } if (aBody.WasPassed()) { nsCOMPtr<nsIInputStream> bodyStream; nsCString contentType; aRv = ExtractByteStreamFromBody(aBody.Value(), getter_AddRefs(bodyStream), contentType); internalResponse->SetBody(bodyStream); if (!contentType.IsVoid() && !internalResponse->Headers()->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) { internalResponse->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, aRv); } if (aRv.Failed()) { return nullptr; } } r->SetMimeType(aRv); return r.forget(); }
/* static */ already_AddRefed<BroadcastChannel> BroadcastChannel::Constructor(const GlobalObject& aGlobal, const nsAString& aChannel, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports()); // Window is null in workers. nsAutoString origin; PrincipalInfo principalInfo; bool privateBrowsing = false; WorkerPrivate* workerPrivate = nullptr; if (NS_IsMainThread()) { nsCOMPtr<nsIGlobalObject> incumbent = mozilla::dom::GetIncumbentGlobal(); if (!incumbent) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsIPrincipal* principal = incumbent->PrincipalOrNull(); if (!principal) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } bool isNullPrincipal; aRv = principal->GetIsNullPrincipal(&isNullPrincipal); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (NS_WARN_IF(isNullPrincipal)) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } GetOrigin(principal, origin, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } aRv = PrincipalToPrincipalInfo(principal, &principalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } nsIDocument* doc = window->GetExtantDoc(); if (doc) { privateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc); // No bfcache when BroadcastChannel is used. doc->DisallowBFCaching(); } } else { JSContext* cx = aGlobal.Context(); workerPrivate = GetWorkerPrivateFromContext(cx); MOZ_ASSERT(workerPrivate); nsRefPtr<InitializeRunnable> runnable = new InitializeRunnable(workerPrivate, origin, principalInfo, privateBrowsing, aRv); runnable->Dispatch(cx); } if (aRv.Failed()) { return nullptr; } nsRefPtr<BroadcastChannel> bc = new BroadcastChannel(window, principalInfo, origin, aChannel, privateBrowsing); // Register this component to PBackground. PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); if (actor) { bc->ActorCreated(actor); } else { BackgroundChild::GetOrCreateForCurrentThread(bc); } if (!workerPrivate) { MOZ_ASSERT(window); MOZ_ASSERT(window->IsInnerWindow()); bc->mInnerID = window->WindowID(); // Register as observer for inner-window-destroyed. nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(bc, "inner-window-destroyed", false); } } else { bc->mWorkerFeature = new BroadcastChannelFeature(bc); JSContext* cx = workerPrivate->GetJSContext(); if (NS_WARN_IF(!workerPrivate->AddFeature(cx, bc->mWorkerFeature))) { NS_WARNING("Failed to register the BroadcastChannel worker feature."); bc->mWorkerFeature = nullptr; aRv.Throw(NS_ERROR_FAILURE); return nullptr; } } return bc.forget(); }
// Automatically import functions in Module \p DestModule based on the summaries // index. // bool FunctionImporter::importFunctions( Module &DestModule, const FunctionImporter::ImportMapTy &ImportList, bool ForceImportReferencedDiscardableSymbols) { DEBUG(dbgs() << "Starting import for Module " << DestModule.getModuleIdentifier() << "\n"); unsigned ImportedCount = 0; // Linker that will be used for importing function Linker TheLinker(DestModule); // Do the actual import of functions now, one Module at a time std::set<StringRef> ModuleNameOrderedList; for (auto &FunctionsToImportPerModule : ImportList) { ModuleNameOrderedList.insert(FunctionsToImportPerModule.first()); } for (auto &Name : ModuleNameOrderedList) { // Get the module for the import const auto &FunctionsToImportPerModule = ImportList.find(Name); assert(FunctionsToImportPerModule != ImportList.end()); std::unique_ptr<Module> SrcModule = ModuleLoader(Name); assert(&DestModule.getContext() == &SrcModule->getContext() && "Context mismatch"); // If modules were created with lazy metadata loading, materialize it // now, before linking it (otherwise this will be a noop). SrcModule->materializeMetadata(); UpgradeDebugInfo(*SrcModule); auto &ImportGUIDs = FunctionsToImportPerModule->second; // Find the globals to import DenseSet<const GlobalValue *> GlobalsToImport; for (Function &F : *SrcModule) { if (!F.hasName()) continue; auto GUID = F.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing function " << GUID << " " << F.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { F.materialize(); if (EnableImportMetadata) { // Add 'thinlto_src_module' metadata for statistics and debugging. F.setMetadata( "thinlto_src_module", llvm::MDNode::get( DestModule.getContext(), {llvm::MDString::get(DestModule.getContext(), SrcModule->getSourceFileName())})); } GlobalsToImport.insert(&F); } } for (GlobalVariable &GV : SrcModule->globals()) { if (!GV.hasName()) continue; auto GUID = GV.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing global " << GUID << " " << GV.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { GV.materialize(); GlobalsToImport.insert(&GV); } } for (GlobalAlias &GA : SrcModule->aliases()) { if (!GA.hasName()) continue; auto GUID = GA.getGUID(); auto Import = ImportGUIDs.count(GUID); DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing alias " << GUID << " " << GA.getName() << " from " << SrcModule->getSourceFileName() << "\n"); if (Import) { // Alias can't point to "available_externally". However when we import // linkOnceODR the linkage does not change. So we import the alias // and aliasee only in this case. This has been handled by // computeImportForFunction() GlobalObject *GO = GA.getBaseObject(); assert(GO->hasLinkOnceODRLinkage() && "Unexpected alias to a non-linkonceODR in import list"); #ifndef NDEBUG if (!GlobalsToImport.count(GO)) DEBUG(dbgs() << " alias triggers importing aliasee " << GO->getGUID() << " " << GO->getName() << " from " << SrcModule->getSourceFileName() << "\n"); #endif GO->materialize(); GlobalsToImport.insert(GO); GA.materialize(); GlobalsToImport.insert(&GA); } } // Link in the specified functions. if (renameModuleForThinLTO(*SrcModule, Index, &GlobalsToImport)) return true; if (PrintImports) { for (const auto *GV : GlobalsToImport) dbgs() << DestModule.getSourceFileName() << ": Import " << GV->getName() << " from " << SrcModule->getSourceFileName() << "\n"; } // Instruct the linker that the client will take care of linkonce resolution unsigned Flags = Linker::Flags::None; if (!ForceImportReferencedDiscardableSymbols) Flags |= Linker::Flags::DontForceLinkLinkonceODR; if (TheLinker.linkInModule(std::move(SrcModule), Flags, &GlobalsToImport)) report_fatal_error("Function Import: link error"); ImportedCount += GlobalsToImport.size(); } NumImported += ImportedCount; DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module " << DestModule.getModuleIdentifier() << "\n"); return ImportedCount; }
bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) { // If main isn't present, claim there is no problem. if (KeepMain && !is_contained(Funcs, BD.getProgram()->getFunction("main"))) return false; // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap).release(); // Convert list to set for fast lookup... std::set<Function *> Functions; for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { Function *CMF = cast<Function>(VMap[Funcs[i]]); assert(CMF && "Function not in module?!"); assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty"); assert(CMF->getName() == Funcs[i]->getName() && "wrong name"); Functions.insert(CMF); } outs() << "Checking for crash with only these functions: "; PrintFunctionList(Funcs); outs() << ": "; if (!ReplaceFuncsWithNull) { // Loop over and delete any functions which we aren't supposed to be playing // with... for (Function &I : *M) if (!I.isDeclaration() && !Functions.count(&I)) DeleteFunctionBody(&I); } else { std::vector<GlobalValue *> ToRemove; // First, remove aliases to functions we're about to purge. for (GlobalAlias &Alias : M->aliases()) { GlobalObject *Root = Alias.getBaseObject(); Function *F = dyn_cast_or_null<Function>(Root); if (F) { if (Functions.count(F)) // We're keeping this function. continue; } else if (Root->isNullValue()) { // This referenced a globalalias that we've already replaced, // so we still need to replace this alias. } else if (!F) { // Not a function, therefore not something we mess with. continue; } PointerType *Ty = cast<PointerType>(Alias.getType()); Constant *Replacement = ConstantPointerNull::get(Ty); Alias.replaceAllUsesWith(Replacement); ToRemove.push_back(&Alias); } for (Function &I : *M) { if (!I.isDeclaration() && !Functions.count(&I)) { PointerType *Ty = cast<PointerType>(I.getType()); Constant *Replacement = ConstantPointerNull::get(Ty); I.replaceAllUsesWith(Replacement); ToRemove.push_back(&I); } } for (auto *F : ToRemove) { F->eraseFromParent(); } // Finally, remove any null members from any global intrinsic. RemoveFunctionReferences(M, "llvm.used"); RemoveFunctionReferences(M, "llvm.compiler.used"); } // Try running the hacked up program... if (TestFn(BD, M)) { BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use function pointers that point into the now-current // module. Funcs.assign(Functions.begin(), Functions.end()); return true; } delete M; return false; }
already_AddRefed<WebSocket> WebSocket::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, const Sequence<nsString>& aProtocols, ErrorResult& aRv) { if (!PrefEnabled()) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(aGlobal.GetAsSupports()); if (!scriptPrincipal) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal(); if (!principal) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobal.GetAsSupports()); if (!sgo) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aGlobal.GetAsSupports()); if (!ownerWindow) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsTArray<nsString> protocolArray; for (uint32_t index = 0, len = aProtocols.Length(); index < len; ++index) { const nsString& protocolElement = aProtocols[index]; if (protocolElement.IsEmpty()) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return nullptr; } if (protocolArray.Contains(protocolElement)) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return nullptr; } if (protocolElement.FindChar(',') != -1) /* interferes w/list */ { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return nullptr; } protocolArray.AppendElement(protocolElement); } nsRefPtr<WebSocket> webSocket = new WebSocket(ownerWindow); nsresult rv = webSocket->Init(aGlobal.Context(), principal, aUrl, protocolArray); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return webSocket.forget(); }
already_AddRefed<HTMLOptionElement> HTMLOptionElement::Option(const GlobalObject& aGlobal, const Optional<nsAString>& aText, const Optional<nsAString>& aValue, const Optional<bool>& aDefaultSelected, const Optional<bool>& aSelected, ErrorResult& aError) { nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports()); nsIDocument* doc; if (!win || !(doc = win->GetExtantDoc())) { aError.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr<nsINodeInfo> nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::option, nullptr, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE); nsRefPtr<HTMLOptionElement> option = new HTMLOptionElement(nodeInfo.forget()); if (aText.WasPassed()) { // Create a new text node and append it to the option nsRefPtr<nsTextNode> textContent = new nsTextNode(option->NodeInfo()->NodeInfoManager()); textContent->SetText(aText.Value(), false); aError = option->AppendChildTo(textContent, false); if (aError.Failed()) { return nullptr; } if (aValue.WasPassed()) { // Set the value attribute for this element. We're calling SetAttr // directly because we want to pass aNotify == false. aError = option->SetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue.Value(), false); if (aError.Failed()) { return nullptr; } if (aDefaultSelected.WasPassed()) { if (aDefaultSelected.Value()) { // We're calling SetAttr directly because we want to pass // aNotify == false. aError = option->SetAttr(kNameSpaceID_None, nsGkAtoms::selected, EmptyString(), false); if (aError.Failed()) { return nullptr; } } if (aSelected.WasPassed()) { option->SetSelected(aSelected.Value(), aError); if (aError.Failed()) { return nullptr; } } } } } return option.forget(); }
/*static*/ already_AddRefed<Response> Response::Constructor(const GlobalObject& aGlobal, const Optional<ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams>& aBody, const ResponseInit& aInit, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); if (aInit.mStatus < 200 || aInit.mStatus > 599) { aRv.ThrowRangeError(MSG_INVALID_RESPONSE_STATUSCODE_ERROR); return nullptr; } nsCString statusText; if (aInit.mStatusText.WasPassed()) { statusText = aInit.mStatusText.Value(); nsACString::const_iterator start, end; statusText.BeginReading(start); statusText.EndReading(end); if (FindCharInReadable('\r', start, end)) { aRv.ThrowTypeError(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR); return nullptr; } // Reset iterator since FindCharInReadable advances it. statusText.BeginReading(start); if (FindCharInReadable('\n', start, end)) { aRv.ThrowTypeError(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR); return nullptr; } } else { // Since we don't support default values for ByteString. statusText = NS_LITERAL_CSTRING("OK"); } nsRefPtr<InternalResponse> internalResponse = new InternalResponse(aInit.mStatus, statusText); // Grab a valid channel info from the global so this response is 'valid' for // interception. if (NS_IsMainThread()) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(global); MOZ_ASSERT(window); nsIDocument* doc = window->GetExtantDoc(); MOZ_ASSERT(doc); ChannelInfo info; info.InitFromDocument(doc); internalResponse->InitChannelInfo(info); } else { workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(worker); internalResponse->InitChannelInfo(worker->GetChannelInfo()); } nsRefPtr<Response> r = new Response(global, internalResponse); if (aInit.mHeaders.WasPassed()) { internalResponse->Headers()->Clear(); // Instead of using Fill, create an object to allow the constructor to // unwrap the HeadersInit. nsRefPtr<Headers> headers = Headers::Create(global, aInit.mHeaders.Value(), aRv); if (aRv.Failed()) { return nullptr; } internalResponse->Headers()->Fill(*headers->GetInternalHeaders(), aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } if (aBody.WasPassed()) { nsCOMPtr<nsIInputStream> bodyStream; nsCString contentType; aRv = ExtractByteStreamFromBody(aBody.Value(), getter_AddRefs(bodyStream), contentType); internalResponse->SetBody(bodyStream); if (!contentType.IsVoid() && !internalResponse->Headers()->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) { internalResponse->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, aRv); } if (aRv.Failed()) { return nullptr; } } r->SetMimeType(); return r.forget(); }
already_AddRefed<DOMMatrix> DOMMatrix::Constructor(const GlobalObject& aGlobal, const DOMMatrixReadOnly& aOther, ErrorResult& aRv) { RefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports(), aOther); return obj.forget(); }
/* static */ already_AddRefed<BroadcastChannel> BroadcastChannel::Constructor(const GlobalObject& aGlobal, const nsAString& aChannel, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports()); // Window is null in workers. nsAutoCString origin; PrincipalInfo principalInfo; WorkerPrivate* workerPrivate = nullptr; if (NS_IsMainThread()) { nsCOMPtr<nsIGlobalObject> incumbent = mozilla::dom::GetIncumbentGlobal(); if (!incumbent) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsIPrincipal* principal = incumbent->PrincipalOrNull(); if (!principal) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } aRv = principal->GetOrigin(origin); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } aRv = PrincipalToPrincipalInfo(principal, &principalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } else { JSContext* cx = aGlobal.Context(); workerPrivate = GetWorkerPrivateFromContext(cx); MOZ_ASSERT(workerPrivate); RefPtr<InitializeRunnable> runnable = new InitializeRunnable(workerPrivate, origin, principalInfo, aRv); runnable->Dispatch(Closing, aRv); } if (aRv.Failed()) { return nullptr; } RefPtr<BroadcastChannel> bc = new BroadcastChannel(window, principalInfo, origin, aChannel); // Register this component to PBackground. PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); if (actor) { bc->ActorCreated(actor); } else { BackgroundChild::GetOrCreateForCurrentThread(bc); } if (!workerPrivate) { MOZ_ASSERT(window); MOZ_ASSERT(window->IsInnerWindow()); bc->mInnerID = window->WindowID(); // Register as observer for inner-window-destroyed. nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(bc, "inner-window-destroyed", false); } } else { bc->mWorkerHolder = new BroadcastChannelWorkerHolder(bc); if (NS_WARN_IF(!bc->mWorkerHolder->HoldWorker(workerPrivate, Closing))) { bc->mWorkerHolder = nullptr; aRv.Throw(NS_ERROR_FAILURE); return nullptr; } } return bc.forget(); }
BOOL ModuleRoot::SetRootProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) { PropertyIndex index = GetRootPropertyIndex(propertyId); if (index != Constants::NoSlot) { if (this->IsWritable(propertyId) == FALSE) { JavascriptError::ThrowCantAssignIfStrictMode(flags, this->GetScriptContext()); #if ENABLE_FIXED_FIELDS if (this->IsFixedProperty(propertyId)) { PropertyValueInfo::SetNoCache(info, this); } else #endif { PropertyValueInfo::Set(info, this, index, PropertyNone); // Try to cache property info even if not writable } return FALSE; } this->SetSlot(SetSlotArgumentsRoot(propertyId, true, index, value)); #if ENABLE_FIXED_FIELDS if (this->IsFixedProperty(propertyId)) { PropertyValueInfo::SetNoCache(info, this); } else #endif { PropertyValueInfo::Set(info, this, index); } return TRUE; } else if (this->hostObject && this->hostObject->HasProperty(propertyId)) { return this->hostObject->SetProperty(propertyId, value, flags, NULL); } // // Try checking the global object // if the module root doesn't have the property and the host object also doesn't have it // GlobalObject* globalObj = this->GetLibrary()->GetGlobalObject(); BOOL setAttempted = TRUE; if (globalObj->SetExistingRootProperty(propertyId, value, NULL, &setAttempted)) { return TRUE; } // // Set was attempted. But the set operation returned false. // This happens, when the property is read only. // In those scenarios, we should be setting the property with default attributes // if (setAttempted) { return FALSE; } return __super::SetRootProperty(propertyId, value, (PropertyOperationFlags)(flags | PropertyOperation_NonFixedValue), info); }
static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments) { GlobalObject* object = new (allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure); object->finishCreation(globalData, arguments); return object; }
already_AddRefed<DOMMatrix> DOMMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { nsRefPtr<DOMMatrix> obj = new DOMMatrix(aGlobal.GetAsSupports()); return obj.forget(); }
/* static */ already_AddRefed<VRSubmitFrameResult> VRSubmitFrameResult::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { RefPtr<VRSubmitFrameResult> obj = new VRSubmitFrameResult(aGlobal.GetAsSupports()); return obj.forget(); }