Pier Angelo Vendrame pushed to branch tor-browser-102.5.0esr-12.5-1 at The Tor Project / Applications / Tor Browser

Commits:

5 changed files:

Changes:

  • browser/components/places/PlacesUIUtils.jsm
    ... ... @@ -1903,7 +1903,11 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "URI_FLAVORS", () => {
    1903 1903
       return [PlacesUtils.TYPE_X_MOZ_URL, TAB_DROP_TYPE, PlacesUtils.TYPE_UNICODE];
    
    1904 1904
     });
    
    1905 1905
     XPCOMUtils.defineLazyGetter(PlacesUIUtils, "SUPPORTED_FLAVORS", () => {
    
    1906
    -  return [...PlacesUIUtils.PLACES_FLAVORS, ...PlacesUIUtils.URI_FLAVORS];
    
    1906
    +  return [
    
    1907
    +    ...PlacesUIUtils.PLACES_FLAVORS,
    
    1908
    +    ...PlacesUIUtils.URI_FLAVORS,
    
    1909
    +    "application/x-torbrowser-opaque",
    
    1910
    +  ];
    
    1907 1911
     });
    
    1908 1912
     
    
    1909 1913
     XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
    

  • browser/components/places/content/controller.js
    ... ... @@ -1251,6 +1251,7 @@ PlacesController.prototype = {
    1251 1251
         [
    
    1252 1252
           PlacesUtils.TYPE_X_MOZ_PLACE,
    
    1253 1253
           PlacesUtils.TYPE_X_MOZ_URL,
    
    1254
    +      "application/x-torbrowser-opaque",
    
    1254 1255
           PlacesUtils.TYPE_UNICODE,
    
    1255 1256
         ].forEach(type => xferable.addDataFlavor(type));
    
    1256 1257
     
    

  • dom/base/ContentAreaDropListener.jsm
    ... ... @@ -5,6 +5,16 @@
    5 5
     const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
    
    6 6
     const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
    
    7 7
     
    
    8
    +const { XPCOMUtils } = ChromeUtils.import(
    
    9
    +  "resource://gre/modules/XPCOMUtils.jsm"
    
    10
    +);
    
    11
    +
    
    12
    +XPCOMUtils.defineLazyGetter(this, "gOpaqueDrag", () => {
    
    13
    +  return Cc["@torproject.org/torbutton-dragDropFilter;1"].getService(
    
    14
    +    Ci.nsISupports
    
    15
    +  ).wrappedJSObject.opaqueDrag;
    
    16
    +});
    
    17
    +
    
    8 18
     // This component is used for handling dragover and drop of urls.
    
    9 19
     //
    
    10 20
     // It checks to see whether a drop of a url is allowed. For instance, a url
    
    ... ... @@ -43,10 +53,15 @@ ContentAreaDropListener.prototype = {
    43 53
           }
    
    44 54
         }
    
    45 55
     
    
    46
    -    type = "text/x-moz-url";
    
    47
    -    if (types.contains(type)) {
    
    56
    +    for (let type of ["text/x-moz-url", "application/x-torbrowser-opaque"]) {
    
    57
    +      if (!types.contains(type)) {
    
    58
    +        continue;
    
    59
    +      }
    
    48 60
           data = dt.mozGetDataAt(type, i);
    
    49 61
           if (data) {
    
    62
    +        if (type === "application/x-torbrowser-opaque") {
    
    63
    +          ({ type, value: data = "" } = gOpaqueDrag.get(data));
    
    64
    +        }
    
    50 65
             let lines = data.split("\n");
    
    51 66
             for (let i = 0, length = lines.length; i < length; i += 2) {
    
    52 67
               this._addLink(links, lines[i], lines[i + 1], type);
    
    ... ... @@ -250,6 +265,7 @@ ContentAreaDropListener.prototype = {
    250 265
         if (
    
    251 266
           !types.includes("application/x-moz-file") &&
    
    252 267
           !types.includes("text/x-moz-url") &&
    
    268
    +      !types.includes("application/x-torbrowser-opaque") &&
    
    253 269
           !types.includes("text/uri-list") &&
    
    254 270
           !types.includes("text/x-moz-text-internal") &&
    
    255 271
           !types.includes("text/plain")
    

  • toolkit/components/places/PlacesUtils.jsm
    ... ... @@ -32,6 +32,12 @@ XPCOMUtils.defineLazyGetter(this, "gCryptoHash", () => {
    32 32
       return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
    
    33 33
     });
    
    34 34
     
    
    35
    +XPCOMUtils.defineLazyGetter(this, "gOpaqueDrag", () => {
    
    36
    +  return Cc["@torproject.org/torbutton-dragDropFilter;1"].getService(
    
    37
    +    Ci.nsISupports
    
    38
    +  ).wrappedJSObject.opaqueDrag;
    
    39
    +});
    
    40
    +
    
    35 41
     // On Mac OSX, the transferable system converts "\r\n" to "\n\n", where
    
    36 42
     // we really just want "\n". On other platforms, the transferable system
    
    37 43
     // converts "\r\n" to "\n".
    
    ... ... @@ -1132,6 +1138,9 @@ var PlacesUtils = {
    1132 1138
       unwrapNodes: function PU_unwrapNodes(blob, type) {
    
    1133 1139
         // We split on "\n"  because the transferable system converts "\r\n" to "\n"
    
    1134 1140
         var nodes = [];
    
    1141
    +    if (type === "application/x-torbrowser-opaque") {
    
    1142
    +      ({ value: blob, type } = gOpaqueDrag.get(blob));
    
    1143
    +    }
    
    1135 1144
         switch (type) {
    
    1136 1145
           case this.TYPE_X_MOZ_PLACE:
    
    1137 1146
           case this.TYPE_X_MOZ_PLACE_SEPARATOR:
    

  • toolkit/torbutton/components/dragDropFilter.js
    ... ... @@ -13,6 +13,7 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
    13 13
     XPCOMUtils.defineLazyModuleGetters(this, {
    
    14 14
       ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
    
    15 15
     });
    
    16
    +XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
    
    16 17
     
    
    17 18
     // Module specific constants
    
    18 19
     const kMODULE_NAME = "Torbutton Drag and Drop Handler";
    
    ... ... @@ -28,50 +29,55 @@ const URLISH_TYPES = Object.freeze([
    28 29
       "application/x-moz-file-promise-url",
    
    29 30
     ]);
    
    30 31
     
    
    31
    -/*
    
    32
    -  Returns true if the text resembles a URL or even just a hostname
    
    33
    -  in a way that may prompt the O.S. or other applications to send out a
    
    34
    -  validation DNS query, if not a full request (e.g. " torproject.org",
    
    35
    -  even with the leading whitespace).
    
    36
    -*/
    
    37
    -function isURLish(text) {
    
    38
    -  // Ignore leading whitespace.
    
    39
    -  text = text.trim();
    
    40
    -
    
    41
    -  // Without any protocol or dot in the first chunk, this is unlikely
    
    42
    -  // to be considered URLish (exception: localhost, but we don't care).
    
    43
    -  if (!/^[a-z][a-z0-9+-]*:\/\//i.test(text)) {
    
    44
    -    // no protocol
    
    45
    -    if (!/^[^.\s\/]+\.[^.\s\/]/.test(text)) {
    
    46
    -      // no dot
    
    47
    -      return false;
    
    32
    +const MAIN_PROCESS =
    
    33
    +  Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT;
    
    34
    +
    
    35
    +const EMPTY_PAYLOAD = {};
    
    36
    +const OpaqueDrag = {
    
    37
    +  listening: false,
    
    38
    +  payload: EMPTY_PAYLOAD,
    
    39
    +  store(value, type) {
    
    40
    +    let opaqueKey = crypto.randomUUID();
    
    41
    +    this.payload = { opaqueKey, value, type };
    
    42
    +    if (!this.listening && MAIN_PROCESS) {
    
    43
    +      Services.ppmm.addMessageListener(
    
    44
    +        "DragDropFilter:GetOpaqueDrag",
    
    45
    +        () => this.payload
    
    46
    +      );
    
    47
    +      this.listening = true;
    
    48 48
         }
    
    49
    -    // Prepare for hostname validation via relative URL building.
    
    50
    -    text = `//${text}`;
    
    51
    -  }
    
    52
    -  // Validate URL or hostname.
    
    53
    -  try {
    
    54
    -    new URL(text, "https://localhost");
    
    55
    -    return true;
    
    56
    -  } catch (e) {
    
    57
    -    // invalid URL, bail out
    
    58
    -  }
    
    59
    -  return false;
    
    60
    -}
    
    61
    -
    
    62
    -// Returns true if any chunk of text is URLish
    
    63
    -const hasURLish = text => text.split(/[^\p{L}_.-:\/%~@$-]+/u).some(isURLish);
    
    49
    +    return opaqueKey;
    
    50
    +  },
    
    51
    +  retrieve(key) {
    
    52
    +    let { opaqueKey, value, type } = this.payload;
    
    53
    +    if (opaqueKey === key) {
    
    54
    +      return { value, type };
    
    55
    +    }
    
    56
    +    if (!MAIN_PROCESS) {
    
    57
    +      this.payload = Services.cpmm.sendSyncMessage(
    
    58
    +        "DragDropFilter:GetOpaqueDrag"
    
    59
    +      )[0];
    
    60
    +      if (key === this.payload.opaqueKey) {
    
    61
    +        return this.retrieve(key);
    
    62
    +      }
    
    63
    +    }
    
    64
    +    return EMPTY_PAYLOAD;
    
    65
    +  },
    
    66
    +};
    
    64 67
     
    
    65 68
     function DragDropFilter() {
    
    66 69
       this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
    
    67 70
         Ci.nsISupports
    
    68 71
       ).wrappedJSObject;
    
    69 72
       this.logger.log(3, "Component Load 0: New DragDropFilter.");
    
    70
    -
    
    71
    -  try {
    
    72
    -    Services.obs.addObserver(this, "on-datatransfer-available");
    
    73
    -  } catch (e) {
    
    74
    -    this.logger.log(5, "Failed to register drag observer");
    
    73
    +  if (MAIN_PROCESS) {
    
    74
    +    // We want to update our status in the main process only, in order to
    
    75
    +    // serve the same opaque drag payload in every process.
    
    76
    +    try {
    
    77
    +      Services.obs.addObserver(this, "on-datatransfer-available");
    
    78
    +    } catch (e) {
    
    79
    +      this.logger.log(5, "Failed to register drag observer");
    
    80
    +    }
    
    75 81
       }
    
    76 82
     }
    
    77 83
     
    
    ... ... @@ -109,23 +115,38 @@ DragDropFilter.prototype = {
    109 115
           const types = aDataTransfer.mozTypesAt(i);
    
    110 116
           for (const type of types) {
    
    111 117
             this.logger.log(3, `Type is: ${type}.`);
    
    112
    -        if (
    
    113
    -          URLISH_TYPES.includes(type) ||
    
    114
    -          ((type === "text/plain" || type === "text/html") &&
    
    115
    -            hasURLish(aDataTransfer.getData(type)))
    
    116
    -        ) {
    
    118
    +        if (URLISH_TYPES.includes(type)) {
    
    117 119
               this.logger.log(
    
    118 120
                 3,
    
    119
    -            `Removing transfer data ${aDataTransfer.getData(type)}`
    
    121
    +            `Removing transfer data ${aDataTransfer.mozGetDataAt(type, i)}`
    
    120 122
               );
    
    123
    +          const urlType = "text/x-moz-url";
    
    124
    +          // Fallback url type, to be parsed by this browser but not externally
    
    125
    +          const INTERNAL_FALLBACK = "application/x-torbrowser-opaque";
    
    126
    +          if (types.contains(urlType)) {
    
    127
    +            const link = aDataTransfer.mozGetDataAt(urlType, i);
    
    128
    +            const opaqueKey = OpaqueDrag.store(link, urlType);
    
    129
    +            aDataTransfer.mozSetDataAt(INTERNAL_FALLBACK, opaqueKey, i);
    
    130
    +          }
    
    121 131
               for (const type of types) {
    
    122
    -            aDataTransfer.clearData(type);
    
    132
    +            if (
    
    133
    +              type !== INTERNAL_FALLBACK &&
    
    134
    +              type !== "text/x-moz-place" // don't touch bookmarks
    
    135
    +            ) {
    
    136
    +              aDataTransfer.mozClearDataAt(type, i);
    
    137
    +            }
    
    123 138
               }
    
    124 139
               break;
    
    125 140
             }
    
    126 141
           }
    
    127 142
         }
    
    128 143
       },
    
    144
    +
    
    145
    +  opaqueDrag: {
    
    146
    +    get(opaqueKey) {
    
    147
    +      return OpaqueDrag.retrieve(opaqueKey);
    
    148
    +    },
    
    149
    +  },
    
    129 150
     };
    
    130 151
     
    
    131 152
     // Assign factory to global object.