ma1 pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser

Commits:

11 changed files:

Changes:

  • browser/actors/ClickHandlerChild.sys.mjs
    ... ... @@ -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,
    

  • browser/app/profile/firefox.js
    ... ... @@ -907,6 +907,9 @@ pref("browser.link.open_newwindow.restriction", 2);
    907 907
       pref("browser.link.open_newwindow.disabled_in_fullscreen", false);
    
    908 908
     #endif
    
    909 909
     
    
    910
    +// If true, opening javscript: URLs using middle-click, CTRL+click etc. are blocked.
    
    911
    +pref("browser.link.alternative_click.block_javascript", true);
    
    912
    +
    
    910 913
     // Tabbed browser
    
    911 914
     pref("browser.tabs.closeTabByDblclick", false);
    
    912 915
     pref("browser.tabs.closeWindowWithLastTab", true);
    

  • browser/base/content/test/general/browser_modifiedclick_inherit_principal.js
    ... ... @@ -10,6 +10,10 @@ const kURL =
    10 10
      * we use the correct principal, and we don't clear the URL bar.
    
    11 11
      */
    
    12 12
     add_task(async function () {
    
    13
    +  await SpecialPowers.pushPrefEnv({
    
    14
    +    set: [["browser.link.alternative_click.block_javascript", false]],
    
    15
    +  });
    
    16
    +
    
    13 17
       await BrowserTestUtils.withNewTab(kURL, async function (browser) {
    
    14 18
         let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
    
    15 19
         await SpecialPowers.spawn(browser, [], async function () {
    

  • browser/base/content/test/linkHandling/browser.toml
    ... ... @@ -2,3 +2,8 @@
    2 2
     support-files = [
    
    3 3
       "file_contentAreaClick_subframe_javascript.html"
    
    4 4
     ]
    
    5
    +
    
    6
    +["browser_javascript_links.js"]
    
    7
    +support-files = [
    
    8
    +  "file_javascript_links_subframe.html"
    
    9
    +]

  • browser/base/content/test/linkHandling/browser_contentAreaClick_subframe_javascript.js
    ... ... @@ -5,6 +5,10 @@ const gExampleComRoot = getRootDirectory(gTestPath).replace(
    5 5
     const IFRAME_FILE = "file_contentAreaClick_subframe_javascript.html";
    
    6 6
     
    
    7 7
     add_task(async function () {
    
    8
    +  await SpecialPowers.pushPrefEnv({
    
    9
    +    set: [["browser.link.alternative_click.block_javascript", false]],
    
    10
    +  });
    
    11
    +
    
    8 12
       await BrowserTestUtils.withNewTab(
    
    9 13
         `data:text/html,<iframe src="${gExampleComRoot + IFRAME_FILE}"></iframe>`,
    
    10 14
         async browser => {
    

  • browser/base/content/test/linkHandling/browser_javascript_links.js
    1
    +/* Any copyright is dedicated to the Public Domain.
    
    2
    + * http://creativecommons.org/publicdomain/zero/1.0/ */
    
    3
    +
    
    4
    +"use strict";
    
    5
    +
    
    6
    +const TEST_PATH = getRootDirectory(gTestPath).replace(
    
    7
    +  "chrome://mochitests/content/",
    
    8
    +  "https://example.com/"
    
    9
    +);
    
    10
    +const IFRAME_PATH = TEST_PATH + "file_javascript_links_subframe.html";
    
    11
    +
    
    12
    +add_setup(async function () {
    
    13
    +  await SpecialPowers.pushPrefEnv({
    
    14
    +    set: [
    
    15
    +      ["browser.link.alternative_click.block_javascript", true],
    
    16
    +      ["browser.tabs.opentabfor.middleclick", true],
    
    17
    +      ["middlemouse.paste", false],
    
    18
    +      ["middlemouse.contentLoadURL", false],
    
    19
    +      ["general.autoScroll", false],
    
    20
    +    ],
    
    21
    +  });
    
    22
    +});
    
    23
    +
    
    24
    +add_task(async function () {
    
    25
    +  await BrowserTestUtils.withNewTab(
    
    26
    +    `data:text/html,<a href="javascript:alert(1);">click me`,
    
    27
    +    async browser => {
    
    28
    +      await BrowserTestUtils.synthesizeMouseAtCenter(
    
    29
    +        "a",
    
    30
    +        { button: 0, ctrlKey: true, metaKey: true },
    
    31
    +        browser
    
    32
    +      );
    
    33
    +      is(
    
    34
    +        gBrowser.tabs.length,
    
    35
    +        2,
    
    36
    +        "Accel+click on javascript: link shouldn't open a new tab"
    
    37
    +      );
    
    38
    +
    
    39
    +      await BrowserTestUtils.synthesizeMouseAtCenter(
    
    40
    +        "a",
    
    41
    +        { button: 1 },
    
    42
    +        browser
    
    43
    +      );
    
    44
    +      is(
    
    45
    +        gBrowser.tabs.length,
    
    46
    +        2,
    
    47
    +        "Middle click on javascript: link shouldn't open a new tab"
    
    48
    +      );
    
    49
    +
    
    50
    +      await BrowserTestUtils.synthesizeMouseAtCenter(
    
    51
    +        "a",
    
    52
    +        { button: 0, shiftKey: true },
    
    53
    +        browser
    
    54
    +      );
    
    55
    +      // This is fragile and might miss the new window, but the test will fail
    
    56
    +      // anyway when finishing with an extra window left behind.
    
    57
    +      // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    
    58
    +      await new Promise(resolve => setTimeout(resolve, 200));
    
    59
    +      is(
    
    60
    +        BrowserWindowTracker.windowCount,
    
    61
    +        1,
    
    62
    +        "Shift+click on javascript: link shouldn't open a new window"
    
    63
    +      );
    
    64
    +    }
    
    65
    +  );
    
    66
    +});
    
    67
    +
    
    68
    +add_task(async function iframe_link() {
    
    69
    +  await BrowserTestUtils.withNewTab(
    
    70
    +    `data:text/html,<iframe src="${IFRAME_PATH}"></iframe>`,
    
    71
    +    async browser => {
    
    72
    +      // ctrl/cmd-click the link in the subframe.
    
    73
    +      await BrowserTestUtils.synthesizeMouseAtCenter(
    
    74
    +        "a",
    
    75
    +        { ctrlKey: true, metaKey: true },
    
    76
    +        browser.browsingContext.children[0]
    
    77
    +      );
    
    78
    +
    
    79
    +      // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    
    80
    +      await new Promise(resolve => setTimeout(resolve, 200));
    
    81
    +      is(
    
    82
    +        gBrowser.tabs.length,
    
    83
    +        2,
    
    84
    +        "Click on javascript: link in iframe shouldn't open a new tab"
    
    85
    +      );
    
    86
    +    }
    
    87
    +  );
    
    88
    +});

  • browser/base/content/test/linkHandling/file_javascript_links_subframe.html
    1
    +<!DOCTYPE html>
    
    2
    +<a href="javascript:alert(1)">click me

  • dom/base/nsObjectLoadingContent.cpp
    ... ... @@ -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"
    
    ... ... @@ -736,11 +737,12 @@ nsObjectLoadingContent::UpdateObjectParameters() {
    736 737
       /// Codebase
    
    737 738
       ///
    
    738 739
     
    
    739
    -  nsAutoString codebaseStr;
    
    740 740
       nsIURI* docBaseURI = el->GetBaseURI();
    
    741
    -  el->GetAttr(nsGkAtoms::codebase, codebaseStr);
    
    742 741
     
    
    743
    -  if (!codebaseStr.IsEmpty()) {
    
    742
    +  nsAutoString codebaseStr;
    
    743
    +  el->GetAttr(nsGkAtoms::codebase, codebaseStr);
    
    744
    +  if (StaticPrefs::dom_object_embed_codebase_enabled() &&
    
    745
    +      !codebaseStr.IsEmpty()) {
    
    744 746
         rv = nsContentUtils::NewURIWithDocumentCharset(
    
    745 747
             getter_AddRefs(newBaseURI), codebaseStr, el->OwnerDoc(), docBaseURI);
    
    746 748
         if (NS_FAILED(rv)) {
    

  • modules/libpref/init/StaticPrefList.yaml
    ... ... @@ -3633,6 +3633,12 @@
    3633 3633
       value: true
    
    3634 3634
       mirror: always
    
    3635 3635
     
    
    3636
    +# Whether the codebase attribute in an <object> is used as the base URI.
    
    3637
    +- name: dom.object_embed.codebase.enabled
    
    3638
    +  type: bool
    
    3639
    +  value: false
    
    3640
    +  mirror: always
    
    3641
    +
    
    3636 3642
     # Whether origin trials are enabled.
    
    3637 3643
     - name: dom.origin-trials.enabled
    
    3638 3644
       type: bool
    

  • testing/web-platform/tests/html/semantics/embedded-content/the-object-element/historical.html
    ... ... @@ -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>

  • widget/gtk/nsClipboard.cpp
    ... ... @@ -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
     MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sClipboardTargets;
    
    70 74
     MOZ_CONSTINIT ClipboardTargets nsRetrievalContext::sPrimaryTargets;
    
    71 75
     
    
    ... ... @@ -313,6 +317,12 @@ nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable,
    313 317
         gtk_target_list_add(list, atom, 0, 0);
    
    314 318
       }
    
    315 319
     
    
    320
    +  // Try to exclude private data from clipboard history.
    
    321
    +  if (aTransferable->GetIsPrivateData()) {
    
    322
    +    GdkAtom atom = gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE);
    
    323
    +    gtk_target_list_add(list, atom, 0, 0);
    
    324
    +  }
    
    325
    +
    
    316 326
       // Get GTK clipboard (CLIPBOARD or PRIMARY)
    
    317 327
       GtkClipboard* gtkClipboard =
    
    318 328
           gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
    
    ... ... @@ -1228,6 +1238,22 @@ void nsClipboard::SelectionGetEvent(GtkClipboard* aClipboard,
    1228 1238
         return;
    
    1229 1239
       }
    
    1230 1240
     
    
    1241
    +  if (selectionTarget == gdk_atom_intern(kKDEPasswordManagerHintMime, FALSE)) {
    
    1242
    +    if (!trans->GetIsPrivateData()) {
    
    1243
    +      MOZ_CLIPBOARD_LOG(
    
    1244
    +          "  requested %s, but the data isn't actually private!\n",
    
    1245
    +          kKDEPasswordManagerHintMime);
    
    1246
    +      return;
    
    1247
    +    }
    
    1248
    +
    
    1249
    +    static const char* kSecret = "secret";
    
    1250
    +    MOZ_CLIPBOARD_LOG("  Setting data to '%s' for %s\n", kSecret,
    
    1251
    +                      kKDEPasswordManagerHintMime);
    
    1252
    +    gtk_selection_data_set(aSelectionData, selectionTarget, 8,
    
    1253
    +                           (const guchar*)kSecret, strlen(kSecret));
    
    1254
    +    return;
    
    1255
    +  }
    
    1256
    +
    
    1231 1257
       MOZ_CLIPBOARD_LOG("  Try if we have anything at GetTransferData() for %s\n",
    
    1232 1258
                         GUniquePtr<gchar>(gdk_atom_name(selectionTarget)).get());
    
    1233 1259