Pier Angelo Vendrame pushed to branch tor-browser-102.5.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
d84fac57
by hackademix at 2022-12-17T13:28:36+00:00
-
a1ee91a6
by hackademix at 2022-12-17T13:28:36+00:00
5 changed files:
- browser/components/places/PlacesUIUtils.jsm
- browser/components/places/content/controller.js
- dom/base/ContentAreaDropListener.jsm
- toolkit/components/places/PlacesUtils.jsm
- toolkit/torbutton/components/dragDropFilter.js
Changes:
| ... | ... | @@ -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() {
|
| ... | ... | @@ -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 |
| ... | ... | @@ -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")
|
| ... | ... | @@ -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:
|
| ... | ... | @@ -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.
|