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.
|