Commits:
-
19837410
by James Teh at 2026-09-27T15:56:21+02:00
Bug 2056767: Shut down DocAccessibleParents before we shut down platform accessibility. a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D322228
Differential Revision: https://phabricator.services.mozilla.com/D323108
-
eca99650
by Rob Wu at 2026-09-27T17:19:00+02:00
Bug 2061470 - Don't drop __proto__ from webRequest bodies r=rpl
Differential Revision: https://phabricator.services.mozilla.com/D323631
-
bddd4de4
by Marco Bonardo at 2026-09-27T17:30:36+02:00
Bug 2066019. a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D321246
Differential Revision: https://phabricator.services.mozilla.com/D323563
-
e8ce3fe3
by Tom Schuster at 2026-09-27T17:32:19+02:00
Bug 2066321 - Update nonceable attribute checks for link elements. r=freddyb
Pending PR: https://github.com/w3c/webappsec-csp/pull/810
Differential Revision: https://phabricator.services.mozilla.com/D322966
-
5fd1f7de
by Leo Tenenbaum at 2026-09-27T17:41:10+02:00
Bug 2067172 - a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D321879
Differential Revision: https://phabricator.services.mozilla.com/D322306
-
43f705a3
by Iain Ireland at 2026-09-27T18:23:46+02:00
Bug 2068385: Fix PBL a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D323744
Differential Revision: https://phabricator.services.mozilla.com/D324712
-
b6746e50
by Iain Ireland at 2026-09-28T10:08:52+02:00
Bug 2068385: Don't support sparse arrays in SpreadMathMinMax a=pascalc
Marking the testcase --slow because it takes 7+ minutes on my laptop in an opt-debug build.
Original Revision: https://phabricator.services.mozilla.com/D323120
Differential Revision: https://phabricator.services.mozilla.com/D324692
14 changed files:
Changes:
accessible/base/DocManager.cpp
| ... |
... |
@@ -31,6 +31,10 @@ |
|
31
|
31
|
#include "nsCoreUtils.h"
|
|
32
|
32
|
#include "xpcAccessibleDocument.h"
|
|
33
|
33
|
|
|
|
34
|
+#if defined(ANDROID)
|
|
|
35
|
+# include "mozilla/Monitor.h"
|
|
|
36
|
+#endif
|
|
|
37
|
+
|
|
34
|
38
|
using namespace mozilla;
|
|
35
|
39
|
using namespace mozilla::a11y;
|
|
36
|
40
|
using namespace mozilla::dom;
|
| ... |
... |
@@ -195,6 +199,18 @@ void DocManager::Shutdown() { |
|
195
|
199
|
}
|
|
196
|
200
|
|
|
197
|
201
|
ClearDocCache();
|
|
|
202
|
+ // Even though remote documents aren't strictly managed by this DocManager
|
|
|
203
|
+ // instance, destroy them now because they might depend on platform specific
|
|
|
204
|
+ // state which is about to be torn down by PlatformShutdown. Iterate the array
|
|
|
205
|
+ // backwards because destroying the document removes it from this array.
|
|
|
206
|
+ if (sRemoteDocuments) {
|
|
|
207
|
+#if defined(ANDROID)
|
|
|
208
|
+ MonitorAutoLock mal(nsAccessibilityService::GetAndroidMonitor());
|
|
|
209
|
+#endif
|
|
|
210
|
+ for (size_t i = sRemoteDocuments->Length(); i-- > 0;) {
|
|
|
211
|
+ (*sRemoteDocuments)[i]->Destroy();
|
|
|
212
|
+ }
|
|
|
213
|
+ }
|
|
198
|
214
|
}
|
|
199
|
215
|
|
|
200
|
216
|
////////////////////////////////////////////////////////////////////////////////
|
accessible/ipc/DocAccessibleParent.cpp
| ... |
... |
@@ -1241,15 +1241,14 @@ void DocAccessibleParent::MaybeInitWindowEmulation() { |
|
1241
|
1241
|
isActive = browserParent->GetDocShellIsActive();
|
|
1242
|
1242
|
}
|
|
1243
|
1243
|
|
|
1244
|
|
- // onCreate is guaranteed to be called synchronously by
|
|
1245
|
|
- // nsWinUtils::CreateNativeWindow, so this reference isn't really necessary.
|
|
1246
|
|
- // However, static analysis complains without it.
|
|
1247
|
1244
|
RefPtr<DocAccessibleParent> thisRef = this;
|
|
1248
|
|
- nsWinUtils::NativeWindowCreateProc onCreate([thisRef](HWND aHwnd) -> void {
|
|
1249
|
|
- ::SetPropW(aHwnd, kPropNameDocAccParent,
|
|
1250
|
|
- reinterpret_cast<HANDLE>(thisRef.get()));
|
|
1251
|
|
- thisRef->SetEmulatedWindowHandle(aHwnd);
|
|
1252
|
|
- });
|
|
|
1245
|
+ nsWinUtils::NativeWindowCreateProc onCreate(
|
|
|
1246
|
+ [thisRef](HWND aHwnd) mutable -> void {
|
|
|
1247
|
+ thisRef->SetEmulatedWindowHandle(aHwnd);
|
|
|
1248
|
+ HANDLE val;
|
|
|
1249
|
+ thisRef.forget(&val); // Release in SetEmulatedWindowHandle.
|
|
|
1250
|
+ ::SetPropW(aHwnd, kPropNameDocAccParent, val);
|
|
|
1251
|
+ });
|
|
1253
|
1252
|
|
|
1254
|
1253
|
HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
|
|
1255
|
1254
|
DebugOnly<HWND> hWnd = nsWinUtils::CreateNativeWindow(
|
| ... |
... |
@@ -1261,6 +1260,7 @@ void DocAccessibleParent::MaybeInitWindowEmulation() { |
|
1261
|
1260
|
void DocAccessibleParent::SetEmulatedWindowHandle(HWND aWindowHandle) {
|
|
1262
|
1261
|
if (!aWindowHandle && mEmulatedWindowHandle && IsTopLevel()) {
|
|
1263
|
1262
|
::DestroyWindow(mEmulatedWindowHandle);
|
|
|
1263
|
+ Release(); // AddRef in MaybeInitWindowEmulation.
|
|
1264
|
1264
|
}
|
|
1265
|
1265
|
mEmulatedWindowHandle = aWindowHandle;
|
|
1266
|
1266
|
}
|
browser/components/places/content/controller.js
| ... |
... |
@@ -1610,7 +1610,7 @@ var PlacesControllerDragHelper = { |
|
1610
|
1610
|
if (
|
|
1611
|
1611
|
!flavor.startsWith("text/x-moz-place") &&
|
|
1612
|
1612
|
(validNodes.length > 1 || dropCount > 1) &&
|
|
1613
|
|
- validNodes.some(n => n.uri?.startsWith("_javascript_:"))
|
|
|
1613
|
+ validNodes.some(n => URL.parse(n.uri)?.protocol === "_javascript_:")
|
|
1614
|
1614
|
) {
|
|
1615
|
1615
|
return false;
|
|
1616
|
1616
|
}
|
| ... |
... |
@@ -1687,18 +1687,14 @@ var PlacesControllerDragHelper = { |
|
1687
|
1687
|
if (
|
|
1688
|
1688
|
externalDrag &&
|
|
1689
|
1689
|
(nodes.length > 1 || dropCount > 1) &&
|
|
1690
|
|
- nodes.some(n => n.uri?.startsWith("_javascript_:"))
|
|
|
1690
|
+ nodes.some(n => URL.parse(n.uri)?.protocol === "_javascript_:")
|
|
1691
|
1691
|
) {
|
|
1692
|
1692
|
throw new Error("_javascript_ bookmarklet passed with uris");
|
|
1693
|
1693
|
}
|
|
1694
|
1694
|
|
|
1695
|
1695
|
// If a single _javascript_ url is being dropped from the urlbar or an external source,
|
|
1696
|
1696
|
// show the bookmark dialog as a speedbump protection against malicious cases.
|
|
1697
|
|
- if (
|
|
1698
|
|
- nodes.length == 1 &&
|
|
1699
|
|
- externalDrag &&
|
|
1700
|
|
- nodes[0].uri?.startsWith("_javascript_")
|
|
1701
|
|
- ) {
|
|
|
1697
|
+ if (nodes.length == 1 && externalDrag) {
|
|
1702
|
1698
|
let uri;
|
|
1703
|
1699
|
try {
|
|
1704
|
1700
|
uri = Services.io.newURI(nodes[0].uri);
|
| ... |
... |
@@ -1706,7 +1702,7 @@ var PlacesControllerDragHelper = { |
|
1706
|
1702
|
// Invalid uri, we skip this code and the entry will be discarded later.
|
|
1707
|
1703
|
}
|
|
1708
|
1704
|
|
|
1709
|
|
- if (uri) {
|
|
|
1705
|
+ if (uri?.scheme === "_javascript_") {
|
|
1710
|
1706
|
let bookmarkGuid = await PlacesUIUtils.showBookmarkDialog(
|
|
1711
|
1707
|
{
|
|
1712
|
1708
|
action: "add",
|
browser/components/places/tests/browser/browser_toolbar_drop_bookmarklet.js
| ... |
... |
@@ -9,6 +9,7 @@ const sandbox = sinon.createSandbox(); |
|
9
|
9
|
const URL1 = "https://example.com/1/";
|
|
10
|
10
|
const URL2 = "https://example.com/2/";
|
|
11
|
11
|
const BOOKMARKLET_URL = `_javascript_: (() => {alert('Hello, World!');})();`;
|
|
|
12
|
+const BOOKMARKLET_URL_MIXED_CASE = `_javascript_: (() => {})();`;
|
|
12
|
13
|
let bookmarks;
|
|
13
|
14
|
|
|
14
|
15
|
registerCleanupFunction(async function () {
|
| ... |
... |
@@ -34,12 +35,18 @@ add_task(async function test() { |
|
34
|
35
|
Assert.ok(placesItems, "PlacesToolbarItems should not be null");
|
|
35
|
36
|
|
|
36
|
37
|
/**
|
|
37
|
|
- * Simulates a drop of a bookmarklet URI onto the bookmarks bar.
|
|
|
38
|
+ * Simulates a drop of a bookmarklet URI onto the bookmarks bar and verifies
|
|
|
39
|
+ * the speedbump dialog appears.
|
|
38
|
40
|
*
|
|
39
|
41
|
* @param {string} aEffect
|
|
40
|
42
|
* The effect to use for the drop operation: move, copy, or link.
|
|
|
43
|
+ * @param {string} aBookmarkletUrl
|
|
|
44
|
+ * The bookmarklet URL to be dropped onto the bookmarks bar.
|
|
41
|
45
|
*/
|
|
42
|
|
- let simulateDragDrop = async function (aEffect) {
|
|
|
46
|
+ let simulateBookmarkletDragDrop = async function (
|
|
|
47
|
+ aEffect,
|
|
|
48
|
+ aBookmarkletUrl = BOOKMARKLET_URL
|
|
|
49
|
+ ) {
|
|
43
|
50
|
info("Simulates drag/drop of a new _javascript_:URL to the bookmarks");
|
|
44
|
51
|
await withBookmarksDialog(
|
|
45
|
52
|
true,
|
| ... |
... |
@@ -47,7 +54,7 @@ add_task(async function test() { |
|
47
|
54
|
EventUtils.synthesizeDrop(
|
|
48
|
55
|
toolbar,
|
|
49
|
56
|
placesItems,
|
|
50
|
|
- [[{ type: "text/x-moz-url", data: BOOKMARKLET_URL }]],
|
|
|
57
|
+ [[{ type: "text/x-moz-url", data: aBookmarkletUrl }]],
|
|
51
|
58
|
aEffect,
|
|
52
|
59
|
window
|
|
53
|
60
|
);
|
| ... |
... |
@@ -61,11 +68,21 @@ add_task(async function test() { |
|
61
|
68
|
|
|
62
|
69
|
Assert.equal(
|
|
63
|
70
|
location,
|
|
64
|
|
- BOOKMARKLET_URL,
|
|
|
71
|
+ aBookmarkletUrl.trim().replace(/^_javascript_/i, "_javascript_"),
|
|
65
|
72
|
"Should have opened the ShowBookmarksDialog with the correct bookmarklet url to be bookmarked"
|
|
66
|
73
|
);
|
|
67
|
74
|
}
|
|
68
|
75
|
);
|
|
|
76
|
+ };
|
|
|
77
|
+
|
|
|
78
|
+ for (let effect of ["copy", "link"]) {
|
|
|
79
|
+ for (let bookmarkletUrl of [
|
|
|
80
|
+ BOOKMARKLET_URL,
|
|
|
81
|
+ BOOKMARKLET_URL_MIXED_CASE,
|
|
|
82
|
+ ` _javascript_: (() => {})();`,
|
|
|
83
|
+ ]) {
|
|
|
84
|
+ await simulateBookmarkletDragDrop(effect, bookmarkletUrl);
|
|
|
85
|
+ }
|
|
69
|
86
|
|
|
70
|
87
|
info("Simulates drag/drop of a new URL to the bookmarks");
|
|
71
|
88
|
let spy = sandbox
|
| ... |
... |
@@ -81,18 +98,13 @@ add_task(async function test() { |
|
81
|
98
|
toolbar,
|
|
82
|
99
|
placesItems,
|
|
83
|
100
|
[[{ type: "text/x-moz-url", data: URL1 }]],
|
|
84
|
|
- aEffect,
|
|
|
101
|
+ effect,
|
|
85
|
102
|
window
|
|
86
|
103
|
);
|
|
87
|
104
|
|
|
88
|
105
|
await promise;
|
|
89
|
106
|
Assert.ok(spy.notCalled, "ShowBookmarksDialog on drop not called for url");
|
|
90
|
107
|
sandbox.restore();
|
|
91
|
|
- };
|
|
92
|
|
-
|
|
93
|
|
- let effects = ["copy", "link"];
|
|
94
|
|
- for (let effect of effects) {
|
|
95
|
|
- await simulateDragDrop(effect);
|
|
96
|
108
|
}
|
|
97
|
109
|
|
|
98
|
110
|
info("Move of existing bookmark / bookmarklet on toolbar");
|
browser/components/places/tests/browser/browser_toolbar_drop_multiple_with_bookmarklet.js
| ... |
... |
@@ -18,12 +18,12 @@ add_task(async function test() { |
|
18
|
18
|
// matter because we will set its data, effect, and mimeType manually.
|
|
19
|
19
|
let placesItems = document.getElementById("PlacesToolbarItems");
|
|
20
|
20
|
Assert.ok(placesItems, "PlacesToolbarItems should not be null");
|
|
21
|
|
- let simulateDragDrop = async function (aEffect, aMimeType) {
|
|
22
|
|
- let urls = [
|
|
23
|
|
- "https://example.com/1/",
|
|
24
|
|
- `_javascript_: (() => {alert('Hello, World!');})();`,
|
|
25
|
|
- "https://example.com/2/",
|
|
26
|
|
- ];
|
|
|
21
|
+ let simulateDragDrop = async function (
|
|
|
22
|
+ aEffect,
|
|
|
23
|
+ aMimeType,
|
|
|
24
|
+ aJsUrl = `_javascript_: (() => {alert('Hello, World!');})();`
|
|
|
25
|
+ ) {
|
|
|
26
|
+ let urls = ["https://example.com/1/", aJsUrl, "https://example.com/2/"];
|
|
27
|
27
|
|
|
28
|
28
|
let data = urls.map(spec => spec + "\n" + spec).join("\n");
|
|
29
|
29
|
|
| ... |
... |
@@ -43,8 +43,13 @@ add_task(async function test() { |
|
43
|
43
|
|
|
44
|
44
|
// Simulate a bookmark drop for all of the mime types and effects.
|
|
45
|
45
|
let mimeType = ["text/x-moz-url"];
|
|
46
|
|
- let effects = ["copy", "link"];
|
|
47
|
|
- for (let effect of effects) {
|
|
48
|
|
- await simulateDragDrop(effect, mimeType);
|
|
|
46
|
+ for (let effect of ["copy", "link"]) {
|
|
|
47
|
+ for (let jsUrl of [
|
|
|
48
|
+ `_javascript_: (() => {alert('Hello, World!');})();`,
|
|
|
49
|
+ `_javascript_: (() => {})();`,
|
|
|
50
|
+ ` _javascript_: (() => {})();`,
|
|
|
51
|
+ ]) {
|
|
|
52
|
+ await simulateDragDrop(effect, mimeType, jsUrl);
|
|
|
53
|
+ }
|
|
49
|
54
|
}
|
|
50
|
55
|
}); |
dom/base/nsContentUtils.cpp
| ... |
... |
@@ -5635,9 +5635,10 @@ void nsContentUtils::RequestFrameFocus(Element& aFrameElement, bool aCanRaise, |
|
5635
|
5635
|
RefPtr<Element> target = &aFrameElement;
|
|
5636
|
5636
|
bool defaultAction = true;
|
|
5637
|
5637
|
if (aCanRaise) {
|
|
5638
|
|
- DispatchEventOnlyToChrome(target->OwnerDoc(), target,
|
|
5639
|
|
- u"framefocusrequested"_ns, CanBubble::eYes,
|
|
5640
|
|
- Cancelable::eYes, &defaultAction);
|
|
|
5638
|
+ RefPtr<Document> doc = target->OwnerDoc();
|
|
|
5639
|
+ DispatchEventOnlyToChrome(doc, target, u"framefocusrequested"_ns,
|
|
|
5640
|
+ CanBubble::eYes, Cancelable::eYes,
|
|
|
5641
|
+ &defaultAction);
|
|
5641
|
5642
|
}
|
|
5642
|
5643
|
if (!defaultAction) {
|
|
5643
|
5644
|
return;
|
dom/script/ScriptLoader.cpp
| ... |
... |
@@ -240,27 +240,27 @@ ScriptLoader::~ScriptLoader() { |
|
240
|
240
|
FireScriptAvailable(NS_ERROR_ABORT, mParserBlockingRequest);
|
|
241
|
241
|
}
|
|
242
|
242
|
|
|
243
|
|
- for (ScriptLoadRequest* req = mXSLTRequests.getFirst(); req;
|
|
|
243
|
+ for (RefPtr<ScriptLoadRequest> req = mXSLTRequests.getFirst(); req;
|
|
244
|
244
|
req = req->getNext()) {
|
|
245
|
245
|
FireScriptAvailable(NS_ERROR_ABORT, req);
|
|
246
|
246
|
}
|
|
247
|
247
|
|
|
248
|
|
- for (ScriptLoadRequest* req = mDeferRequests.getFirst(); req;
|
|
|
248
|
+ for (RefPtr<ScriptLoadRequest> req = mDeferRequests.getFirst(); req;
|
|
249
|
249
|
req = req->getNext()) {
|
|
250
|
250
|
FireScriptAvailable(NS_ERROR_ABORT, req);
|
|
251
|
251
|
}
|
|
252
|
252
|
|
|
253
|
|
- for (ScriptLoadRequest* req = mLoadingAsyncRequests.getFirst(); req;
|
|
|
253
|
+ for (RefPtr<ScriptLoadRequest> req = mLoadingAsyncRequests.getFirst(); req;
|
|
254
|
254
|
req = req->getNext()) {
|
|
255
|
255
|
FireScriptAvailable(NS_ERROR_ABORT, req);
|
|
256
|
256
|
}
|
|
257
|
257
|
|
|
258
|
|
- for (ScriptLoadRequest* req = mLoadedAsyncRequests.getFirst(); req;
|
|
|
258
|
+ for (RefPtr<ScriptLoadRequest> req = mLoadedAsyncRequests.getFirst(); req;
|
|
259
|
259
|
req = req->getNext()) {
|
|
260
|
260
|
FireScriptAvailable(NS_ERROR_ABORT, req);
|
|
261
|
261
|
}
|
|
262
|
262
|
|
|
263
|
|
- for (ScriptLoadRequest* req =
|
|
|
263
|
+ for (RefPtr<ScriptLoadRequest> req =
|
|
264
|
264
|
mNonAsyncExternalScriptInsertedRequests.getFirst();
|
|
265
|
265
|
req; req = req->getNext()) {
|
|
266
|
266
|
FireScriptAvailable(NS_ERROR_ABORT, req);
|
dom/security/nsContentSecurityUtils.cpp
| ... |
... |
@@ -1179,8 +1179,9 @@ nsString nsContentSecurityUtils::GetIsElementNonceableNonce( |
|
1179
|
1179
|
// element’s attribute list:
|
|
1180
|
1180
|
if (nsCOMPtr<nsIScriptElement> script =
|
|
1181
|
1181
|
do_QueryInterface(const_cast<Element*>(&aElement))) {
|
|
1182
|
|
- auto containsScriptOrStyle = [](const nsAString& aStr) {
|
|
1183
|
|
- return aStr.LowerCaseFindASCII("<script") != kNotFound ||
|
|
|
1182
|
+ auto containsLinkScriptOrStyle = [](const nsAString& aStr) {
|
|
|
1183
|
+ return aStr.LowerCaseFindASCII("<link") != kNotFound ||
|
|
|
1184
|
+ aStr.LowerCaseFindASCII("<script") != kNotFound ||
|
|
1184
|
1185
|
aStr.LowerCaseFindASCII("<style") != kNotFound;
|
|
1185
|
1186
|
};
|
|
1186
|
1187
|
|
| ... |
... |
@@ -1188,21 +1189,21 @@ nsString nsContentSecurityUtils::GetIsElementNonceableNonce( |
|
1188
|
1189
|
uint32_t i = 0;
|
|
1189
|
1190
|
while (BorrowedAttrInfo info = aElement.GetAttrInfoAt(i++)) {
|
|
1190
|
1191
|
// Step 2.1. If attribute’s name contains an ASCII case-insensitive match
|
|
1191
|
|
- // for "<script" or "<style", return "Not Nonceable".
|
|
|
1192
|
+ // for "<link", <script" or "<style", return "Not Nonceable".
|
|
1192
|
1193
|
const nsAttrName* name = info.mName;
|
|
1193
|
1194
|
if (nsAtom* prefix = name->GetPrefix()) {
|
|
1194
|
|
- if (containsScriptOrStyle(nsDependentAtomString(prefix))) {
|
|
|
1195
|
+ if (containsLinkScriptOrStyle(nsDependentAtomString(prefix))) {
|
|
1195
|
1196
|
return EmptyString();
|
|
1196
|
1197
|
}
|
|
1197
|
1198
|
}
|
|
1198
|
|
- if (containsScriptOrStyle(nsDependentAtomString(name->LocalName()))) {
|
|
|
1199
|
+ if (containsLinkScriptOrStyle(nsDependentAtomString(name->LocalName()))) {
|
|
1199
|
1200
|
return EmptyString();
|
|
1200
|
1201
|
}
|
|
1201
|
1202
|
|
|
1202
|
1203
|
// Step 2.2. If attribute’s value contains an ASCII case-insensitive match
|
|
1203
|
|
- // for "<script" or "<style", return "Not Nonceable".
|
|
|
1204
|
+ // for "<link", "<script" or "<style", return "Not Nonceable".
|
|
1204
|
1205
|
info.mValue->ToString(value);
|
|
1205
|
|
- if (containsScriptOrStyle(value)) {
|
|
|
1206
|
+ if (containsLinkScriptOrStyle(value)) {
|
|
1206
|
1207
|
return EmptyString();
|
|
1207
|
1208
|
}
|
|
1208
|
1209
|
}
|
js/src/jit/BaselineIC.cpp
| ... |
... |
@@ -1735,10 +1735,15 @@ bool DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, |
|
1735
|
1735
|
// Transition stub state to megamorphic or generic if warranted.
|
|
1736
|
1736
|
MaybeTransition(cx, frame, stub);
|
|
1737
|
1737
|
|
|
|
1738
|
+ // The array is required to be packed, but may have indexed properties
|
|
|
1739
|
+ // if its length exceeds MAX_DENSE_ELEMENTS_COUNT. Don't optimize in
|
|
|
1740
|
+ // that case.
|
|
|
1741
|
+ bool isIndexed = arr.toObject().as<NativeObject>().isIndexed();
|
|
|
1742
|
+
|
|
1738
|
1743
|
// Try attaching a call stub.
|
|
1739
|
1744
|
bool handled = false;
|
|
1740
|
1745
|
if (op != JSOp::SpreadEval && op != JSOp::StrictSpreadEval &&
|
|
1741
|
|
- stub->state().canAttachStub()) {
|
|
|
1746
|
+ stub->state().canAttachStub() && !isIndexed) {
|
|
1742
|
1747
|
// Try CacheIR first:
|
|
1743
|
1748
|
Rooted<ArrayObject*> aobj(cx, &arr.toObject().as<ArrayObject>());
|
|
1744
|
1749
|
MOZ_ASSERT(IsPackedArray(aobj));
|
js/src/jit/CacheIR.cpp
| ... |
... |
@@ -6431,7 +6431,9 @@ ObjOperandId InlinableNativeIRGenerator::emitLoadArgsArray() { |
|
6431
|
6431
|
MOZ_ASSERT(!hasBoundArguments());
|
|
6432
|
6432
|
|
|
6433
|
6433
|
if (flags_.getArgFormat() == CallFlags::Spread) {
|
|
6434
|
|
- return writer.loadSpreadArgs();
|
|
|
6434
|
+ ObjOperandId result = writer.loadSpreadArgs();
|
|
|
6435
|
+ writer.guardArrayIsPacked(result);
|
|
|
6436
|
+ return result;
|
|
6435
|
6437
|
}
|
|
6436
|
6438
|
|
|
6437
|
6439
|
MOZ_ASSERT(flags_.getArgFormat() == CallFlags::FunApplyArray);
|
js/src/jit/CacheIRWriter.h
| ... |
... |
@@ -523,7 +523,13 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { |
|
523
|
523
|
ArgumentKind kind = ArgumentKind::Arg0;
|
|
524
|
524
|
uint32_t argc = 1;
|
|
525
|
525
|
CallFlags flags(CallFlags::Spread);
|
|
526
|
|
- return ObjOperandId(loadArgumentFixedSlot(kind, argc, flags).id());
|
|
|
526
|
+ ValOperandId argId = loadArgumentFixedSlot(kind, argc, flags);
|
|
|
527
|
+#ifdef ENABLE_PORTABLE_BASELINE_INTERP
|
|
|
528
|
+ // PBL doesn't support implicit unboxing of objects.
|
|
|
529
|
+ return guardToObject(argId);
|
|
|
530
|
+#else
|
|
|
531
|
+ return ObjOperandId(argId.id());
|
|
|
532
|
+#endif
|
|
527
|
533
|
}
|
|
528
|
534
|
|
|
529
|
535
|
void callScriptedFunction(ObjOperandId callee, Int32OperandId argc,
|
js/src/vm/PortableBaselineInterpret.cpp
| ... |
... |
@@ -3915,11 +3915,8 @@ uint64_t ICInterpretOps(uint64_t arg0, uint64_t arg1, ICStub* stub, |
|
3915
|
3915
|
CACHEOP_CASE(Int32MinMaxArrayResult) {
|
|
3916
|
3916
|
ObjOperandId arrayId = cacheIRReader.objOperandId();
|
|
3917
|
3917
|
bool isMax = cacheIRReader.readBool();
|
|
3918
|
|
- // ICs that use this opcode depend on implicit unboxing due to
|
|
3919
|
|
- // type-overload on ObjOperandId when a value is loaded
|
|
3920
|
|
- // directly from an argument slot. We explicitly unbox here.
|
|
3921
|
3918
|
NativeObject* nobj = reinterpret_cast<NativeObject*>(
|
|
3922
|
|
- &READ_VALUE_REG(arrayId.id()).toObject());
|
|
|
3919
|
+ READ_REG(arrayId.id()));
|
|
3923
|
3920
|
uint32_t len = nobj->getDenseInitializedLength();
|
|
3924
|
3921
|
if (len == 0) {
|
|
3925
|
3922
|
FAIL_IC();
|
| ... |
... |
@@ -3948,11 +3945,8 @@ uint64_t ICInterpretOps(uint64_t arg0, uint64_t arg1, ICStub* stub, |
|
3948
|
3945
|
CACHEOP_CASE(NumberMinMaxArrayResult) {
|
|
3949
|
3946
|
ObjOperandId arrayId = cacheIRReader.objOperandId();
|
|
3950
|
3947
|
bool isMax = cacheIRReader.readBool();
|
|
3951
|
|
- // ICs that use this opcode depend on implicit unboxing due to
|
|
3952
|
|
- // type-overload on ObjOperandId when a value is loaded
|
|
3953
|
|
- // directly from an argument slot. We explicitly unbox here.
|
|
3954
|
3948
|
NativeObject* nobj = reinterpret_cast<NativeObject*>(
|
|
3955
|
|
- &READ_VALUE_REG(arrayId.id()).toObject());
|
|
|
3949
|
+ READ_REG(arrayId.id()));
|
|
3956
|
3950
|
uint32_t len = nobj->getDenseInitializedLength();
|
|
3957
|
3951
|
if (len == 0) {
|
|
3958
|
3952
|
FAIL_IC();
|
toolkit/components/extensions/test/mochitest/test_ext_webrequest_upload.html
| ... |
... |
@@ -27,6 +27,7 @@ |
|
27
|
27
|
enctype="multipart/form-data"
|
|
28
|
28
|
>
|
|
29
|
29
|
<input type="text" name="textInput2" value="value2">
|
|
|
30
|
+<input type="text" name="__proto__" value="regression test for bug 2061470">
|
|
30
|
31
|
<input type="file" name="testFile">
|
|
31
|
32
|
<input type="file" name="emptyFile">
|
|
32
|
33
|
</form>
|
| ... |
... |
@@ -161,11 +162,19 @@ add_task(async function test_xhr_forms() { |
|
161
|
162
|
}
|
|
162
|
163
|
let action = new URL(form.action);
|
|
163
|
164
|
let formData = new FormData(form);
|
|
164
|
|
- let webRequestFD = {};
|
|
165
|
165
|
|
|
166
|
166
|
let updateActionURL = () => {
|
|
|
167
|
+ let webRequestFD = {};
|
|
167
|
168
|
for (let name of formData.keys()) {
|
|
168
|
|
- webRequestFD[name] = name in uploads ? [uploads[name].fileName] : formData.getAll(name);
|
|
|
169
|
+ if (Object.hasOwn(webRequestFD, name)) {
|
|
|
170
|
+ // Ignore duplicate keys; formData.getAll already read all values.
|
|
|
171
|
+ continue;
|
|
|
172
|
+ }
|
|
|
173
|
+ const value = Object.hasOwn(uploads, name) ? [uploads[name].fileName] : formData.getAll(name);
|
|
|
174
|
+ // Cannot use webRequestFD[name] = value, because for "__proto__" as
|
|
|
175
|
+ // name, that would trigger the Object.prototype.__proto__ setter
|
|
|
176
|
+ // instead of defining a data property.
|
|
|
177
|
+ Object.defineProperty(webRequestFD, name, { value, enumerable: true });
|
|
169
|
178
|
}
|
|
170
|
179
|
action.searchParams.set("upload", JSON.stringify(webRequestFD));
|
|
171
|
180
|
action.searchParams.set("enctype", form.enctype);
|
toolkit/components/extensions/webrequest/WebRequestUpload.sys.mjs
| ... |
... |
@@ -117,22 +117,6 @@ class Headers extends Map { |
|
117
|
117
|
}
|
|
118
|
118
|
}
|
|
119
|
119
|
|
|
120
|
|
-/**
|
|
121
|
|
- * Creates a new Object with a corresponding property for every
|
|
122
|
|
- * key-value pair in the given Map.
|
|
123
|
|
- *
|
|
124
|
|
- * @param {Map} map
|
|
125
|
|
- * The map to convert.
|
|
126
|
|
- * @returns {object}
|
|
127
|
|
- */
|
|
128
|
|
-function mapToObject(map) {
|
|
129
|
|
- let result = {};
|
|
130
|
|
- for (let [key, value] of map) {
|
|
131
|
|
- result[key] = value;
|
|
132
|
|
- }
|
|
133
|
|
- return result;
|
|
134
|
|
-}
|
|
135
|
|
-
|
|
136
|
120
|
/**
|
|
137
|
121
|
* Rewinds the given seekable input stream to its beginning, and catches
|
|
138
|
122
|
* any resulting errors.
|
| ... |
... |
@@ -446,7 +430,7 @@ function createFormData(stream, channel, lenient) { |
|
446
|
430
|
try {
|
|
447
|
431
|
let formData = parseFormData(stream, channel, lenient);
|
|
448
|
432
|
if (formData) {
|
|
449
|
|
- return mapToObject(formData);
|
|
|
433
|
+ return Object.fromEntries(formData);
|
|
450
|
434
|
}
|
|
451
|
435
|
} catch (e) {
|
|
452
|
436
|
Cu.reportError(e);
|
|