Firefox · DOM
CVE-2026-117956
Logic Error in DOM
Overview
Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
dom/chrome-webidl/Nimbus.webidldom/chrome-webidl/moz.buildtoolkit/components/nimbus/lib/NimbusFeatures.cpp
Patch
diff --git a/dom/chrome-webidl/Nimbus.webidl b/dom/chrome-webidl/Nimbus.webidl
new file mode 100644
index 00000000000..85a3c350451
--- /dev/null
+++ b/dom/chrome-webidl/Nimbus.webidl
@@ -0,0 +1,31 @@
+/* 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/.
+ */
+
+/**
+ * Cached metadata about an active Nimbus experiment or rollout.
+ *
+ * This metadata is stored inside prefs of the form `nimbus.syncdatastore.*` and
+ * `nimbus.syncdefaultsstore.*` by ExperimentStore.sys.mjs for a subset of
+ * features that require either:
+ * - being accessible from platform code, or
+ * - being read very early in startup, before Nimbus has fully initialized.
+ */
+[GenerateInitFromJSON]
+dictionary CachedNimbusExperimentMetadata {
+ /** The experiment slug. */
+ required UTF8String slug;
+
+ /** The active branch. */
+ required CachedNimbusExperimentBranch branch;
+};
+
+/**
+ * Cached metadata about the active branch of an experiment or rollout.
+ */
+[GenerateInitFromJSON]
+dictionary CachedNimbusExperimentBranch {
+ /** The slug of the active branch. */
+ required UTF8String slug;
+};
diff --git a/dom/chrome-webidl/moz.build b/dom/chrome-webidl/moz.build
index b8a31d66125..ab69b1a0bd9 100644
--- a/dom/chrome-webidl/moz.build
+++ b/dom/chrome-webidl/moz.build
@@ -23,6 +23,9 @@ with Files("MatchGlob.webidl"):
with Files("MatchPattern.webidl"):
BUG_COMPONENT = ("WebExtensions", "General")
+with Files("Nimbus.webidl"):
+ BUG_COMPONENT = ("Firefox", "Nimbus Desktop Client")
+
with Files("WebExtension*.webidl"):
BUG_COMPONENT = ("WebExtensions", "General")
@@ -83,6 +86,7 @@ WEBIDL_FILES = [
"MozStorageStatementParams.webidl",
"MozStorageStatementRow.webidl",
"NetDashboard.webidl",
+ "Nimbus.webidl",
"OriginAttributes.webidl",
"PathUtils.webidl",
"PermissionSetParameters.webidl",
diff --git a/toolkit/components/nimbus/lib/NimbusFeatures.cpp b/toolkit/components/nimbus/lib/NimbusFeatures.cpp
index ddafe50fee0..5cc67e0a9c3 100644
--- a/toolkit/components/nimbus/lib/NimbusFeatures.cpp
+++ b/toolkit/components/nimbus/lib/NimbusFeatures.cpp
@@ -4,12 +4,9 @@
#include "mozilla/browser/NimbusFeatures.h"
#include "mozilla/browser/NimbusFeatureManifest.h"
+#include "mozilla/dom/NimbusBinding.h"
#include "mozilla/Try.h"
-#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/glean/NimbusMetrics.h"
-#include "jsapi.h"
-#include "js/JSON.h"
-#include "nsJSUtils.h"
#include "nsPrintfCString.h"
namespace mozilla {
@@ -207,44 +204,25 @@ nsresult NimbusFeatures::OffUpdate(const nsACString& aFeatureId,
nsresult GetExperimentSlug(const nsACString& aFeatureId,
nsACString& aExperimentSlug,
nsACString& aBranchSlug) {
- nsAutoCString prefName;
- nsAutoString prefValue;
-
aExperimentSlug.Truncate();
aBranchSlug.Truncate();
+ nsAutoCString prefName;
GetNimbusPrefName(kSyncDataPrefBranch, aFeatureId, EmptyCString(), prefName);
+
+ nsAutoString prefValue;
MOZ_TRY(Preferences::GetString(prefName.get(), prefValue));
if (prefValue.IsEmpty()) {
return NS_ERROR_UNEXPECTED;
}
- dom::AutoJSAPI jsapi;
- if (!jsapi.Init(xpc::PrivilegedJunkScope())) {
+
+ dom::CachedNimbusExperimentMetadata meta;
+ if (!meta.Init(prefValue)) {
return NS_ERROR_UNEXPECTED;
}
- JSContext* cx = jsapi.cx();
- JS::Rooted<JS::Value> json(cx, JS::NullValue());
- if (JS_ParseJSON(cx, prefValue.BeginReading(), prefValue.Length(), &json) &&
- json.isObject()) {
- JS::Rooted<JSObject*> experimentJSON(cx, json.toObjectOrNull());
- JS::Rooted<JS::Value> expSlugValue(cx);
- if (!JS_GetProperty(cx, experimentJSON, "slug", &expSlugValue)) {
- return NS_ERROR_UNEXPECTED;
- }
- AssignJSString(cx, aExperimentSlug, expSlugValue.toString());
- JS::Rooted<JS::Value> branchJSON(cx);
- if (!JS_GetProperty(cx, experimentJSON, "branch", &branchJSON) &&
- !branchJSON.isObject()) {
- return NS_ERROR_UNEXPECTED;
- }
- JS::Rooted<JSObject*> branchObj(cx, branchJSON.toObjectOrNull());
- JS::Rooted<JS::Value> branchSlugValue(cx);
- if (!JS_GetProperty(cx, branchObj, "slug", &branchSlugValue)) {
- return NS_ERROR_UNEXPECTED;
- }
- AssignJSString(cx, aBranchSlug, branchSlugValue.toString());
- }
+ aExperimentSlug.Assign(std::move(meta.mSlug));
+ aBranchSlug.Assign(std::move(meta.mBranch.mSlug));
return NS_OK;
}
Loading diff…
References
On This Page