diff --git a/rhino/src/main/java/org/mozilla/javascript/Context.java b/rhino/src/main/java/org/mozilla/javascript/Context.java index 95c73d6a5d..49edfff71f 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Context.java +++ b/rhino/src/main/java/org/mozilla/javascript/Context.java @@ -1749,7 +1749,8 @@ public static Object javaToJS(Object value, Scriptable scope, Context cx) { if (value instanceof String || value instanceof Number || value instanceof Boolean - || value instanceof Scriptable) { + || value instanceof Scriptable + || value instanceof Undefined) { return value; } else if (value instanceof Character) { return String.valueOf(((Character) value).charValue()); diff --git a/rhino/src/main/java/org/mozilla/javascript/MemberBox.java b/rhino/src/main/java/org/mozilla/javascript/MemberBox.java index 1f6ab40c14..80900cac47 100644 --- a/rhino/src/main/java/org/mozilla/javascript/MemberBox.java +++ b/rhino/src/main/java/org/mozilla/javascript/MemberBox.java @@ -89,26 +89,6 @@ Class getDeclaringClass() { return memberObject.getDeclaringClass(); } - String toJavaDeclaration() { - StringBuilder sb = new StringBuilder(); - if (isMethod()) { - Method method = method(); - sb.append(method.getReturnType()); - sb.append(' '); - sb.append(method.getName()); - } else { - Constructor ctor = ctor(); - String name = ctor.getDeclaringClass().getName(); - int lastDot = name.lastIndexOf('.'); - if (lastDot >= 0) { - name = name.substring(lastDot + 1); - } - sb.append(name); - } - sb.append(JavaMembers.liveConnectSignature(argTypes)); - return sb.toString(); - } - @Override public String toString() { return memberObject.toString(); diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeJavaMethod.java b/rhino/src/main/java/org/mozilla/javascript/NativeJavaMethod.java index 4c9112e9d8..96be7616a2 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeJavaMethod.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeJavaMethod.java @@ -7,6 +7,7 @@ package org.mozilla.javascript; import java.lang.reflect.Array; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Arrays; import java.util.EnumSet; @@ -424,7 +425,7 @@ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) { bestFitIndex = extraBestFits[j]; } buf.append("\n "); - buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration()); + buf.append(toJavaDeclaration(methodsOrCtors[bestFitIndex])); } MemberBox firstFitMember = methodsOrCtors[firstBestFit]; @@ -443,6 +444,26 @@ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) { buf.toString()); } + private static String toJavaDeclaration(MemberBox memberBox) { + StringBuilder sb = new StringBuilder(); + if (memberBox.isMethod()) { + Method method = memberBox.method(); + sb.append(method.getReturnType()); + sb.append(' '); + sb.append(method.getName()); + } else { + Constructor ctor = memberBox.ctor(); + String name = ctor.getDeclaringClass().getName(); + int lastDot = name.lastIndexOf('.'); + if (lastDot >= 0) { + name = name.substring(lastDot + 1); + } + sb.append(name); + } + sb.append(JavaMembers.liveConnectSignature(memberBox.argTypes)); + return sb.toString(); + } + /** Types are equal */ private static final int PREFERENCE_EQUAL = 0; diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java index 4e3a97c7d4..a413653dd3 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java +++ b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java @@ -148,7 +148,6 @@ public static ScriptableObject initSafeStandardObjects( } scope.associateValue(LIBRARY_SCOPE_KEY, scope); - new ClassCache().associate(scope); BaseFunction.init(cx, scope, sealed); NativeObject.init(scope, sealed); @@ -190,10 +189,6 @@ public static ScriptableObject initSafeStandardObjects( NativeStringIterator.init(scope, sealed); NativeJavaObject.init(scope, sealed); - NativeJavaMap.init(scope, sealed); - - boolean withXml = - cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null; // define lazy-loaded properties using their class name new LazilyLoadedCtor( @@ -201,14 +196,6 @@ public static ScriptableObject initSafeStandardObjects( new LazilyLoadedCtor( scope, "Continuation", "org.mozilla.javascript.NativeContinuation", sealed, true); - if (withXml) { - String xmlImpl = cx.getE4xImplementationFactory().getImplementationClassName(); - new LazilyLoadedCtor(scope, "XML", xmlImpl, sealed, true); - new LazilyLoadedCtor(scope, "XMLList", xmlImpl, sealed, true); - new LazilyLoadedCtor(scope, "Namespace", xmlImpl, sealed, true); - new LazilyLoadedCtor(scope, "QName", xmlImpl, sealed, true); - } - if (((cx.getLanguageVersion() >= Context.VERSION_1_8) && cx.hasFeature(Context.FEATURE_V8_EXTENSIONS)) || (cx.getLanguageVersion() >= Context.VERSION_ES6)) { @@ -299,10 +286,32 @@ public static ScriptableObject initSafeStandardObjects( return scope; } + public static boolean isLiveConnectEnabled(Scriptable scope) { + return Boolean.TRUE.equals(ScriptableObject.getTopScopeValue(scope, LIVE_CONNECT_ENABLED)); + } + public static ScriptableObject initStandardObjects( Context cx, ScriptableObject scope, boolean sealed) { ScriptableObject s = initSafeStandardObjects(cx, scope, sealed); + // The following obects are "unsafe", as they allow access to java classes with reflection + s.associateValue(LIVE_CONNECT_ENABLED, Boolean.TRUE); + new ClassCache().associate(s); + + NativeJavaObject.init(s, sealed); + NativeJavaMap.init(s, sealed); + + boolean withXml = + cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null; + + if (withXml) { + String xmlImpl = cx.getE4xImplementationFactory().getImplementationClassName(); + new LazilyLoadedCtor(s, "XML", xmlImpl, sealed, true); + new LazilyLoadedCtor(s, "XMLList", xmlImpl, sealed, true); + new LazilyLoadedCtor(s, "Namespace", xmlImpl, sealed, true); + new LazilyLoadedCtor(s, "QName", xmlImpl, sealed, true); + } + new LazilyLoadedCtor( s, "Packages", "org.mozilla.javascript.NativeJavaTopPackage", sealed, true); new LazilyLoadedCtor( @@ -1453,6 +1462,7 @@ public static Optional canonicalNumericIndexString(String arg) { // XXX: this is until setDefaultNamespace will learn how to store NS // properly and separates namespace form Scriptable.get etc. private static final String DEFAULT_NS_TAG = "__default_namespace__"; + private static final String LIVE_CONNECT_ENABLED = "__live_connect_enabled__"; public static Object setDefaultNamespace(Object namespace, Context cx) { Scriptable scope = cx.currentActivationCall; @@ -4402,26 +4412,27 @@ public static Scriptable newCatchScope( if (errorObject instanceof NativeError) { ((NativeError) errorObject).setStackProvider(re); } - - if (javaException != null && isVisible(cx, javaException)) { - Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null); - ScriptableObject.defineProperty( - errorObject, - "javaException", - wrap, - ScriptableObject.PERMANENT - | ScriptableObject.READONLY - | ScriptableObject.DONTENUM); - } - if (isVisible(cx, re)) { - Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null); - ScriptableObject.defineProperty( - errorObject, - "rhinoException", - wrap, - ScriptableObject.PERMANENT - | ScriptableObject.READONLY - | ScriptableObject.DONTENUM); + if (ScriptRuntime.isLiveConnectEnabled(scope)) { + if (javaException != null && isVisible(cx, javaException)) { + Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null); + ScriptableObject.defineProperty( + errorObject, + "javaException", + wrap, + ScriptableObject.PERMANENT + | ScriptableObject.READONLY + | ScriptableObject.DONTENUM); + } + if (isVisible(cx, re)) { + Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null); + ScriptableObject.defineProperty( + errorObject, + "rhinoException", + wrap, + ScriptableObject.PERMANENT + | ScriptableObject.READONLY + | ScriptableObject.DONTENUM); + } } obj = errorObject; } @@ -4501,26 +4512,27 @@ public static Scriptable wrapException(Throwable t, Scriptable scope, Context cx if (errorObject instanceof NativeError) { ((NativeError) errorObject).setStackProvider(re); } - - if (javaException != null && isVisible(cx, javaException)) { - Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null); - ScriptableObject.defineProperty( - errorObject, - "javaException", - wrap, - ScriptableObject.PERMANENT - | ScriptableObject.READONLY - | ScriptableObject.DONTENUM); - } - if (isVisible(cx, re)) { - Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null); - ScriptableObject.defineProperty( - errorObject, - "rhinoException", - wrap, - ScriptableObject.PERMANENT - | ScriptableObject.READONLY - | ScriptableObject.DONTENUM); + if (ScriptRuntime.isLiveConnectEnabled(scope)) { + if (javaException != null && isVisible(cx, javaException)) { + Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null); + ScriptableObject.defineProperty( + errorObject, + "javaException", + wrap, + ScriptableObject.PERMANENT + | ScriptableObject.READONLY + | ScriptableObject.DONTENUM); + } + if (isVisible(cx, re)) { + Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null); + ScriptableObject.defineProperty( + errorObject, + "rhinoException", + wrap, + ScriptableObject.PERMANENT + | ScriptableObject.READONLY + | ScriptableObject.DONTENUM); + } } return errorObject; }