Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

eval from XPCOM in FF3

5 views
Skip to first unread message

jas...@t-online.hu

unread,
Aug 6, 2008, 9:06:21 AM8/6/08
to
Hi,

I have a javascript XPCOM component, and in FF3 this code just does
not work: (in FF2 it works fine)

eval.call(obj, source)
I get a NS_ERROR_XPC_NOT_ENOUGH_ARGS exception. (in a try/catch block)

This is for loading/evaulating javascript code into the web page/
context of the content window (obj is a window reference, source is
the script to be loaded). The javascript must be runnig in the web
page, because it has analizing functions (e.g. counts the amount of
different html elements in every frame of the actual web page). There
is a toolbar button for the component, and when it is clicked the
javascript code should be loaded into the web page and the functions
should be running, then the component would process the information
gathered.

Note, that obj.eval(source) was not even working in FF2 (it gives this
error : function eval must be called directly, and not by way of a
function)


Any help would be appreciated.


PS
I tried to use evalinsandbox, but could not make it work. The
javascript objects/functions would not become members of the actual
window. (I have namespaced functions in the javascript code, like
x.y.x = function() { ...}, maybe that is a problem for the sandbox?)

The eval.call() works for the chrome (browser.xul), though, but it
does not help me.
I heard the tigthened security in FF3, but could not find any solution
for my problem.


Thanks,

giorgio71


John J. Barton

unread,
Aug 6, 2008, 10:52:53 AM8/6/08
to
jas...@t-online.hu wrote:
> Hi,
>
> I have a javascript XPCOM component, and in FF3 this code just does
> not work: (in FF2 it works fine)
>
> eval.call(obj, source)
> I get a NS_ERROR_XPC_NOT_ENOUGH_ARGS exception. (in a try/catch block)

I've not seen this method, but any way I don't believe eval has anything
to do with your problem.

>
> This is for loading/evaulating javascript code into the web page/
> context of the content window (obj is a window reference, source is

Compiling code into the scope of the web page from an extension can be
done by appending a 'script' tag to the page. See lib.js, addScript in
Firebug,
http://fbug.googlecode.com/svn/branches/firebug1.2/content/firebug/lib.js

> the script to be loaded). The javascript must be runnig in the web
> page, because it has analizing functions (e.g. counts the amount of
> different html elements in every frame of the actual web page). There

Well, this work could (and I think should) be done by operating on the
DOM from the extension rather than by code injection.

> is a toolbar button for the component, and when it is clicked the
> javascript code should be loaded into the web page and the functions
> should be running, then the component would process the information
> gathered.
>
> Note, that obj.eval(source) was not even working in FF2 (it gives this
> error : function eval must be called directly, and not by way of a
> function)

That hasn't worked in a long time. You only need "eval(source)", and you
need "source" to carry the scope changes.

>
>
> Any help would be appreciated.
>
>
> PS
> I tried to use evalinsandbox, but could not make it work. The
> javascript objects/functions would not become members of the actual
> window. (I have namespaced functions in the javascript code, like
> x.y.x = function() { ...}, maybe that is a problem for the sandbox?)

I wasn't successful with evalInSandbox either, but you can do some
things with it some of the time. Partly I think the problem is that
exactly what one wants from evalInSandbox is unclear.

In FF3, extensions get a read-only, write-silent-fail copy of the web
page window object. You can write properties on this window in the scope
of your extension, and you can read them back in your extension. But
they are not visible to the web page. So don't write any properties (or
set any functions on) any web page object.

John.

Boris Zbarsky

unread,
Aug 6, 2008, 11:37:23 AM8/6/08
to
John J. Barton wrote:
> In FF3, extensions get a read-only, write-silent-fail copy of the web
> page window object. You can write properties on this window in the scope
> of your extension, and you can read them back in your extension. But
> they are not visible to the web page.

That's just a result of holding an XPCNativeWrapper, no? Does
initializing the sandbox with the .wrappedJSObject of the content window
work better?

