Firefox · Widget
CVE-2026-100757
Logic Error in Widget
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifwidget/cocoa/nsColorPicker.mm |
modified | |
ifwidget/gtk/nsApplicationChooser.cpp |
modified | |
switchwidget/gtk/nsApplicationChooser.cpp |
modified | |
ifwidget/gtk/nsColorPicker.cpp |
modified | |
switchwidget/gtk/nsColorPicker.cpp |
modified | |
ifwidget/gtk/nsFilePicker.cpp |
modified | |
ifwidget/nsFilePickerProxy.cpp |
modified |
Files Changed
widget/cocoa/nsColorPicker.mmwidget/gtk/nsApplicationChooser.cppwidget/gtk/nsColorPicker.cppwidget/gtk/nsFilePicker.cppwidget/gtk/nsFilePicker.hwidget/nsFilePickerProxy.cpp
Patch
diff --git a/widget/cocoa/nsColorPicker.mm b/widget/cocoa/nsColorPicker.mm
index 92ff6c7da8f..cb54c1cc143 100644
--- a/widget/cocoa/nsColorPicker.mm
+++ b/widget/cocoa/nsColorPicker.mm
@@ -4,6 +4,8 @@
#import <Cocoa/Cocoa.h>
+#include <utility>
+
#include "nsCocoaUtils.h"
#include "nsColorPicker.h"
#include "nsThreadUtils.h"
@@ -158,14 +160,22 @@ nsresult nsColorPicker::OpenNative() {
void nsColorPicker::Update(NSColor* aColor) {
GetHexStringFromNSColor(aColor, mInitialColor);
- mCallback->Update(mInitialColor);
+ if (mCallback) {
+ mCallback->Update(mInitialColor);
+ }
}
void nsColorPicker::Done() {
+ // A null callback means a re-entrant call; the outer one owns the teardown.
+ nsCOMPtr<nsIColorPickerShownCallback> callback = std::move(mCallback);
+ if (!callback) {
+ return;
+ }
+
[mColorPanelWrapper close];
[mColorPanelWrapper release];
mColorPanelWrapper = nullptr;
- mCallback->Done(u""_ns);
- mCallback = nullptr;
+
+ callback->Done(u""_ns);
NS_RELEASE_THIS();
}
diff --git a/widget/gtk/nsApplicationChooser.cpp b/widget/gtk/nsApplicationChooser.cpp
index 67ccd8448e3..4976f4f3d61 100644
--- a/widget/gtk/nsApplicationChooser.cpp
+++ b/widget/gtk/nsApplicationChooser.cpp
@@ -7,6 +7,8 @@
#include <gio/gdesktopappinfo.h>
#include <gtk/gtk.h>
+#include <utility>
+
#include "WidgetUtils.h"
#include "mozilla/GRefPtr.h"
#include "nsCExternalHandlerService.h"
@@ -75,6 +77,13 @@ void nsApplicationChooser::OnDestroy(GtkWidget* chooser, gpointer user_data) {
}
void nsApplicationChooser::Done(GtkWidget* chooser, gint response) {
+ // A null callback means a re-entrant call; the outer one owns the teardown.
+ nsCOMPtr<nsIApplicationChooserFinishedCallback> callback =
+ std::move(mCallback);
+ if (!callback) {
+ return;
+ }
+
nsCOMPtr<nsIGIOHandlerApp> gioHandler;
switch (response) {
case GTK_RESPONSE_OK:
@@ -105,9 +114,6 @@ void nsApplicationChooser::Done(GtkWidget* chooser, gint response) {
this);
gtk_widget_destroy(chooser);
- if (mCallback) {
- mCallback->Done(gioHandler);
- mCallback = nullptr;
- }
+ callback->Done(gioHandler);
NS_RELEASE_THIS();
}
diff --git a/widget/gtk/nsColorPicker.cpp b/widget/gtk/nsColorPicker.cpp
index 9e957e78779..40acb970f80 100644
--- a/widget/gtk/nsColorPicker.cpp
+++ b/widget/gtk/nsColorPicker.cpp
@@ -4,6 +4,8 @@
#include <gtk/gtk.h>
+#include <utility>
+
#ifdef MOZ_X11
# include "X11UndefineNone.h"
#endif
@@ -206,6 +208,12 @@ void nsColorPicker::OnDestroy(GtkWidget* color_chooser, gpointer user_data) {
}
void nsColorPicker::Done(GtkWidget* color_chooser, gint response) {
+ // A null callback means a re-entrant call; the outer one owns the teardown.
+ nsCOMPtr<nsIColorPickerShownCallback> callback = std::move(mCallback);
+ if (!callback) {
+ return;
+ }
+
switch (response) {
case GTK_RESPONSE_OK:
case GTK_RESPONSE_ACCEPT:
@@ -232,10 +240,8 @@ void nsColorPicker::Done(GtkWidget* color_chooser, gint response) {
this);
gtk_widget_destroy(color_chooser);
- if (mCallback) {
- mCallback->Done(mColor);
- mCallback = nullptr;
- }
+
+ callback->Done(mColor);
NS_RELEASE_THIS();
}
diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
index f3e30bee0ad..b6bcca3e0e2 100644
--- a/widget/gtk/nsFilePicker.cpp
+++ b/widget/gtk/nsFilePicker.cpp
@@ -10,6 +10,8 @@
#include <sys/types.h>
#include <unistd.h>
+#include <utility>
+
#include "AsyncDBus.h"
#include "GRefPtr.h"
#include "MozContainer.h"
@@ -664,7 +666,7 @@ void nsFilePicker::DonePortal(GVariant* aResult) {
}
ClearPortalState();
- DoneCommon(result);
+ DoneCommon(result, std::move(mCallback));
}
#endif
@@ -878,6 +880,12 @@ void nsFilePicker::DoneNonPortal(GtkWidget* file_chooser, gint response) {
return;
}
+ // A null callback means a re-entrant call; the outer one owns the teardown.
+ nsCOMPtr<nsIFilePickerShownCallback> callback = std::move(mCallback);
+ if (!callback) {
+ return;
+ }
+
mFileChooser = nullptr;
nsIFilePicker::ResultCode result;
@@ -927,11 +935,12 @@ void nsFilePicker::DoneNonPortal(GtkWidget* file_chooser, gint response) {
mFileChooserDelegate = nullptr;
}
- DoneCommon(result);
+ DoneCommon(result, std::move(callback));
NS_RELEASE_THIS();
}
-void nsFilePicker::DoneCommon(ResultCode aResult) {
+void nsFilePicker::DoneCommon(ResultCode aResult,
+ nsCOMPtr<nsIFilePickerShownCallback> aCallback) {
if (aResult == ResultCode::returnOK) {
if (mMode == nsIFilePicker::modeSave) {
nsCOMPtr<nsIFile> file;
@@ -961,9 +970,8 @@ void nsFilePicker::DoneCommon(ResultCode aResult) {
}
}
- if (mCallback) {
- mCallback->Done(aResult);
- mCallback = nullptr;
+ if (aCallback) {
+ aCallback->Done(aResult);
}
}
diff --git a/widget/gtk/nsFilePicker.h b/widget/gtk/nsFilePicker.h
index 492ad69cccc..dcd43efcfbe 100644
--- a/widget/gtk/nsFilePicker.h
+++ b/widget/gtk/nsFilePicker.h
@@ -67,7 +67,7 @@ class nsFilePicker final : public nsBaseFilePicker {
void ClearPortalState();
#endif
- void DoneCommon(ResultCode);
+ void DoneCommon(ResultCode, nsCOMPtr<nsIFilePickerShownCallback>);
RefPtr<nsWindow> mParentWidget;
nsCOMPtr<nsIFilePickerShownCallback> mCallback;
diff --git a/widget/nsFilePickerProxy.cpp b/widget/nsFilePickerProxy.cpp
index de61340a472..4194642853e 100644
--- a/widget/nsFilePickerProxy.cpp
+++ b/widget/nsFilePickerProxy.cpp
@@ -5,6 +5,8 @@
#include "nsFilePickerProxy.h"
+#include <utility>
+
#include "mozilla/dom/BlobImpl.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/BrowsingContext.h"
@@ -203,9 +205,8 @@ mozilla::ipc::IPCResult nsFilePickerProxy::Recv__delete__(
}
}
- if (mCallback) {
- mCallback->Done(aResult);
- mCallback = nullptr;
+ if (nsCOMPtr<nsIFilePickerShownCallback> callback = std::move(mCallback)) {
+ callback->Done(aResult);
}
return IPC_OK();
@@ -284,9 +285,8 @@ nsFilePickerProxy::GetDomFileOrDirectoryEnumerator(
void nsFilePickerProxy::ActorDestroy(ActorDestroyReason aWhy) {
mIPCActive = false;
- if (mCallback) {
- mCallback->Done(nsIFilePicker::returnCancel);
- mCallback = nullptr;
+ if (nsCOMPtr<nsIFilePickerShownCallback> callback = std::move(mCallback)) {
+ callback->Done(nsIFilePicker::returnCancel);
}
}
Loading diff…
References
On This Page