Closed Bug 978995 Opened 6 years ago Closed 6 years ago

Stop exporting symbols from xpconnect

Categories

(Core :: XPConnect, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla30

People

(Reporter: ehsan, Assigned: ehsan)

Details

Attachments

(1 file)

No description provided.
Assignee: nobody → ehsan
Attachment #8384889 - Flags: review?(bobbyholley)
Comment on attachment 8384889 [details] [diff] [review]
Stop exporting symbols from xpconnect

Review of attachment 8384889 [details] [diff] [review]:
-----------------------------------------------------------------

r=me with the below fixed.

::: js/xpconnect/src/nsXPConnect.cpp
@@ +237,1 @@
>  xpc::SystemErrorReporterExternal(JSContext *cx, const char *message,

Please remove this function entirely, and move any consumers over to SystemErrorReporter.
Attachment #8384889 - Flags: review?(bobbyholley) → review+
https://hg.mozilla.org/mozilla-central/rev/0330b013cc66
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla30
Guys, I need your help. I am using Gecko SDK (from XULRunner) to build my own application by including header files and using Gecko libs. Among other things I am using nsCxPusher when calling scripts, but with this change my application could not be built using Gecko SDK v.30, because linker cannot find nsCxPusher::Push(struct JSContext *) and mozilla::AutoCxPusher::~AutoCxPusher(void).
If I don't use nsCxPusher then I cannot get some property values (i.e. document.location).
Please let me know if there is some other way to do what I need.
You should not interact with the JS engine or the DOM from C++. You should create a JS-implemented XPCOM Component and do it there.
(In reply to Bobby Holley (:bholley) from comment #6)
> You should not interact with the JS engine or the DOM from C++. You should
> create a JS-implemented XPCOM Component and do it there.

But I really need to do this from C++. It worked for me for years (since Gecko SDK 1.9) and this change is the only issue. I am sorry, but I don't understand how JS-implemented component will help me to get the needed information (i.e. document.location object) in the C++ code.
(In reply to Denis from comment #7)
> (In reply to Bobby Holley (:bholley) from comment #6)
> > You should not interact with the JS engine or the DOM from C++. You should
> > create a JS-implemented XPCOM Component and do it there.
> 
> But I really need to do this from C++. It worked for me for years (since
> Gecko SDK 1.9) and this change is the only issue.

This really hasn't been safe for a long time, and it was probably causing crashes and other stability issues in your app. :-(

> I am sorry, but I don't
> understand how JS-implemented component will help me to get the needed
> information (i.e. document.location object) in the C++ code.

The idea is to use an XPIDL interface to interact with JS (your JS) from C++, and then the JS interacts with the DOM. You'd create some interface (nsILocationToucher), implement that interface from your JS-implemented component, and then use the component as glue between your C++ and the DOM.
There were stability issues at the early stages of development because I did not knew all the necessary details of Gecko usage, but all they were successfully fixed and now my application works stable. The point is that my application is a some kind of testing tool that gives read-write access to all internals of web page, so if I get you right it will be very difficult to make JS-proxy for all the objects I need to work with. Actually I found a workaround: I get location through the document window - it works for me now. But I am afraid this change may cause some other issues to me in the future, so I really want to find some better solution. I think this change significantly affects Gecko SDK usage, though for me it does not seem to be very important for Firefox development.
Anyway thank you very much for your replies.
I'm on the same page with Denis, and why would you actively kill that support does it disturb anyone to have this export?
We are also relying on that.
I don't care that much, whether you keep the interfaces stable as long as they are there.
Of course it would be nice to have them stable. But as long as you know what you're doing (or you can guess good enough) it's fine :)
(In reply to Reinhold Degenfellner from comment #10)
> I'm on the same page with Denis, and why would you actively kill that
> support does it disturb anyone to have this export?

Because I would rather that such apps break at compile time, so that people come and find this bug, and we can point them to the right thing. The alternative just lets people write unsafe code without realizing it.

> We are also relying on that.
> I don't care that much, whether you keep the interfaces stable as long as
> they are there.
> Of course it would be nice to have them stable. But as long as you know what
> you're doing (or you can guess good enough) it's fine :)

No, it's not. Going forward, the steps required to safely interact with the JS engine in Gecko are quite involved, and make use of a number of RAII classes that aren't possible to use externally. The supported way to interact with JS from external C++ is via an XPCOM component.
I basically get your point. My problem is that the "supported" way is also not very well documented and the "unsupported" one was working for us starting from FF 4.0 (honestly not for 15 and 16, still don't know why). And we are well aware of the RAII mechanics as this caused some issues in the past when moving foward.
Can I do the supported way without linking xulrunner or just without mozjs?
I found several sources on JS XPCOM but I don't think I understand how I would expose those interfaces to C++.
Do you know the links that explain that?
thx
(In reply to Bobby Holley (:bholley) from comment #11)
> Because I would rather that such apps break at compile time, so that people
> come and find this bug, and we can point them to the right thing. The
> alternative just lets people write unsafe code without realizing it.

What you mean by saying "unsafe code"? Is this because of a security concern or application stability?
Our code is working stable for years (the same thing Reinhold says), and the security is not affected in my case. Maybe in the future when all the incoming JS engine changes will be landed it will became unsafe but for now it is working really fine. So I don't see any reason to make "such apps break at compile time". Why do you want to fix something that is not broken?
(In reply to Denis from comment #14)
> (In reply to Bobby Holley (:bholley) from comment #11)
> > Because I would rather that such apps break at compile time, so that people
> > come and find this bug, and we can point them to the right thing. The
> > alternative just lets people write unsafe code without realizing it.
> 
> What you mean by saying "unsafe code"? Is this because of a security concern
> or application stability?

Both.

> Our code is working stable for years (the same thing Reinhold says)

Even if yours is, lots of others aren't. We've seen tons of crashes on stability telemetry related to binary components trying to hook into JSAPI. Often times it relates to the interaction between two external components that each work fine by themselves. It's not something we want people doing.

> security is not affected in my case.

If you're building something other than a web browser from scratch, you can just re-export the symbols yourself. If you're trying to link into pre-built Firefox binaries shipped by Mozilla, then security is affected as far as I'm concerned.

> Maybe in the future when all the
> incoming JS engine changes will be landed it will became unsafe but for now
> it is working really fine. So I don't see any reason to make "such apps
> break at compile time". Why do you want to fix something that is not broken?

See the above part about preventing crashes caused by binary components. Also, to avoid wasting peoples' time trying to keep up with an ever-changing landscape of undocumented JSAPI interaction changes, when I know that in the long run they will need to do what I suggest in comment 11.
Ok, I see. Thanks again.
(In reply to Denis from comment #16)
> Ok, I see. Thanks again.

Thanks for understanding! Let me know if you run into any trouble with the JS-implemented component. :-)
The links you provided are basically about implementing something in JS. What I can't find is how we can access these interfaces via native (c++) code. Is it sufficient to just include the generated headers and the rest happens automagically?

(In reply to Bobby Holley (:bholley) from comment #17)
> (In reply to Denis from comment #16)
> > Ok, I see. Thanks again.
> 
> Thanks for understanding! Let me know if you run into any trouble with the
> JS-implemented component. :-)
(In reply to Reinhold Degenfellner from comment #18)
> The links you provided are basically about implementing something in JS.

Yes.

> What I can't find is how we can access these interfaces via native (c++)
> code.

That is not supported.

The whole point of this approach is that you access these interfaces from JS (which is supported), and communicate with between your JS and C++ using a JS-implemented XPCOM component.
so doing something like this:
nsCOMPtr<nsIObserver> pJavaScriptBridge = do_CreateInstance("@borland.com/javascriptbridgecomponent;1", &result);
      if (NS_SUCCEEDED(result))
      {
        pJavaScriptBridge->Observe(0, "initialize", 0);
      }
is not supported? although it works? the only downside here is that I'm not able to make it work with a custom interface (nsIObserver is provided by the sdk)
(In reply to Reinhold Degenfellner from comment #20)
> so doing something like this:
> nsCOMPtr<nsIObserver> pJavaScriptBridge =
> do_CreateInstance("@borland.com/javascriptbridgecomponent;1", &result);
>       if (NS_SUCCEEDED(result))
>       {
>         pJavaScriptBridge->Observe(0, "initialize", 0);
>       }
> is not supported?

That's definitely supported. What's not supported is touching Gecko-internal DOM interfaces (like nsINode or nsIDocument) from C++.

> the only downside here is that I'm not
> able to make it work with a custom interface (nsIObserver is provided by the
> sdk)

This should work, FWIW. See [1] for information about compiling your interfaces to typelibs+headers.

[1] https://developer.mozilla.org/en-US/docs/Mozilla/XPIDL/pyxpidl
I've just saw the message in the Firefox console - "The Components object is deprecated. It will soon be removed.". Does it mean that XPCOM components are deprecated? If it does, then what is the replacement for them?
(In reply to Denis from comment #22)
> I've just saw the message in the Firefox console - "The Components object is
> deprecated. It will soon be removed.". Does it mean that XPCOM components
> are deprecated? If it does, then what is the replacement for them?

No, that message is only triggered when accessing |Components| from untrusted content (like a web page). Components for System-Principaled globals is here to stay.
You need to log in before you can comment on or make changes to this bug.