-Boris

jas...@t-online.hu

unread,
Aug 6, 2008, 11:40:39 AM8/6/08
to
On Aug 6, 4:52 pm, "John J. Barton" <johnjbar...@johnjbarton.com>
wrote:

> jas...@t-online.hu wrote:
> > Hi,
>
> > I have a javascript XPCOM component, and in FF3 this code just does
> > not work: (in FF2 it works fine)
>
> > eval.call(obj, source)
> > I get a NS_ERROR_XPC_NOT_ENOUGH_ARGS exception. (in a try/catch block)
>
> I've not seen this method, but any way I don't believe eval has anything
> to do with your problem.
>
>
>
> > This is for loading/evaulating javascript code into the web page/
> > context of the content window (obj is a window reference, source is
>
> Compiling code into the scope of the web page from an extension can be
> done by appending a 'script' tag to the page.  See lib.js, addScript in
> Firebug,http://fbug.googlecode.com/svn/branches/firebug1.2/content/firebug/li...

I know, but I cannot change the source of the web page, so I need
runtime injection.

>
> > the script to be loaded). The javascript must be runnig in the web
> > page, because it has analizing functions (e.g. counts the amount of
> > different html elements in every frame of the actual web page). There
>
> Well, this work could (and I think should) be done by operating on the
> DOM from the extension rather than by code injection.

Agree, that was a sloppy example, not exactly what I do.

>
> > is a toolbar button for the component, and when it is clicked the
> > javascript code should be loaded into the web page and the functions
> > should be running, then the component would process the information
> > gathered.
>
> > Note, that obj.eval(source) was not even working in FF2 (it gives this
> > error : function eval must be called directly, and not by way of a
> > function)
>
> That hasn't worked in a long time. You only need "eval(source)", and you
> need "source" to carry the scope changes.
>
>
>
> > Any help would be appreciated.
>
> > PS
> > I tried to use evalinsandbox, but could not make it work. The
> > javascript objects/functions would not become members of the actual
> > window. (I have namespaced functions in the javascript code, like
> > x.y.x = function() { ...}, maybe that is a problem for the sandbox?)
>
> I wasn't successful with evalInSandbox either, but you can do some
> things with it some of the time.  Partly I think the problem is that
> exactly what one wants from evalInSandbox is unclear.
>
> In FF3, extensions get a read-only, write-silent-fail copy of the web
> page window object. You can write properties on this window in the scope
> of your extension, and you can read them back in your extension. But
> they are not visible to the web page. So don't write any properties (or
> set any functions on) any web page object.
>

Would you please explain what is this "copy object", how to get or
access this object and if it is read-only, then how could I give
properties to it? (I just do not get it, if something is read-only it
means it cannot be changed.)
Maybe I could inject my scripts into this object? I do not care if it
is a copy, guess what, it is the better, becasue this guarantees that
the original web page will remain intact.


What I have now, is this:
the toolbar button's onclick handler can access the window.content
object (this is the top frame of the web page) and sends it to the
component, then the component can walk through the window hierarchy
and load the scripts into every frame. (as described above it works in
FF2)

Thanks, John

> John.

Sergey Yanovich

unread,
Aug 6, 2008, 11:53:47 AM8/6/08
to

Not sure what 'sandbox' means here, but anyway I can confirm that I am
able to manipulate any window of my xul application from JS XPCOM using
.wrappedJSObject on it.

--
Sergey Yanovich

John J. Barton

unread,
Aug 6, 2008, 12:04:45 PM8/6/08
to
jas...@t-online.hu wrote:
> On Aug 6, 4:52 pm, "John J. Barton" <johnjbar...@johnjbarton.com>
> wrote:
...

>> Compiling code into the scope of the web page from an extension can be
>> done by appending a 'script' tag to the page. See lib.js, addScript in
>> Firebug,http://fbug.googlecode.com/svn/branches/firebug1.2/content/firebug/li...
>
> I know, but I cannot change the source of the web page, so I need
> runtime injection.

