Additional adjustments to URL handling
Follow-up to df40ee7216
- Restore opening of non-HTTP URL schemes in link attachments
- Remove scheme whitelist for link attachments, since it's not enforced
via the API anyway and we prompt before an external application is
opened. Instead, just block a few schemes (e.g., 'javascript') from
launching.
TODO:
- Provide some way to change/reset an application association if the
user checks the box to automatically open that scheme.
- Show an error message if a link attachment with an invalid URL is
double-clicked
This commit is contained in:
parent
8172f00941
commit
3d2afa9c7f
4 changed files with 33 additions and 23 deletions
|
@ -606,24 +606,13 @@ Zotero.Attachments = new function(){
|
|||
var title = options.title;
|
||||
var collections = options.collections;
|
||||
|
||||
/* Throw error on invalid URLs
|
||||
We currently accept the following protocols:
|
||||
PersonalBrain (brain://)
|
||||
DevonThink (x-devonthink-item://)
|
||||
Notational Velocity (nv://)
|
||||
MyLife Organized (mlo://)
|
||||
Evernote (evernote://)
|
||||
OneNote (onenote://)
|
||||
Kindle (kindle://)
|
||||
Logos (logosres:)
|
||||
Bear (bear://)
|
||||
MarginNote (marginnoteapp://)
|
||||
Zotero (zotero://) */
|
||||
|
||||
var urlRe = /^((https?|zotero|evernote|onenote|brain|nv|mlo|kindle|x-devonthink-item|bear|marginnoteapp|ftp):\/\/|logosres:)[^\s]*$/;
|
||||
var matches = urlRe.exec(url);
|
||||
var matches = url.match(/^([a-z]+):(\/\/)?.+/);
|
||||
if (!matches) {
|
||||
throw ("Invalid URL '" + url + "' in Zotero.Attachments.linkFromURL()");
|
||||
throw new Error(`Invalid URL '${url}'`);
|
||||
}
|
||||
var scheme = matches[1];
|
||||
if (['javascript', 'data', 'chrome', 'resource', 'mailto'].includes(scheme)) {
|
||||
throw new Error(`Invalid scheme '${scheme}'`);
|
||||
}
|
||||
|
||||
// If no title provided, figure it out from the URL
|
||||
|
|
|
@ -187,7 +187,8 @@ Zotero.Utilities = {
|
|||
isHTTPURL: function (url, allowNoScheme = false) {
|
||||
// From https://stackoverflow.com/a/3809435
|
||||
var noSchemeRE = /^[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
|
||||
return /^https?:\/\//.test(url) || (allowNoScheme && noSchemeRE.test(url));
|
||||
return /^https?:\/\//.test(url)
|
||||
|| (allowNoScheme && !url.startsWith('mailto:') && noSchemeRE.test(url));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1023,17 +1023,32 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
|||
|
||||
|
||||
/**
|
||||
* Launch an HTTP URL externally, the best way we can
|
||||
*
|
||||
* Used only by Standalone
|
||||
* Launch a URL externally, the best way we can
|
||||
*/
|
||||
this.launchURL = function (url) {
|
||||
if (!Zotero.Utilities.isHTTPURL(url)) {
|
||||
if (Zotero.Utilities.isHTTPURL(url, true)) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
// Launch non-HTTP URLs
|
||||
else {
|
||||
throw new Error("launchURL() requires an HTTP(S) URL");
|
||||
let matches = url.match(/^([a-z]+):/);
|
||||
if (!matches) {
|
||||
throw new Error(`Invalid URL '${url}'`);
|
||||
}
|
||||
let scheme = matches[1];
|
||||
if (['javascript', 'data', 'chrome', 'resource'].includes(scheme)) {
|
||||
throw new Error(`Invalid scheme '${scheme}'`);
|
||||
}
|
||||
let svc = Components.classes['@mozilla.org/uriloader/external-protocol-service;1']
|
||||
.getService(Components.interfaces.nsIExternalProtocolService);
|
||||
let found = {};
|
||||
let handlerInfo = svc.getProtocolHandlerInfoFromOS(scheme, found);
|
||||
if (!found.value) {
|
||||
throw new Error(`Handler not found for '${scheme}' URLs`);
|
||||
}
|
||||
svc.loadURI(Services.io.newURI(url, null, null));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1058,7 +1073,8 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
|||
|
||||
let exec = Zotero.File.pathToFile(path);
|
||||
if (!exec.exists()) {
|
||||
throw ("Fallback executable not found -- check extensions.zotero." + pref + " in about:config");
|
||||
throw new Error("Fallback executable not found -- "
|
||||
+ "check extensions.zotero." + pref + " in about:config");
|
||||
}
|
||||
|
||||
var proc = Components.classes["@mozilla.org/process/util;1"]
|
||||
|
|
|
@ -55,6 +55,10 @@ describe("Zotero.Utilities", function() {
|
|||
assert.isFalse(Zotero.Utilities.isHTTPURL('file:///c:/path/to/file.txt'));
|
||||
});
|
||||
|
||||
it("should return false for mailto URLs in allowNoScheme mode", function () {
|
||||
assert.isFalse(Zotero.Utilities.isHTTPURL('mailto:foo@example.com', true));
|
||||
});
|
||||
|
||||
it("should return false for zotero: URL", function () {
|
||||
assert.isFalse(Zotero.Utilities.isHTTPURL('zotero://select/library/items/AAAAAAAA'));
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue