summaryrefslogtreecommitdiffstats
path: root/js/public/Principals.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/public/Principals.h')
-rw-r--r--js/public/Principals.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/js/public/Principals.h b/js/public/Principals.h
new file mode 100644
index 0000000000..609b1ecff6
--- /dev/null
+++ b/js/public/Principals.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* JSPrincipals and related interfaces. */
+
+#ifndef js_Principals_h
+#define js_Principals_h
+
+#include "mozilla/Atomics.h"
+
+#include <stdint.h>
+
+#include "jstypes.h"
+
+#include "js/TypeDecls.h"
+
+struct JSStructuredCloneReader;
+struct JSStructuredCloneWriter;
+
+struct JSPrincipals {
+ /* Don't call "destroy"; use reference counting macros below. */
+ mozilla::Atomic<int32_t, mozilla::SequentiallyConsistent> refcount{0};
+
+#ifdef JS_DEBUG
+ /* A helper to facilitate principals debugging. */
+ uint32_t debugToken;
+#endif
+
+ JSPrincipals() = default;
+
+ void setDebugToken(uint32_t token) {
+#ifdef JS_DEBUG
+ debugToken = token;
+#endif
+ }
+
+ /*
+ * Write the principals with the given |writer|. Return false on failure,
+ * true on success.
+ */
+ virtual bool write(JSContext* cx, JSStructuredCloneWriter* writer) = 0;
+
+ /*
+ * Whether the principal corresponds to a System or AddOn Principal.
+ * Technically this also checks for an ExpandedAddonPrincipal.
+ */
+ virtual bool isSystemOrAddonPrincipal() = 0;
+
+ /*
+ * This is not defined by the JS engine but should be provided by the
+ * embedding.
+ */
+ JS_PUBLIC_API void dump();
+};
+
+extern JS_PUBLIC_API void JS_HoldPrincipals(JSPrincipals* principals);
+
+extern JS_PUBLIC_API void JS_DropPrincipals(JSContext* cx,
+ JSPrincipals* principals);
+
+// Return whether the first principal subsumes the second. The exact meaning of
+// 'subsumes' is left up to the browser. Subsumption is checked inside the JS
+// engine when determining, e.g., which stack frames to display in a backtrace.
+typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second);
+
+namespace JS {
+enum class RuntimeCode { JS, WASM };
+} // namespace JS
+
+/*
+ * Used to check if a CSP instance wants to disable eval() and friends.
+ * See JSContext::isRuntimeCodeGenEnabled() in vm/JSContext.cpp.
+ *
+ * `code` is the JavaScript source code passed to eval/Function, but nullptr
+ * for Wasm.
+ *
+ * Returning `false` from this callback will prevent the execution/compilation
+ * of the code.
+ */
+typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::RuntimeCode kind,
+ JS::HandleString code);
+
+struct JSSecurityCallbacks {
+ JSCSPEvalChecker contentSecurityPolicyAllows;
+ JSSubsumesOp subsumes;
+};
+
+extern JS_PUBLIC_API void JS_SetSecurityCallbacks(
+ JSContext* cx, const JSSecurityCallbacks* callbacks);
+
+extern JS_PUBLIC_API const JSSecurityCallbacks* JS_GetSecurityCallbacks(
+ JSContext* cx);
+
+/*
+ * Code running with "trusted" principals will be given a deeper stack
+ * allocation than ordinary scripts. This allows trusted script to run after
+ * untrusted script has exhausted the stack. This function sets the
+ * runtime-wide trusted principal.
+ *
+ * This principals is not held (via JS_HoldPrincipals/JS_DropPrincipals).
+ * Instead, the caller must ensure that the given principals stays valid for as
+ * long as 'cx' may point to it. If the principals would be destroyed before
+ * 'cx', JS_SetTrustedPrincipals must be called again, passing nullptr for
+ * 'prin'.
+ */
+extern JS_PUBLIC_API void JS_SetTrustedPrincipals(JSContext* cx,
+ JSPrincipals* prin);
+
+typedef void (*JSDestroyPrincipalsOp)(JSPrincipals* principals);
+
+/*
+ * Initialize the callback that is called to destroy JSPrincipals instance
+ * when its reference counter drops to zero. The initialization can be done
+ * only once per JS runtime.
+ */
+extern JS_PUBLIC_API void JS_InitDestroyPrincipalsCallback(
+ JSContext* cx, JSDestroyPrincipalsOp destroyPrincipals);
+
+/*
+ * Read a JSPrincipals instance from the given |reader| and initialize the out
+ * paratemer |outPrincipals| to the JSPrincipals instance read.
+ *
+ * Return false on failure, true on success. The |outPrincipals| parameter
+ * should not be modified if false is returned.
+ *
+ * The caller is not responsible for calling JS_HoldPrincipals on the resulting
+ * JSPrincipals instance, the JSReadPrincipalsOp must increment the refcount of
+ * the resulting JSPrincipals on behalf of the caller.
+ */
+using JSReadPrincipalsOp = bool (*)(JSContext* cx,
+ JSStructuredCloneReader* reader,
+ JSPrincipals** outPrincipals);
+
+/*
+ * Initialize the callback that is called to read JSPrincipals instances from a
+ * buffer. The initialization can be done only once per JS runtime.
+ */
+extern JS_PUBLIC_API void JS_InitReadPrincipalsCallback(
+ JSContext* cx, JSReadPrincipalsOp read);
+
+namespace JS {
+
+class MOZ_RAII AutoHoldPrincipals {
+ JSContext* cx_;
+ JSPrincipals* principals_ = nullptr;
+
+ public:
+ explicit AutoHoldPrincipals(JSContext* cx, JSPrincipals* principals = nullptr)
+ : cx_(cx) {
+ reset(principals);
+ }
+
+ ~AutoHoldPrincipals() { reset(nullptr); }
+
+ void reset(JSPrincipals* principals) {
+ if (principals) {
+ JS_HoldPrincipals(principals);
+ }
+ if (principals_) {
+ JS_DropPrincipals(cx_, principals_);
+ }
+ principals_ = principals;
+ }
+
+ JSPrincipals* get() const { return principals_; }
+};
+
+} // namespace JS
+
+#endif /* js_Principals_h */