addScript does runtime code injection so I'm not sure what you mean.
...


>> In FF3, extensions get a read-only, write-silent-fail copy of the web
>> page window object. You can write properties on this window in the scope
>> of your extension, and you can read them back in your extension. But
>> they are not visible to the web page. So don't write any properties (or
>> set any functions on) any web page object.
>>
>
> Would you please explain what is this "copy object", how to get or
> access this object and if it is read-only, then how could I give
> properties to it? (I just do not get it, if something is read-only it
> means it cannot be changed.)

Sorry I don't know exactly what to call this thing. It is readable, and
you can write on it, but the web page cannot read what you write.
(Personally I think it should be read only, but I didn't convince the
developers of this). But the bottom line as far as I can see, don't add
properties to web page window object in extensions.

> Maybe I could inject my scripts into this object? I do not care if it
> is a copy, guess what, it is the better, becasue this guarantees that
> the original web page will remain intact.

Sorry, you're not making sense. What is "the original web page"? There
is only the page state in the browser. It is created by Firefox by
reading the HTML from a server. Then you want to change it. You can do
that by using DOM operations. One DOM operation is to add a tag. One tag
is 'script' which will cause code to be added to the state of the page.
You can't add code to the state of the page without altering the state
of the page, adding code is altering.

John J. Barton

unread,
Aug 6, 2008, 12:15:58 PM8/6/08
to
Boris Zbarsky wrote:
> John J. Barton wrote:
>> In FF3, extensions get a read-only, write-silent-fail copy of the web
>> page window object. You can write properties on this window in the
>> scope of your extension, and you can read them back in your extension.
>> But they are not visible to the web page.
>
> That's just a result of holding an XPCNativeWrapper, no? Does

Yes, the proper way to say this is: in an extension you get a wrapped
object. You can read the properties of the wrapped object and get the
object's properties. But if you write properties they are written on the
wrapper (which I think is a bug) and thus never seen by the web page
(which is good, exactly what you want).

> initializing the sandbox with the .wrappedJSObject of the content window
> work better?

Dolske played with this for a bit and the closest he got was:
sandbox.__proto__ = win.wrappedJSObject;
But then we hit one more case and I threw in the towel. We had put a lot
of time into evalInSandbox and each time another case would fail. With
the script injection I could be more confident that we understood what
could happen and how to debug failures. In addition, every time you
issue win.wrappedJSObject you have to be very careful because the
unwrapped object is a security risk.

>
> -Boris

jas...@t-online.hu

unread,
Aug 6, 2008, 12:30:30 PM8/6/08
to
On Aug 6, 6:04 pm, "John J. Barton" <johnjbar...@johnjbarton.com>

wrote:
> jas...@t-online.hu wrote:
> > On Aug 6, 4:52 pm, "John J. Barton" <johnjbar...@johnjbarton.com>
> > wrote:
> ...
> >> Compiling code into the scope of the web page from an extension can be
> >> done by appending a 'script' tag to the page.  See lib.js, addScript in
> >> Firebug,http://fbug.googlecode.com/svn/branches/firebug1.2/content/firebug/li...
>
> > I know, but I cannot change the source of the web page, so I need
> > runtime injection.
>
> addScript does runtime code injection so I'm not sure what you mean.
> ...
>
It adds script tags to the source, I do not want to change the source,
while using eval, it does not change the source, but creates my
javascript objects and functions attached to the given window. Yes it
changes the web page as well.We should focus on this. I have to use
eval or something similar, I thought evalinsandbox is the same. It
gets a copy of the original window, and puts it in the sandbox, so it
is isolated from the real web page.
But this does not seem to work either, not even in FF2. See below.

