Skip to content

Commit

Permalink
Missing properties are not enumerable when checking enumerability
Browse files Browse the repository at this point in the history
When checking property enumerability
_(`Object.prototype.propertyIsEnumerable`)_, missing properties should return
`false` instead of throwing a `Property {0} not found.` exception.

Fixes mozilla#415
  • Loading branch information
whitlockjc committed Apr 5, 2018
1 parent 1a83fd3 commit 6e2b67f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
39 changes: 26 additions & 13 deletions src/org/mozilla/javascript/NativeObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

package org.mozilla.javascript;

import sun.font.ScriptRun;

import java.util.*;

/**
Expand Down Expand Up @@ -181,20 +183,31 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
}
} else {
String s = ScriptRuntime.toStringIdOrIndex(cx, arg);
if (s == null) {
int index = ScriptRuntime.lastIndexResult(cx);
result = thisObj.has(index, thisObj);
if (result && thisObj instanceof ScriptableObject) {
ScriptableObject so = (ScriptableObject) thisObj;
int attrs = so.getAttributes(index);
result = ((attrs & ScriptableObject.DONTENUM) == 0);
// When checking if a property is enumerable, a missing property should return "false" instead of
// throwing an exception. See: https://github.com/mozilla/rhino/issues/415
try {
if (s == null) {
int index = ScriptRuntime.lastIndexResult(cx);
result = thisObj.has(index, thisObj);
s = Integer.toString(index);
if (result && thisObj instanceof ScriptableObject) {
ScriptableObject so = (ScriptableObject) thisObj;
int attrs = so.getAttributes(index);
result = ((attrs & ScriptableObject.DONTENUM) == 0);
}
} else {
result = thisObj.has(s, thisObj);
if (result && thisObj instanceof ScriptableObject) {
ScriptableObject so = (ScriptableObject) thisObj;
int attrs = so.getAttributes(s);
result = ((attrs & ScriptableObject.DONTENUM) == 0);
}
}
} else {
result = thisObj.has(s, thisObj);
if (result && thisObj instanceof ScriptableObject) {
ScriptableObject so = (ScriptableObject) thisObj;
int attrs = so.getAttributes(s);
result = ((attrs & ScriptableObject.DONTENUM) == 0);
} catch (EvaluatorException ee) {
if (ee.getMessage().startsWith(ScriptRuntime.getMessage1("msg.prop.not.found", s))) {
result = false;
} else {
throw ee;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.mozilla.javascript.tests.es5;

import org.junit.Test;
import org.mozilla.javascript.NativeObject;

import static org.junit.Assert.assertFalse;
import static org.mozilla.javascript.tests.Evaluator.eval;

public class StringPropertyIsEnumerableTest {

@Test
public void testStringPropertyIsEnumerable() {
NativeObject object = new NativeObject();

Object result = eval("'s'.propertyIsEnumerable(0)", "obj", object);

assertFalse((Boolean)result);
}

}

0 comments on commit 6e2b67f

Please sign in to comment.