Firefox · DOM
CVE-2026-74965
Logic Error in DOM
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
forwidget/windows/JumpListBuilder.cpp |
modified | |
ifwidget/windows/tests/gtest/TestJumpListBuilder.cpp |
modified |
Files Changed
browser/modules/WindowsJumpLists.sys.mjsdom/chrome-webidl/WindowsJumpListShortcutDescription.webidlwidget/windows/JumpListBuilder.cppwidget/windows/tests/gtest/TestJumpListBuilder.cpp
Patch
diff --git a/browser/modules/WindowsJumpLists.sys.mjs b/browser/modules/WindowsJumpLists.sys.mjs
index 18d6fb85be4..5ddca6c3776 100644
--- a/browser/modules/WindowsJumpLists.sys.mjs
+++ b/browser/modules/WindowsJumpLists.sys.mjs
@@ -93,7 +93,7 @@ var tasksCfg = [
get description() {
return _getString("taskbar.tasks.newTab.description");
},
- args: "-new-tab about:blank",
+ args: ["-new-tab", "about:blank"],
iconIndex: 3, // New window icon
open: true,
close: true, // The jump list already has an app launch icon, but
@@ -109,7 +109,7 @@ var tasksCfg = [
get description() {
return _getString("taskbar.tasks.newWindow.description");
},
- args: "-browser",
+ args: ["-browser"],
iconIndex: 2, // New tab icon
open: true,
close: true, // No point, but we don't always update the list on
@@ -125,7 +125,7 @@ let privateWindowTask = {
get description() {
return _getString("taskbar.tasks.newPrivateWindow.description");
},
- args: "-private-window",
+ args: ["-private-window"],
iconIndex: 4, // Private browsing mode icon
open: true,
close: true, // No point, but we don't always update the list on
@@ -267,7 +267,7 @@ var Builder = class {
title: row.getResultByName("title"),
description: row.getResultByName("title"),
path: selfPath,
- arguments: row.getResultByName("url"),
+ arguments: ["-osint", "-url", row.getResultByName("url")],
fallbackIconIndex: 1,
iconPath,
});
diff --git a/dom/chrome-webidl/WindowsJumpListShortcutDescription.webidl b/dom/chrome-webidl/WindowsJumpListShortcutDescription.webidl
index d32eb6c61be..73767c84ac6 100644
--- a/dom/chrome-webidl/WindowsJumpListShortcutDescription.webidl
+++ b/dom/chrome-webidl/WindowsJumpListShortcutDescription.webidl
@@ -27,7 +27,7 @@ dictionary WindowsJumpListShortcutDescription {
* Arguments to be supplied to the executable when the item is selected in
* the Jump List.
*/
- DOMString arguments;
+ sequence<DOMString> arguments;
/**
* A description of the item that is displayed as a tooltip.
diff --git a/widget/windows/JumpListBuilder.cpp b/widget/windows/JumpListBuilder.cpp
index 02e5f7a0d3b..121e69236c5 100644
--- a/widget/windows/JumpListBuilder.cpp
+++ b/widget/windows/JumpListBuilder.cpp
@@ -13,6 +13,7 @@
// clang-format on
#include "WinUtils.h"
+#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WindowsJumpListShortcutDescriptionBinding.h"
@@ -876,10 +877,20 @@ nsresult JumpListBuilder::GetShellLinkFromDescription(
hr = psl->SetDescription(descriptionCopy.get());
- if (aDesc.mArguments.WasPassed() && !aDesc.mArguments.Value().IsEmpty()) {
- hr = psl->SetArguments(aDesc.mArguments.Value().get());
- } else {
- hr = psl->SetArguments(L"");
+ if (aDesc.mArguments.WasPassed()) {
+ const mozilla::dom::Sequence<nsString>& arguments =
+ aDesc.mArguments.Value();
+
+ // MakeCommandLine expects wchar_t**, but we have Sequence<nsString>, so
+ // convert it over.
+ AutoTArray<const wchar_t*, 8> flatArgs;
+ for (const nsString& arg : arguments) {
+ flatArgs.AppendElement(arg.get());
+ }
+
+ UniquePtr<wchar_t[]> commandLine = mozilla::MakeCommandLine(
+ AssertedCast<int>(flatArgs.Length()), flatArgs.Elements());
+ hr = psl->SetArguments(commandLine.get());
}
// Set up the fallback icon in the event that a valid icon URI has
diff --git a/widget/windows/tests/gtest/TestJumpListBuilder.cpp b/widget/windows/tests/gtest/TestJumpListBuilder.cpp
index a46eb4e5051..d6dd8208fce 100644
--- a/widget/windows/tests/gtest/TestJumpListBuilder.cpp
+++ b/widget/windows/tests/gtest/TestJumpListBuilder.cpp
@@ -17,6 +17,7 @@ PSSTDAPI PropVariantToString(REFPROPVARIANT propvar, PWSTR psz, UINT cch);
#include "JumpListBuilder.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Promise.h"
@@ -113,7 +114,17 @@ MATCHER_P(ShellLinksEq, descs,
}
if (desc.mArguments.WasPassed()) {
- if (!desc.mArguments.Value().Equals(argsBuf)) {
+ mozilla::CommandLineParserWin<char16_t> parser;
+ parser.HandleCommandLine(nsDependentString(argsBuf));
+
+ const mozilla::dom::Sequence<nsString>& args = desc.mArguments.Value();
+
+ bool same = std::equal(
+ parser.Argv(), parser.Argv() + parser.Argc(), args.cbegin(),
+ args.cend(), [](const char16_t* aParsed, const nsAString& aExpected) {
+ return aExpected == nsDependentString(aParsed);
+ });
+ if (!same) {
return false;
}
} else {
@@ -310,8 +321,8 @@ void GenerateWindowsJumpListShortcutDescriptions(
desc.mFallbackIconIndex = 0;
if (!(i % 2)) {
- nsAutoString arguments(u"-arg1 -arg2 -arg3");
- desc.mArguments.Construct(arguments);
+ desc.mArguments.Construct(nsTArray<nsString>{
+ u"-arg1"_ns, u"argument with a space"_ns, u"-arg3"_ns});
nsAutoString iconPath(u"C:\\Some\\icon.png");
desc.mIconPath.Construct(iconPath);
}
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/widget/windows/tests/gtest/TestJumpListBuilder.cpp b/widget/windows/tests/gtest/TestJumpListBuilder.cpp
index a46eb4e5051..d6dd8208fce 100644
--- a/widget/windows/tests/gtest/TestJumpListBuilder.cpp
+++ b/widget/windows/tests/gtest/TestJumpListBuilder.cpp
@@ -17,6 +17,7 @@ PSSTDAPI PropVariantToString(REFPROPVARIANT propvar, PWSTR psz, UINT cch);
#include "JumpListBuilder.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Promise.h"
@@ -113,7 +114,17 @@ MATCHER_P(ShellLinksEq, descs,
}
if (desc.mArguments.WasPassed()) {
- if (!desc.mArguments.Value().Equals(argsBuf)) {
+ mozilla::CommandLineParserWin<char16_t> parser;
+ parser.HandleCommandLine(nsDependentString(argsBuf));
+
+ const mozilla::dom::Sequence<nsString>& args = desc.mArguments.Value();
+
+ bool same = std::equal(
+ parser.Argv(), parser.Argv() + parser.Argc(), args.cbegin(),
+ args.cend(), [](const char16_t* aParsed, const nsAString& aExpected) {
+ return aExpected == nsDependentString(aParsed);
+ });
+ if (!same) {
return false;
}
} else {
@@ -310,8 +321,8 @@ void GenerateWindowsJumpListShortcutDescriptions(
desc.mFallbackIconIndex = 0;
if (!(i % 2)) {
- nsAutoString arguments(u"-arg1 -arg2 -arg3");
- desc.mArguments.Construct(arguments);
+ desc.mArguments.Construct(nsTArray<nsString>{
+ u"-arg1"_ns, u"argument with a space"_ns, u"-arg3"_ns});
nsAutoString iconPath(u"C:\\Some\\icon.png");
desc.mIconPath.Construct(iconPath);
}
Loading diff…
References
On This Page