ma1 pushed to branch mullvad-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
7d9abcbb
by Tom Schuster at 2025-08-18T13:26:10+02:00
-
46fcfe95
by Tom Schuster at 2025-08-18T13:26:12+02:00
-
e710fcf4
by Tom Schuster at 2025-08-18T13:26:13+02:00
-
663d9707
by Kershaw Chang at 2025-08-18T13:26:15+02:00
7 changed files:
- browser/actors/ClickHandlerChild.sys.mjs
- browser/app/profile/firefox.js
- dom/base/nsObjectLoadingContent.cpp
- modules/libpref/init/StaticPrefList.yaml
- netwerk/protocol/http/nsHttpConnection.cpp
- testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html
- widget/gtk/nsClipboard.cpp
Changes:
| ... | ... | @@ -12,12 +12,26 @@ ChromeUtils.defineESModuleGetters(lazy, { |
| 12 | 12 | E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs",
|
| 13 | 13 | });
|
| 14 | 14 | |
| 15 | +XPCOMUtils.defineLazyPreferenceGetter(
|
|
| 16 | + lazy,
|
|
| 17 | + "autoscrollEnabled",
|
|
| 18 | + "general.autoScroll",
|
|
| 19 | + true
|
|
| 20 | +);
|
|
| 21 | + |
|
| 22 | +XPCOMUtils.defineLazyPreferenceGetter(
|
|
| 23 | + lazy,
|
|
| 24 | + "blockJavascript",
|
|
| 25 | + "browser.link.alternative_click.block_javascript",
|
|
| 26 | + true
|
|
| 27 | +);
|
|
| 28 | + |
|
| 15 | 29 | export class MiddleMousePasteHandlerChild extends JSWindowActorChild {
|
| 16 | 30 | handleEvent(clickEvent) {
|
| 17 | 31 | if (
|
| 18 | 32 | clickEvent.defaultPrevented ||
|
| 19 | 33 | clickEvent.button != 1 ||
|
| 20 | - MiddleMousePasteHandlerChild.autoscrollEnabled
|
|
| 34 | + lazy.autoscrollEnabled
|
|
| 21 | 35 | ) {
|
| 22 | 36 | return;
|
| 23 | 37 | }
|
| ... | ... | @@ -34,13 +48,6 @@ export class MiddleMousePasteHandlerChild extends JSWindowActorChild { |
| 34 | 48 | }
|
| 35 | 49 | }
|
| 36 | 50 | |
| 37 | -XPCOMUtils.defineLazyPreferenceGetter(
|
|
| 38 | - MiddleMousePasteHandlerChild,
|
|
| 39 | - "autoscrollEnabled",
|
|
| 40 | - "general.autoScroll",
|
|
| 41 | - true
|
|
| 42 | -);
|
|
| 43 | - |
|
| 44 | 51 | export class ClickHandlerChild extends JSWindowActorChild {
|
| 45 | 52 | handleEvent(wrapperEvent) {
|
| 46 | 53 | this.handleClickEvent(wrapperEvent.sourceEvent);
|
| ... | ... | @@ -112,6 +119,14 @@ export class ClickHandlerChild extends JSWindowActorChild { |
| 112 | 119 | };
|
| 113 | 120 | |
| 114 | 121 | if (href && !isFromMiddleMousePasteHandler) {
|
| 122 | + if (
|
|
| 123 | + lazy.blockJavascript &&
|
|
| 124 | + Services.io.extractScheme(href) == "javascript"
|
|
| 125 | + ) {
|
|
| 126 | + // We don't want to open new tabs or windows for javascript: links.
|
|
| 127 | + return;
|
|
| 128 | + }
|
|
| 129 | + |
|
| 115 | 130 | try {
|
| 116 | 131 | Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(
|
| 117 | 132 | principal,
|
| ... | ... | @@ -880,6 +880,9 @@ pref("browser.link.open_newwindow.restriction", 2); |
| 880 | 880 | pref("browser.link.open_newwindow.disabled_in_fullscreen", false);
|
| 881 | 881 | #endif
|
| 882 | 882 | |
| 883 | +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked.
|
|
| 884 | +pref("browser.link.alternative_click.block_javascript", true);
|
|
| 885 | + |
|
| 883 | 886 | // Tabbed browser
|
| 884 | 887 | pref("browser.tabs.closeTabByDblclick", false);
|
| 885 | 888 | pref("browser.tabs.closeWindowWithLastTab", true);
|
| ... | ... | @@ -73,6 +73,7 @@ |
| 73 | 73 | #include "mozilla/PresShell.h"
|
| 74 | 74 | #include "mozilla/ProfilerLabels.h"
|
| 75 | 75 | #include "mozilla/StaticPrefs_browser.h"
|
| 76 | +#include "mozilla/StaticPrefs_dom.h"
|
|
| 76 | 77 | #include "nsChannelClassifier.h"
|
| 77 | 78 | #include "nsFocusManager.h"
|
| 78 | 79 | #include "ReferrerInfo.h"
|
| ... | ... | @@ -720,11 +721,12 @@ nsObjectLoadingContent::UpdateObjectParameters() { |
| 720 | 721 | /// Codebase
|
| 721 | 722 | ///
|
| 722 | 723 | |
| 723 | - nsAutoString codebaseStr;
|
|
| 724 | 724 | nsIURI* docBaseURI = el->GetBaseURI();
|
| 725 | - el->GetAttr(nsGkAtoms::codebase, codebaseStr);
|
|
| 726 | 725 | |
| 727 | - if (!codebaseStr.IsEmpty()) {
|
|
| 726 | + nsAutoString codebaseStr;
|
|
| 727 | + el->GetAttr(nsGkAtoms::codebase, codebaseStr);
|
|
| 728 | + if (StaticPrefs::dom_object_embed_codebase_enabled() &&
|
|
| 729 | + !codebaseStr.IsEmpty()) {
|
|
| 728 | 730 | rv = nsContentUtils::NewURIWithDocumentCharset(
|
| 729 | 731 | getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI);
|
| 730 | 732 | if (NS_FAILED(rv)) {
|
| ... | ... | @@ -3206,6 +3206,12 @@ |
| 3206 | 3206 | value: true
|
| 3207 | 3207 | mirror: always
|
| 3208 | 3208 | |
| 3209 | +# Whether the codebase attribute in an <object> is used as the base URI.
|
|
| 3210 | +- name: dom.object_embed.codebase.enabled
|
|
| 3211 | + type: bool
|
|
| 3212 | + value: false
|
|
| 3213 | + mirror: always
|
|
| 3214 | + |
|
| 3209 | 3215 | # Whether origin trials are enabled.
|
| 3210 | 3216 | - name: dom.origin-trials.enabled
|
| 3211 | 3217 | type: bool
|
| ... | ... | @@ -1663,9 +1663,10 @@ nsresult nsHttpConnection::OnSocketWritable() { |
| 1663 | 1663 | }
|
| 1664 | 1664 | |
| 1665 | 1665 | LOG((" writing transaction request stream\n"));
|
| 1666 | - rv = mTransaction->ReadSegmentsAgain(this,
|
|
| 1667 | - nsIOService::gDefaultSegmentSize,
|
|
| 1668 | - &transactionBytes, &again);
|
|
| 1666 | + RefPtr<nsAHttpTransaction> transaction = mTransaction;
|
|
| 1667 | + rv = transaction->ReadSegmentsAgain(this,
|
|
| 1668 | + nsIOService::gDefaultSegmentSize,
|
|
| 1669 | + &transactionBytes, &again);
|
|
| 1669 | 1670 | if (mTlsHandshaker->EarlyDataUsed()) {
|
| 1670 | 1671 | mContentBytesWritten0RTT += transactionBytes;
|
| 1671 | 1672 | if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
|
| ... | ... | @@ -1688,7 +1689,8 @@ nsresult nsHttpConnection::OnSocketWritable() { |
| 1688 | 1689 | static_cast<uint32_t>(mSocketOutCondition), again));
|
| 1689 | 1690 | |
| 1690 | 1691 | // XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF.
|
| 1691 | - if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) {
|
|
| 1692 | + if (rv == NS_BASE_STREAM_CLOSED &&
|
|
| 1693 | + (mTransaction && !mTransaction->IsDone())) {
|
|
| 1692 | 1694 | rv = NS_OK;
|
| 1693 | 1695 | transactionBytes = 0;
|
| 1694 | 1696 | }
|
| ... | ... | @@ -1731,7 +1733,8 @@ nsresult nsHttpConnection::OnSocketWritable() { |
| 1731 | 1733 | // When Spdy tunnel is used we need to explicitly set when a request is
|
| 1732 | 1734 | // done.
|
| 1733 | 1735 | if ((mState != HttpConnectionState::SETTING_UP_TUNNEL) && !mSpdySession) {
|
| 1734 | - nsHttpTransaction* trans = mTransaction->QueryHttpTransaction();
|
|
| 1736 | + nsHttpTransaction* trans =
|
|
| 1737 | + mTransaction ? mTransaction->QueryHttpTransaction() : nullptr;
|
|
| 1735 | 1738 | // needed for websocket over h2 (direct)
|
| 1736 | 1739 | if (!trans || !trans->IsWebsocketUpgrade()) {
|
| 1737 | 1740 | mRequestDone = true;
|
| ... | ... | @@ -1835,7 +1838,8 @@ nsresult nsHttpConnection::OnSocketReadable() { |
| 1835 | 1838 | rv = NS_ERROR_FAILURE;
|
| 1836 | 1839 | LOG((" No Transaction In OnSocketWritable\n"));
|
| 1837 | 1840 | } else {
|
| 1838 | - rv = mTransaction->WriteSegmentsAgain(
|
|
| 1841 | + RefPtr<nsAHttpTransaction> transaction = mTransaction;
|
|
| 1842 | + rv = transaction->WriteSegmentsAgain(
|
|
| 1839 | 1843 | this, nsIOService::gDefaultSegmentSize, &n, &again);
|
| 1840 | 1844 | }
|
| 1841 | 1845 | LOG(("nsHttpConnection::OnSocketReadable %p trans->ws rv=%" PRIx32
|
| ... | ... | @@ -30,4 +30,17 @@ async_test(t => { |
| 30 | 30 | obj.onerror = t.unreached_func();
|
| 31 | 31 | document.body.appendChild(obj);
|
| 32 | 32 | }, "object's typemustmatch content attribute should not be supported");
|
| 33 | + |
|
| 34 | +async_test(t => {
|
|
| 35 | + const obj = document.createElement("object");
|
|
| 36 | + t.add_cleanup(() => obj.remove());
|
|
| 37 | + obj.setAttribute("data", "/common/blank.html");
|
|
| 38 | + obj.setAttribute("codebase", "https://test.invalid/");
|
|
| 39 | + obj.onload = t.step_func_done(() => {
|
|
| 40 | + assert_not_equals(obj.contentDocument, null, "/common/blank.html should be loaded");
|
|
| 41 | + assert_equals(obj.contentDocument.location.origin, location.origin, "document should be loaded with current origin as base");
|
|
| 42 | + });
|
|
| 43 | + obj.onerror = t.unreached_func();
|
|
| 44 | + document.body.appendChild(obj);
|
|
| 45 | +}, "object's codebase content attribute should not be supported");
|
|
| 33 | 46 | </script> |
| ... | ... | @@ -66,6 +66,10 @@ static const char kHTMLMarkupPrefix[] = |
| 66 | 66 | |
| 67 | 67 | static const char kURIListMime[] = "text/uri-list";
|
| 68 | 68 | |
| 69 | +// MIME to exclude sensitive data (password) from the clipboard history on not
|
|
| 70 | +// just KDE.
|
|
| 71 | +static const char kKDEPasswordManagerHintMime[] = "x-kde-passwordManagerHint";
|
|
| 72 | + |
|
| 69 | 73 | ClipboardTargets nsRetrievalContext::sClipboardTargets;
|
| 70 | 74 | ClipboardTargets nsRetrievalContext::sPrimaryTargets;
|
| 71 | 75 | |
| ... | ... | @@ -323,6 +327,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, |
| 323 | 327 | gtk_target_list_add(list, atom, 0, 0);
|
| 324 | 328 | }
|
| 325 | 329 | |
| 330 | + // Try to exclude private data from clipboard history.
|
|
| 331 | + if (aTransferable->GetIsPrivateData()) {
|
|
| 332 | + GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE);
|
|
| 333 | + gtk_target_list_add(list, atom, 0, 0);
|
|
| 334 | + }
|
|
| 335 | + |
|
| 326 | 336 | // Get GTK clipboard (CLIPBOARD or PRIMARY)
|
| 327 | 337 | GtkClipboard* gtkClipboard =
|
| 328 | 338 | gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
|
| ... | ... | @@ -1313,6 +1323,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard, |
| 1313 | 1323 | return;
|
| 1314 | 1324 | }
|
| 1315 | 1325 | |
| 1326 | + if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) {
|
|
| 1327 | + if (!trans->GetIsPrivateData()) {
|
|
| 1328 | + MOZ_CLIPBOARD_LOG(
|
|
| 1329 | + " requested %s, but the data isn't actually private!\n",
|
|
| 1330 | + kKDEPasswordManagerHintMime);
|
|
| 1331 | + return;
|
|
| 1332 | + }
|
|
| 1333 | + |
|
| 1334 | + static const char* kSecret = "secret";
|
|
| 1335 | + MOZ_CLIPBOARD_LOG(" Setting data to '%s' for %s\n", kSecret,
|
|
| 1336 | + kKDEPasswordManagerHintMime);
|
|
| 1337 | + gtk_selection_data_set(aSelectionData, selectionTarget, 8,
|
|
| 1338 | + (const guchar*)kSecret, strlen(kSecret));
|
|
| 1339 | + return;
|
|
| 1340 | + }
|
|
| 1341 | + |
|
| 1316 | 1342 | MOZ_CLIPBOARD_LOG(" Try if we have anything at GetTransferData() for %s\n",
|
| 1317 | 1343 | GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get());
|
| 1318 | 1344 |