TrustedTypePolicy.cpp (4064B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/TrustedTypePolicy.h" 8 9 #include <utility> 10 11 #include "mozilla/dom/DOMString.h" 12 #include "mozilla/dom/TrustedTypePolicyFactory.h" 13 #include "mozilla/dom/TrustedTypesBinding.h" 14 15 namespace mozilla::dom { 16 17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TrustedTypePolicy, mParentObject, 18 mOptions.mCreateHTMLCallback, 19 mOptions.mCreateScriptCallback, 20 mOptions.mCreateScriptURLCallback) 21 22 TrustedTypePolicy::TrustedTypePolicy(TrustedTypePolicyFactory* aParentObject, 23 const nsAString& aName, Options&& aOptions) 24 : mParentObject{aParentObject}, 25 mName{aName}, 26 mOptions{std::move(aOptions)} {} 27 28 JSObject* TrustedTypePolicy::WrapObject(JSContext* aCx, 29 JS::Handle<JSObject*> aGivenProto) { 30 return TrustedTypePolicy_Binding::Wrap(aCx, this, aGivenProto); 31 } 32 33 void TrustedTypePolicy::GetName(DOMString& aResult) const { 34 aResult.SetKnownLiveString(mName); 35 } 36 37 #define IMPL_CREATE_TRUSTED_TYPE(_trustedTypeSuffix) \ 38 already_AddRefed<Trusted##_trustedTypeSuffix> \ 39 TrustedTypePolicy::Create##_trustedTypeSuffix( \ 40 JSContext* aJSContext, const nsAString& aInput, \ 41 const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) \ 42 const { \ 43 /* Invoking the callback could delete the policy and hence the callback. \ 44 * Hence keep a strong reference to it on the stack. \ 45 */ \ 46 RefPtr<Create##_trustedTypeSuffix##Callback> callbackObject = \ 47 mOptions.mCreate##_trustedTypeSuffix##Callback; \ 48 \ 49 return CreateTrustedType<Trusted##_trustedTypeSuffix>( \ 50 callbackObject, aInput, aArguments, aErrorResult); \ 51 } 52 53 IMPL_CREATE_TRUSTED_TYPE(HTML) 54 IMPL_CREATE_TRUSTED_TYPE(Script) 55 IMPL_CREATE_TRUSTED_TYPE(ScriptURL) 56 57 template <typename T, typename CallbackObject> 58 already_AddRefed<T> TrustedTypePolicy::CreateTrustedType( 59 const RefPtr<CallbackObject>& aCallbackObject, const nsAString& aValue, 60 const Sequence<JS::Value>& aArguments, ErrorResult& aErrorResult) const { 61 nsString policyValue; 62 DetermineTrustedPolicyValue(aCallbackObject, aValue, aArguments, true, 63 aErrorResult, policyValue); 64 65 if (aErrorResult.Failed()) { 66 return nullptr; 67 } 68 69 if (policyValue.IsVoid()) { 70 policyValue = EmptyString(); 71 } 72 73 RefPtr<T> trustedObject = new T(std::move(policyValue)); 74 75 // TODO: add special handling for `TrustedScript` when default policy support 76 // is added. 77 78 return trustedObject.forget(); 79 } 80 81 template <typename CallbackObject> 82 void TrustedTypePolicy::DetermineTrustedPolicyValue( 83 const RefPtr<CallbackObject>& aCallbackObject, const nsAString& aValue, 84 const nsTArray<JS::Value>& aArguments, bool aThrowIfMissing, 85 ErrorResult& aErrorResult, nsAString& aResult) const { 86 if (!aCallbackObject) { 87 aResult.SetIsVoid(true); 88 89 if (aThrowIfMissing) { 90 aErrorResult.ThrowTypeError("Function missing."); 91 } 92 93 return; 94 } 95 96 nsString callbackResult; 97 aCallbackObject->Call(aValue, aArguments, callbackResult, aErrorResult, 98 nullptr, CallbackObject::eRethrowExceptions); 99 100 if (!aErrorResult.Failed()) { 101 aResult = std::move(callbackResult); 102 } 103 } 104 105 } // namespace mozilla::dom