Skip to content

Commit

Permalink
Add "initSafeStandardObjects" to create standard objects with
Browse files Browse the repository at this point in the history
no Java class access whatsoever.
  • Loading branch information
Gregory Brail committed Apr 13, 2015
1 parent 52b8881 commit 09dbbd3
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 16 deletions.
99 changes: 99 additions & 0 deletions src/org/mozilla/javascript/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,33 @@ public final ScriptableObject initStandardObjects()
return initStandardObjects(null, false);
}

/**
* Initialize the standard objects, leaving out those that offer access directly
* to Java classes. This sets up "scope" to have access to all the standard
* JavaScript classes, but does not create global objects for any top-level
* Java packages. In addition, the "Packages," "JavaAdapter," and
* "JavaImporter" classes, and the "getClass" function, are not
* initialized.
*
* The result of this function is a scope that may be safely used in a "sandbox"
* environment where it is not desirable to give access to Java code from JavaScript.
*
* Creates instances of the standard objects and their constructors
* (Object, String, Number, Date, etc.), setting up 'scope' to act
* as a global object as in ECMA 15.1.<p>
*
* This method must be called to initialize a scope before scripts
* can be evaluated in that scope.<p>
*
* This method does not affect the Context it is called upon.
*
* @return the initialized scope
*/
public final ScriptableObject initSafeStandardObjects()
{
return initSafeStandardObjects(null, false);
}

/**
* Initialize the standard objects.
*
Expand All @@ -1024,6 +1051,37 @@ public final Scriptable initStandardObjects(ScriptableObject scope)
return initStandardObjects(scope, false);
}

/**
* Initialize the standard objects, leaving out those that offer access directly
* to Java classes. This sets up "scope" to have access to all the standard
* JavaScript classes, but does not create global objects for any top-level
* Java packages. In addition, the "Packages," "JavaAdapter," and
* "JavaImporter" classes, and the "getClass" function, are not
* initialized.
*
* The result of this function is a scope that may be safely used in a "sandbox"
* environment where it is not desirable to give access to Java code from JavaScript.
*
* Creates instances of the standard objects and their constructors
* (Object, String, Number, Date, etc.), setting up 'scope' to act
* as a global object as in ECMA 15.1.<p>
*
* This method must be called to initialize a scope before scripts
* can be evaluated in that scope.<p>
*
* This method does not affect the Context it is called upon.
*
* @param scope the scope to initialize, or null, in which case a new
* object will be created to serve as the scope
* @return the initialized scope. The method returns the value of the scope
* argument if it is not null or newly allocated scope object which
* is an instance {@link ScriptableObject}.
*/
public final Scriptable initSafeStandardObjects(ScriptableObject scope)
{
return initSafeStandardObjects(scope, false);
}

/**
* Initialize the standard objects.
*
Expand Down Expand Up @@ -1057,6 +1115,47 @@ public ScriptableObject initStandardObjects(ScriptableObject scope,
return ScriptRuntime.initStandardObjects(this, scope, sealed);
}

/**
* Initialize the standard objects, leaving out those that offer access directly
* to Java classes. This sets up "scope" to have access to all the standard
* JavaScript classes, but does not create global objects for any top-level
* Java packages. In addition, the "Packages," "JavaAdapter," and
* "JavaImporter" classes, and the "getClass" function, are not
* initialized.
*
* The result of this function is a scope that may be safely used in a "sandbox"
* environment where it is not desirable to give access to Java code from JavaScript.
*
* Creates instances of the standard objects and their constructors
* (Object, String, Number, Date, etc.), setting up 'scope' to act
* as a global object as in ECMA 15.1.<p>
*
* This method must be called to initialize a scope before scripts
* can be evaluated in that scope.<p>
*
* This method does not affect the Context it is called upon.<p>
*
* This form of the method also allows for creating "sealed" standard
* objects. An object that is sealed cannot have properties added, changed,
* or removed. This is useful to create a "superglobal" that can be shared
* among several top-level objects. Note that sealing is not allowed in
* the current ECMA/ISO language specification, but is likely for
* the next version.
*
* @param scope the scope to initialize, or null, in which case a new
* object will be created to serve as the scope
* @param sealed whether or not to create sealed standard objects that
* cannot be modified.
* @return the initialized scope. The method returns the value of the scope
* argument if it is not null or newly allocated scope object.
* @since 1.7.6
*/
public ScriptableObject initSafeStandardObjects(ScriptableObject scope,
boolean sealed)
{
return ScriptRuntime.initSafeStandardObjects(this, scope, sealed);
}

/**
* Get the singleton object that represents the JavaScript Undefined value.
*/
Expand Down
42 changes: 26 additions & 16 deletions src/org/mozilla/javascript/ScriptRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ public static boolean isRhinoRuntimeType(Class<?> cl)
}
}

public static ScriptableObject initStandardObjects(Context cx,
ScriptableObject scope,
boolean sealed)
public static ScriptableObject initSafeStandardObjects(Context cx,
ScriptableObject scope,
boolean sealed)
{
if (scope == null) {
scope = new NativeObject();
Expand Down Expand Up @@ -204,22 +204,9 @@ public static ScriptableObject initStandardObjects(Context cx,
// define lazy-loaded properties using their class name
new LazilyLoadedCtor(scope, "RegExp",
"org.mozilla.javascript.regexp.NativeRegExp", sealed, true);
new LazilyLoadedCtor(scope, "Packages",
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
new LazilyLoadedCtor(scope, "getClass",
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
new LazilyLoadedCtor(scope, "JavaAdapter",
"org.mozilla.javascript.JavaAdapter", sealed, true);
new LazilyLoadedCtor(scope, "JavaImporter",
"org.mozilla.javascript.ImporterTopLevel", sealed, true);
new LazilyLoadedCtor(scope, "Continuation",
"org.mozilla.javascript.NativeContinuation", sealed, true);

for (String packageName : getTopPackageNames()) {
new LazilyLoadedCtor(scope, packageName,
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
}

if (withXml) {
String xmlImpl = cx.getE4xImplementationFactory().getImplementationClassName();
new LazilyLoadedCtor(scope, "XML", xmlImpl, sealed, true);
Expand Down Expand Up @@ -271,6 +258,29 @@ public static ScriptableObject initStandardObjects(Context cx,

return scope;
}

public static ScriptableObject initStandardObjects(Context cx,
ScriptableObject scope,
boolean sealed)
{
ScriptableObject s = initSafeStandardObjects(cx, scope, sealed);

new LazilyLoadedCtor(s, "Packages",
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
new LazilyLoadedCtor(s, "getClass",
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
new LazilyLoadedCtor(s, "JavaAdapter",
"org.mozilla.javascript.JavaAdapter", sealed, true);
new LazilyLoadedCtor(s, "JavaImporter",
"org.mozilla.javascript.ImporterTopLevel", sealed, true);

for (String packageName : getTopPackageNames()) {
new LazilyLoadedCtor(s, packageName,
"org.mozilla.javascript.NativeJavaTopPackage", sealed, true);
}

return s;
}

static String[] getTopPackageNames() {
// Include "android" top package if running on Android
Expand Down

1 comment on commit 09dbbd3

@hrj
Copy link

@hrj hrj commented on 09dbbd3 Apr 16, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This API will be very useful to gngr!

👏

Please sign in to comment.