Closed Bug 1249154 Opened 8 years ago Closed 7 years ago

No good way to access files from profile folder in content process

Categories

(Add-on SDK Graveyard :: General, defect)

defect
Not set
normal

Tracking

(e10s-)

RESOLVED INCOMPLETE
Tracking Status
e10s - ---

People

(Reporter: blask, Unassigned)

Details

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0
Build ID: 20160209234513

Steps to reproduce:

I tried to reference an image from outside of my add-on's xpi in the content process and struggled to get it to work. In this case it was a background set by the user, but I also create thumbnails and would like to have them referenced directly instead of sending them as big blob to the content process. I asked on discourse (https://discourse.mozilla-community.org/t/load-local-files-images-and-or-css-in-sdk-add-on/7080) but didn't get a good response.


Actual results:

I kind of got it to work with a chrome.manifest that points to a profile folder I create and where I copy the image, but needed to set "unpack" to true (to get the relative path working) which apparently is not recommended (see comment here: https://discourse.mozilla-community.org/t/load-local-files-images-and-or-css-in-sdk-add-on/7080/10?u=sblask)

My implementation is here: https://github.com/sblask/firefox-bookmark-dial/commit/5dbdc9c0cc665ea620d35f4e733bc51fb74818c8


Expected results:

It would be good to have an easy way to access files from a standardized add-on profile folder from a content process. Sure, I can read files in the main process and send them manually to the content process in a message, but that isn't easy and probably not very performant either. The solution should also work in WebExtensions obviously.
Component: Untriaged → WebExtensions
Product: Firefox → Toolkit
This isn't applicable to WebExtensions.
Component: WebExtensions → Untriaged
Product: Toolkit → Firefox
(In reply to Kris Maglione [:kmag] from comment #1)
> This isn't applicable to WebExtensions.

Could you explain why? Is there an API for it or does the restriction not exist? How would you go about displaying images on a content page that are not remote and do not come with the add-on either?
For one thing, WebExtensions don't have filesystem access, so files in the profile directory are not relevant to them.

Aside from that, all of your examples are very much about traditional extensions. A solution for WebExtensions would not be relevant to them.
There are some sandbox restrictions on MacOS that prevent access to certain paths in the profile. But since you're not on Mac, that isn't the problem. We also don't allow the content process to know what the location of the profile directory is. But that doesn't sound like your problem either.

We do have all sorts of security restrictions that prevent some URIs from loading other URIs. Those are unrelated to e10s or content processes.

I'm not very knowledgeable about the add-on SDK, but I would expect that this method would give you a URI that you could use:
https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/self#data.url%28name%29
tracking-e10s: --- → -
> I'm not very knowledgeable about the add-on SDK, but I would expect that
> this method would give you a URI that you could use:
> https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/self#data.
> url%28name%29

This gives me a resource:// url to the data directory of my addon's xpi. The stuff I do with the chrome.manifest gives me the same thing but to the profile folder. Which is fine for me, but seems a bit hacky to others.

I guess what I am asking for is a well defined exception to all the security restrictions(I am totally ignorant as to what they are and why they are in place) that is only valid for add-on pages.
Aren't these images that you're including in your extension package? Why would it be hacky to find them in the extension?

Or are you loading images from other places on the user's hard drive?
> Or are you loading images from other places on the user's hard drive?

Yes, exactly. The user can choose an image in the preferences, I copy it into the profile folder and then reference it the content page by resource:// url. And all of that is necessary because file:// urls are not accepted at all.
It's actually possible via undocumented SDK-API to register any path as a resource-URI which can be used wherever a resource-URI is allowed/needed. If that is considered a feature or a bug I am not sure yet…¹

    const resourceURI = require('sdk/uri/resource');
    const path = require('sdk/url').fromFilename(require('sdk/system').pathFor('ProfD'))
    resourceURI.mount('my-profile', path);
    // unmount isn't automatic
    const unload = require("sdk/system/unload").when;
    unload(() => resourceURI.unmount('my-profile'));

The profile is accessible as 'resource://my-profile/' then (not only from your extension, but globally, so namespace it carefully).

¹ I am not sure as it allows extensions like my unreleased https://github.com/DonKult/dotPageMod which kinda defeat the point of extension review and signing, even if similar extensions passed review/signing.
Has comment 8 helped resolve your concern? If not, I will find a component group to place this in for further assistance.
Flags: needinfo?(blask)
I guess for SDK add-ons yes, but I still wonder how I would for example load a local background image in a webextension.
Flags: needinfo?(blask)
We would like this to be reviewed and confirmed or WF by someone in Web Extensions, thanks.
Component: Untriaged → WebExtensions
Product: Firefox → Toolkit
(In reply to sblask from comment #10)
> I still wonder how I would for example load a local background image in a webextension.

In a Chrome extension you'd use (1) an HTML5 file input with `type="image/*"` on the 'Options' page to get a local file, (2) `FileReader.readAsDataURL` to convert it to a string, and (3) DOMStorage, WebSQL, IndexedDB, or FileSystem API to persist the string. On the 'newtab' override page you'd (4) retrieve the data URL from storage and (5) paste it into a stylesheet or into `*.style.backgroundImage`.

Alternatively you could (3a) persist the input as a Blob, then (4a) retrieve it as a Blob, (4b) create a URI for it with `URL.createObjectURL`, and (5a) use the blob: URI as the property value. (Or else persist it as a string, then convert it to a Blob, but some little cursing is involved.) This works because all of an extension's pages, including the override page, have the same origin. Passing the image as a Blob to any other page requires more trickiness [1].

[1] http://stackoverflow.com/questions/23847708/pass-large-blob-or-file-from-chrome-extension
[2] Bug 1234150 - Support chrome_url_overrides manifest field
(In reply to Michelle Funches - QA from comment #11)
> We would like this to be reviewed and confirmed or WF by someone in Web
> Extensions, thanks.

I can confirm that this will not be possible in WebExtensions because they do not have access to the file system. If the request is for WebExtensions to have file system access please file a bug for that.

Since this is about a particular SDK API, I'm moving it that component.
Component: WebExtensions → General
Product: Toolkit → Add-on SDK
Version: 44 Branch → unspecified
https://bugzilla.mozilla.org/show_bug.cgi?id=1399562
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.