> >> In FF3, extensions get a read-only, write-silent-fail copy of the web
> >> page window object. You can write properties on this window in the scope
> >> of your extension, and you can read them back in your extension. But
> >> they are not visible to the web page. So don't write any properties (or
> >> set any functions on) any web page object.
>
> > Would you please explain what is this "copy object", how to get or
> > access this object and if it is read-only, then how could I give
> > properties to it? (I just do not get it, if something is read-only it
> > means it cannot  be changed.)
>
> Sorry I don't know exactly what to call this thing. It is readable, and
> you can write on it, but the web page cannot read what you write.
> (Personally I think it should be read only, but I didn't convince the
> developers of this).  But the bottom line as far as I can see, don't add
> properties to web page window object in extensions.
>
> > Maybe I could inject my scripts into this object? I do not care if it
> > is a copy, guess what, it is the better, becasue this guarantees that
> > the original web page will remain intact.
>
> Sorry, you're not making sense.  What is "the original web page"? There
> is only the page state in the browser. It is created by Firefox by
> reading the HTML from a server. Then you want to change it. You can do
> that by using DOM operations. One DOM operation is to add a tag. One tag
> is 'script' which will cause code to be added to the state of the page.
> You can't add code to the state of the page without altering the state
> of the page, adding code is altering.

I might making not sense, but you are talking about a "copy", so if it
is a copy, then there must be an original, I guess.

Please would somebody tell me why eval.call(obj, source) does not work
in FF3, and what should I use instead of it?
Maybe it is a security risk in FF3 to use eval on the web page, but
it works from firebug console. Could not find out how they do it...

Anyway, this is what does not working for me

function MyEval(_window, source)
{
eval.call(_window, source);
//_window.eval(source); //not works even in FF2
/*
var safeWindow = new XPCNativeWrapper(_window);
var sandbox = new Components.utils.Sandbox(safeWindow);
sandbox.window = safeWindow;
sandbox.document = sandbox.window.document;
sandbox.unsafeWindow = _window;
sandbox.__proto__ = sandbox.window;
//var scriptToEval = "(function(){"+source+"})()";
var scriptToEval = source;
var result;
try
{
result = Components.utils.evalInSandbox(scriptToEval,
sandbox);
alert("myeval result\n" + result);
}
*/
}

I cannot see my javascript objects neither in _window nor
sandbox.window
Sometimes result contains only the last function in the file,
sometimes it is empty. Not sure what is it for?


Sergey Yanovich

unread,
Aug 6, 2008, 12:51:18 PM8/6/08
to
jas...@t-online.hu wrote:
> I have a javascript XPCOM component, and in FF3 this code just does
> not work: (in FF2 it works fine)
>
> eval.call(obj, source)
> I get a NS_ERROR_XPC_NOT_ENOUGH_ARGS exception. (in a try/catch block)

I am practically sure, that your problem is with the script you are
adding, and not with eval.call().

NS_ERROR_XPC_NOT_ENOUGH_ARGS has nothing to do with security. Your
script is probably using an UNFROZEN interface, which method began to
receive an extra parameter in FF3.

--
Sergey Yanovich

Boris Zbarsky

unread,
Aug 6, 2008, 12:55:11 PM8/6/08
to
jas...@t-online.hu wrote:
>> addScript does runtime code injection so I'm not sure what you mean.
>>
> It adds script tags to the source

No, it adds them to the DOM. That's not the same thing. Furthermore,
you can remove the script tag as soon as it's executed, if you want.

> I might making not sense, but you are talking about a "copy", so if it
> is a copy, then there must be an original, I guess.

There is no copy. There is an object that shadows certain properties of
the Window.

> Please would somebody tell me why eval.call(obj, source) does not work
> in FF3, and what should I use instead of it?

I suspect you're asking in the wrong newsgroup. I suggest the JS engine
newsgroup, or perhaps .dom.

> var safeWindow = new XPCNativeWrapper(_window);
> var sandbox = new Components.utils.Sandbox(safeWindow);
> sandbox.window = safeWindow;
> sandbox.document = sandbox.window.document;
> sandbox.unsafeWindow = _window;
> sandbox.__proto__ = sandbox.window;

