for an assignment to a property with only a getter defined, the assignment should cancel out the getter

RESOLVED INVALID

Status

Rhino
Core
RESOLVED INVALID
10 years ago
9 years ago

People

(Reporter: Norris Boyd, Assigned: Norris Boyd)

Tracking

Details

(Assignee)

Description

10 years ago
I'm trying to figure out if this failing piece of code fails due to a
bug in Rhino. The short of it is that we have a global object (in this
case an instance of TestBean) that has a read-only property named
"blah"; we execute some JS code which attempts to define a function
named "blah" (and does so successfully, I think), but when the code
attempts to call this new function, Rhino picks up the read-only
"blah" property on the global object (rather than the function) --
throwing a TypeError.

The real-world application of this is in HtmlUnit: the global object
in an HTML document is the window, which has (for example) a read-only
"navigator" property. However, you are allowed to define a function
named "navigator" and call it (hiding the real "navigator" property).

Have a look at the code below and let me know what you think... Should
this work in Rhino? Is it a bug? Is it misconfiguration?

Take care,

Daniel

public class TestBean extends ScriptableObject {
    private Object blah = "a";
    public Object getBlah() {
        return blah;
    }
    @Override
    public String getClassName() {
        return "TestBean";
    }

}

public void testPropertyReplacement() throws Exception {
    Context cx = ContextFactory.getGlobal().enterContext();
    try {
        ScriptableObject scope = new TestBean();
        cx.initStandardObjects(scope);
        Method getter = TestBean.class.getDeclaredMethod("getBlah");
        scope.defineProperty("blah", null, getter, null,
ScriptableObject.EMPTY);
        String source =
            "function blah() { return 'x'; }\n" +
            "blah();\n";
        cx.evaluateString(scope, source, "source", 1, null);
    } finally {
        Context.exit();
    }
(Assignee)

Comment 1

10 years ago
Fixed:

Checking in src/org/mozilla/javascript/ScriptableObject.java;
/cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/ScriptableObject.java,v  <-
-  ScriptableObject.java
new revision: 1.134; previous revision: 1.133
done
Status: NEW → RESOLVED
Last Resolved: 10 years ago
Resolution: --- → FIXED
(Assignee)

Comment 2

9 years ago
My change to fix this conflicts with current SpiderMonkey behavior. I checked with Brendan and he recommended just matching the latest 3.1 behavior. Based on TC39 ES3.1 Draft of 9-Feb-2009, 8.12.4, step 2, we should throw a TypeError in this case. I've changed Rhino to do so.

You can work around this change by defining the getter/setter combination such that calling the setter will result in the getter returning that value.
Resolution: FIXED → INVALID

Comment 3

9 years ago
Norris,
I'm surprised by the way you've changed it. What about making it dependent of the languageVersion as done for other features that differ between specs?
(Assignee)

Comment 4

9 years ago
Does it not work for you to do the workaround? This is a messy case, with behavior that existed outside the spec that is now being specified, and with this change living in the currently released version. The next big release of Rhino will have es5 support, so I'll want that version to have this behavior.

Comment 5

9 years ago
In fact we need *both* behaviours, the old one as well as the new one, depending on the browser that we simulated. For this purpose, I have added on Context feature in our Rhino "fork":
https://htmlunit.svn.sourceforge.net/svnroot/htmlunit/trunk/core-js/rhino/src/org/mozilla/javascript/ScriptableObject.java

Implementing all setters would be just too much work: we have a lot of such properties.

From my understanding of Rhino, the "normal" way for Rhino to handle such a change without to compromise backward compatibility is to add a dedicated Context feature (or to make this behaviour depend on the JS version).
You need to log in before you can comment on or make changes to this bug.