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

instanceof fails on external Scriptable

6 views
Skip to first unread message

wolffiex

unread,
Sep 13, 2008, 8:22:54 PM9/13/08
to
Hi everyone,
I found a little surprising behavior today with Rhino. I don't know if
this is a bug; I'm hoping someone will weigh in. It appears that
instanceof doesn't work on objects from a foreign scope. I assume this
is because instanceof just looks up the prototype chain, but I wonder
if that is the correct implementation, given the fact that you can
pass objects from one scope to another using Rhino and Java. Here's my
little testcase:


import org.junit.Test;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

public class ObjectSurprise {
@Test
public void showBug(){
ContextFactory factory = new ContextFactory();
Context cx1 = factory.enterContext();
Context cx2 = factory.enterContext();
final Scriptable scope1 = cx1.initStandardObjects();

cx1.evaluateString(scope1,
"tryMe = function(){return {};}",
"tryMe", 1, null);

Scriptable result = (Scriptable)
ScriptableObject.callMethod(scope1, "tryMe", new Object[]
{});


String throwIfNotObject =
"isObject = function(obj){ if( !(obj instanceof
Object)) throw('not an object');}";

cx1.evaluateString(scope1, throwIfNotObject, "isObject", 1,
null);
Object [] arg = { result };

//doesn't throw, as expected
ScriptableObject.callMethod(scope1, "isObject", arg);
Context.exit();

final Scriptable scope2 = cx2.initStandardObjects();
cx2.evaluateString(scope2, throwIfNotObject, "isObject", 1,
null);

//throws -- unexpected
ScriptableObject.callMethod(scope2, "isObject", arg);
Context.exit();
}
}

Norris Boyd

unread,
Sep 26, 2008, 3:12:49 PM9/26/08
to

You're right: instanceof just walks up the prototype chain looking for
the object. Mixing objects from two separate initStandardObject calls
is problematic in general; why do you need to do this?

--N

wolffiex

unread,
Sep 27, 2008, 3:19:42 PM9/27/08
to
Hi Norris,
Thanks for the reply. This is how I'm handling JSON data from
untrusted sources: I inflate the object in a security-guarded context,
and then inject it into the context where my script is running. Is
this a bad idea? Should I make sure that the different contexts share
a sealed version of the same top level scope?

A

Marc Guillemot

unread,
Sep 29, 2008, 4:48:27 AM9/29/08
to

we didn't hurt this problem until now, but in the case of HtmlUnit,
mixing objects of two separate initStandardObject calls is natural as
each Window is a top scope and windows have access to child and parent
windows.

Cheers,
Marc.
--
Web: http://www.efficient-webtesting.com
Blog: http://mguillem.wordpress.com

wolffiex

unread,
Oct 1, 2008, 12:03:47 PM10/1/08
to

I just saw a post about this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=374918

Seems like it's related, huh?

A

Marc Guillemot

unread,
Oct 1, 2008, 2:24:11 PM10/1/08
to
wolffiex wrote:
> I just saw a post about this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=374918
>
> Seems like it's related, huh?

no, this is totally different.
As primitive aren't Scriptable, they don't hold information about their
scope. Rhino takes the Context's top scope what is incorrect and causes
errors when many scopes are involved.

0 new messages