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`)_ on a `String`, missing properties
should return `false` instead of throwing a `Property {0} not found.` exception.

Fixes mozilla#415
  • Loading branch information
whitlockjc committed Apr 6, 2018
1 parent 1a83fd3 commit cb5eca7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
37 changes: 24 additions & 13 deletions src/org/mozilla/javascript/NativeObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,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,26 @@
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;

/**
* When calling <b>propertyIsEnumerable</b> on a <b>String</b>, missing properties should return <b>false</b> instead of
* throwing a <b>Property {0} not found.</b> exception.
*
* @see <a href="https://github.com/mozilla/rhino/issues/415">https://github.com/mozilla/rhino/issues/415</a>
*/
public class StringMissingPropertyIsNotEnumerableTest {

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

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

assertFalse((Boolean)result);
}

}

0 comments on commit cb5eca7

Please sign in to comment.