See... you actually want _window.wrappedJSObject all the places where
you use safeWindow, if you expect the web page to see your stuff. Of
course keep in mind that the web page will also be able to affect your
script execution, so you have to be a little careful.

-Boris

jas...@t-online.hu

unread,
Aug 6, 2008, 4:45:19 PM8/6/08
to
On Aug 6, 6:51 pm, Sergey Yanovich <ynv...@gmail.com> wrote:
> jas...@t-online.hu wrote:
> > I have a javascript XPCOM component, and in FF3 this code just does
> > not work: (in FF2 it works fine)
>
> > eval.call(obj, source)
> > I get a NS_ERROR_XPC_NOT_ENOUGH_ARGS exception. (in a try/catch block)
>
> I am practically sure, that your problem is with the script you are
> adding, and not with eval.call().
>

It is the very same script what I add to FF2, so why would it be a
problem for FF3 to evalutate?

> NS_ERROR_XPC_NOT_ENOUGH_ARGS has nothing to do with security. Your
> script is probably using an UNFROZEN interface, which method began to
> receive an extra parameter in FF3.
>

The only interface is used: nsisupports.

As I said before, I get the exception here
try{
eval.call(obj, source);
}catch(e){
alert(e) -> NS_ERROR_XPC_NOT_ENOUGH_ARGS
}


Thanks, though

> --
> Sergey Yanovich

Boris Zbarsky

unread,
Aug 6, 2008, 5:16:52 PM8/6/08
to
jas...@t-online.hu wrote:
> alert(e) -> NS_ERROR_XPC_NOT_ENOUGH_ARGS

You do realize "XPC" is "XPConnect", not "XPCOM", right?

-Boris

jas...@t-online.hu

unread,
Aug 7, 2008, 6:30:24 AM8/7/08
to

Now I do, so what does it have to do with the issue?

Sergey Yanovich

unread,
Aug 7, 2008, 9:36:36 AM8/7/08
to
jas...@t-online.hu wrote:
> On Aug 6, 6:51 pm, Sergey Yanovich <ynv...@gmail.com> wrote:
> It is the very same script what I add to FF2, so why would it be a
> problem for FF3 to evalutate?
>
>> NS_ERROR_XPC_NOT_ENOUGH_ARGS has nothing to do with security. Your
>> script is probably using an UNFROZEN interface, which method began to
>> receive an extra parameter in FF3.

The quoted passage answers your question.

BTW, what do you see in the error console (I mean JavaScript error
console) when you try to add your script?

--
Sergey Yanovich

Boris Zbarsky

unread,
Aug 7, 2008, 1:18:59 PM8/7/08
to
jas...@t-online.hu wrote:
> Now I do, so what does it have to do with the issue?

It means you're asking in the wrong place, and if you want to get useful
answers (and in particular if you want people who might know something
about your problem to see the question) you should be asking in the
newsgroups I suggested in my message dated "8/6/08 12:55 PM".

-Boris

jas...@t-online.hu

unread,
Aug 9, 2008, 7:58:11 AM8/9/08
to

If I do not use try/catch then no error occurs, nothing in the Error
Console or in Firebug console. However my javascript object appears in
the DOM but it is undefined (I can see it in Firebug DOM window). This
means the eval fails to work without error message.

I have to tell you guys, there is no helpful thoughts in this thread,
so I try to summarize the issue again

- what I want to do needs to work with any web page (that is why I
cannot use the libs recommended above, because to use those libs, you
need to include them first, but I obviously cannot do it, neither do
not want)
- I need to use eval (or something equivalent to it) to load the
scripts (you can think of what greasemonkey does with the user
scripts, however I do not want to alter the web page just load my
scripts and run them)
- the eval.call(obj, source) in try/catch block gives the error
NS_ERROR_XPC_NOT_ENOUGH_ARGS in FF3, it works in FF2, without try/
catch see a few lines above
- obviously I want to use the same scripts in FF2 or FF3, so the
script is fine (unless eval has problems with it only in FF3, see
below)
- the component is written in javascript and uses 1 interface, which
is not unfrozen, it is nsISupports

