diff --git a/src/org/mozilla/javascript/ScriptableObject.java b/src/org/mozilla/javascript/ScriptableObject.java index 5218a68e01..2898e5c955 100644 --- a/src/org/mozilla/javascript/ScriptableObject.java +++ b/src/org/mozilla/javascript/ScriptableObject.java @@ -2200,14 +2200,26 @@ public static Scriptable getClassPrototype(Scriptable scope, * @param obj a JavaScript object * @return the corresponding global scope */ - public static Scriptable getTopLevelScope(Scriptable obj) + public static Scriptable getTopLevelScope(final Scriptable obj) { + // FIXME: some classes throw NPE in toString methods! + // FIXME: some classes throw StackOverflow in toString methods! + final HashSet cache = new HashSet(); + cache.add(obj); + Scriptable temp = obj; for (;;) { - Scriptable parent = obj.getParentScope(); + final Scriptable parent = temp.getParentScope(); + // prevent indefinite loop. + // FIXME: HtmlUnit's Window handles are sometimes each other's descendants. + if (cache.contains(parent)) { + return parent; +// throw new IllegalStateException("Scriptable is it's own descendant!: " + obj); + } if (parent == null) { - return obj; + return temp; } - obj = parent; + temp = parent; + cache.add(parent); } }