Maybe it is the window type which causes the problem. I might not use
the eval on this type of window?

I get the top window reference from the overlay
<toolbarbutton>
..
oncommand="ButtonClick()"
</toolbarbutton>


//helper class
function WrapperClass(object)
{
this.wrappedJSObject = this;
this.object = object;
}

function ButtonClick()
{
var win = new WrapperClass(window.content);
var comp = Component.classes[<mycomponent>]; //this is my
extension/component
comp.Set(win);
}

In the component :

function Set(win)
{
var topwindow = win.wrappedJSObject.object;

//Eventually I walk through the topwindow and all of its childs
then using eval.call, so the first eval.call is something like this
var source = "whatever";
eval.call(topwindow, source);
}

Any thoughts about it? I read that there are a few
XPCNativeSafeWrapperWhatever classes in FF3, should I use them?

All I want to know why this is happening in FF3, and how to fix this.

I am not a mozilla expert, I had created my extension, and it is
working in FF2, but not in FF3. I might have been lucky that it works
in FF2. But I need to make it work in FF3.
So, please help.

PS
Took the advice, posted the issue to js-engine, no answer so far

Thanks, again

giorgio71

John J. Barton

unread,
Aug 10, 2008, 11:32:50 AM8/10/08
to
jas...@t-online.hu wrote:
...

>
> I have to tell you guys, there is no helpful thoughts in this thread,
> so I try to summarize the issue again

Or are you choosing not to listen?

>
> - what I want to do needs to work with any web page (that is why I
> cannot use the libs recommended above, because to use those libs, you
> need to include them first, but I obviously cannot do it, neither do
> not want)

Code injection works on any page.

> - I need to use eval (or something equivalent to it) to load the
> scripts (you can think of what greasemonkey does with the user
> scripts, however I do not want to alter the web page just load my
> scripts and run them)

This statement still makes no sense. Greasemonkey alters the page. You
want to alter the page. Code injection alters the page. If you don't
like to have 'script' tags in the page after injection just take them out.

> - the eval.call(obj, source) in try/catch block gives the error
> NS_ERROR_XPC_NOT_ENOUGH_ARGS in FF3, it works in FF2, without try/
> catch see a few lines above

What works in FF2 is not relevant since the security mechanism is
completely different. There could be a bug in FF3 of course, so it would
be great if you can find the answer to the error message.

I'll repeat that I've never seen "eval.call()" used. The eval() op is
special, I suggest you use "eval('with (obj) {'+source+'}')";

> - obviously I want to use the same scripts in FF2 or FF3, so the
> script is fine (unless eval has problems with it only in FF3, see
> below)

code injection works in both FF2 and FF3.

> - the component is written in javascript and uses 1 interface, which
> is not unfrozen, it is nsISupports
>
> Maybe it is the window type which causes the problem. I might not use
> the eval on this type of window?

Yes, this is true, as I said before. You can't write on web page windows
from an extension directly.

...


> Any thoughts about it? I read that there are a few
> XPCNativeSafeWrapperWhatever classes in FF3, should I use them?

In FF3 the windows are wrapped automatically. If you unwrap them you are
exposing your users to security attack.

jas...@t-online.hu

unread,
Sep 18, 2008, 2:56:09 AM9/18/08
to
It turned out that the problem looks similar to
https://bugzilla.mozilla.org/show_bug.cgi?id=435151

The NS_ERROR_XPC_NOT_ENOUGH_ARGS error is not for the eval itself, but
for the code to be evaled. Eventually all of the new Something()
throws this exception.
The problem is eliminated when new Array() is replaced by [] and new
Object() is replaced by {}, however I have no idea how to replace new
Date() or new RegExp() or new MyClass()...

Not sure if this the desired behaviour, otherwise, please advise how
to proceed on.
Any ideas are welcome.


Regards,
jaszay

0 new messages