Reformat files in experimental

This commit is contained in:
Tommy Lillehagen 2017-10-06 14:56:44 +01:00
parent 551dc43265
commit b1fb321230
23 changed files with 134 additions and 130 deletions

View File

@ -32,7 +32,7 @@ fun recordUsedInstrumentedCallStack() {
val throwable = Throwable() val throwable = Throwable()
var index = 0 var index = 0
while (true) { while (true) {
require (index < throwable.stackTrace.size) { "Can't find getStack call" } require(index < throwable.stackTrace.size) { "Can't find getStack call" }
val stackElement = throwable.stackTrace[index] val stackElement = throwable.stackTrace[index]
if (stackElement.className == "co.paralleluniverse.fibers.Stack" && stackElement.methodName == "getStack") { if (stackElement.className == "co.paralleluniverse.fibers.Stack" && stackElement.methodName == "getStack") {
break break
@ -129,7 +129,7 @@ class QuasarInstrumentationHookAgent {
// The separator append is a hack, it causes a package with an empty name to be added to the exclude tree, // The separator append is a hack, it causes a package with an empty name to be added to the exclude tree,
// which practically causes that level of the tree to be always expanded in the output globs. // which practically causes that level of the tree to be always expanded in the output globs.
val expand = arguments.expand?.let { PackageTree.fromStrings(it.map { "$it${arguments.separator}" }, arguments.separator) } val expand = arguments.expand?.let { PackageTree.fromStrings(it.map { "$it${arguments.separator}" }, arguments.separator) }
val truncatedTree = truncate?.let { scannedTree.truncate(it)} ?: scannedTree val truncatedTree = truncate?.let { scannedTree.truncate(it) } ?: scannedTree
val expandedTree = expand?.let { alwaysExcludedTree.merge(it) } ?: alwaysExcludedTree val expandedTree = expand?.let { alwaysExcludedTree.merge(it) } ?: alwaysExcludedTree
val globs = truncatedTree.toGlobs(expandedTree) val globs = truncatedTree.toGlobs(expandedTree)
globs.forEach { globs.forEach {
@ -152,7 +152,7 @@ object QuasarInstrumentationHook : ClassFileTransformer {
val instrumentMap = mapOf<String, (CtClass) -> Unit>( val instrumentMap = mapOf<String, (CtClass) -> Unit>(
"co/paralleluniverse/fibers/Stack" to { clazz -> "co/paralleluniverse/fibers/Stack" to { clazz ->
// This is called on each suspend, we hook into it to get the stack trace of actually used Suspendables // This is called on each suspend, we hook into it to get the stack trace of actually used Suspendables
val getStackMethod = clazz.methods.single { it.name == "getStack" } val getStackMethod = clazz.methods.single { it.name == "getStack" }
getStackMethod.insertBefore( getStackMethod.insertBefore(
"$hookClassName.${::recordUsedInstrumentedCallStack.name}();" "$hookClassName.${::recordUsedInstrumentedCallStack.name}();"
) )
@ -194,7 +194,7 @@ object QuasarInstrumentationHook : ClassFileTransformer {
throwable.printStackTrace(System.out) throwable.printStackTrace(System.out)
classfileBuffer classfileBuffer
} }
} }
} }
data class Glob(val parts: List<String>, val isFull: Boolean) { data class Glob(val parts: List<String>, val isFull: Boolean) {
@ -271,6 +271,7 @@ data class PackageTree(val branches: Map<String, PackageTree>) {
val exclude: PackageTree, val exclude: PackageTree,
val globSoFar: List<String> val globSoFar: List<String>
) )
val toExpandList = LinkedList(listOf(State(this, excludeTree, emptyList()))) val toExpandList = LinkedList(listOf(State(this, excludeTree, emptyList())))
val globs = ArrayList<Glob>() val globs = ArrayList<Glob>()
while (true) { while (true) {

View File

@ -43,7 +43,6 @@ public class CandidacyStatus {
} }
/** /**
*
* @param signature * @param signature
* @return true if the input was absent from the underlying map * @return true if the input was absent from the underlying map
*/ */
@ -52,7 +51,6 @@ public class CandidacyStatus {
} }
/** /**
*
* @param methodSignature * @param methodSignature
* @return true if the input was absent from the underlying map * @return true if the input was absent from the underlying map
*/ */
@ -62,7 +60,7 @@ public class CandidacyStatus {
/** /**
* Static factory method * Static factory method
* *
* @param startingSet * @param startingSet
* @return a candidacy status based on the starting set * @return a candidacy status based on the starting set
*/ */
@ -81,7 +79,7 @@ public class CandidacyStatus {
/** /**
* Static factory method * Static factory method
* *
* @return a candidacy status based on the starting set * @return a candidacy status based on the starting set
*/ */
public static CandidacyStatus of() { public static CandidacyStatus of() {
@ -90,8 +88,8 @@ public class CandidacyStatus {
/** /**
* Add additional methods that are known to be deterministic * Add additional methods that are known to be deterministic
* *
* @param methodNames * @param methodNames
*/ */
public void addKnownDeterministicMethods(final Set<String> methodNames) { public void addKnownDeterministicMethods(final Set<String> methodNames) {
for (String known : methodNames) { for (String known : methodNames) {
@ -101,7 +99,7 @@ public class CandidacyStatus {
/** /**
* Getter method for candidate methods * Getter method for candidate methods
* *
* @param methodSignature * @param methodSignature
* @return the candidate method corresponding to a method signature * @return the candidate method corresponding to a method signature
*/ */
@ -149,10 +147,10 @@ public class CandidacyStatus {
} }
/** /**
* Increases the recursive depth of this classloading process, throwing a * Increases the recursive depth of this classloading process, throwing a
* ClassNotFoundException if it becomes too high * ClassNotFoundException if it becomes too high
* *
* @throws ClassNotFoundException * @throws ClassNotFoundException
*/ */
public void incRecursiveCount() throws ClassNotFoundException { public void incRecursiveCount() throws ClassNotFoundException {
if (recursiveDepth >= MAX_CLASSLOADING_RECURSIVE_DEPTH - 1) { if (recursiveDepth >= MAX_CLASSLOADING_RECURSIVE_DEPTH - 1) {
@ -174,7 +172,7 @@ public class CandidacyStatus {
out.add(candidateName); out.add(candidateName);
} }
} }
return out; return out;
} }

View File

@ -6,15 +6,14 @@ import java.util.Set;
/** /**
* A candidate method that is under evaluation. Candidate methods have one of the following states: * A candidate method that is under evaluation. Candidate methods have one of the following states:
* * <p>
* <ul> * <ul>
* <li>{@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.</li> * <li>{@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.</li>
* <li>{@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.</li> * <li>{@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.</li>
* <li>{@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.</li> * <li>{@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.</li>
* </ul> * </ul>
* * <p>
* CandidateMethods themselves reference other CandidateMethods which are be checked for their deterministic state * CandidateMethods themselves reference other CandidateMethods which are be checked for their deterministic state
*
*/ */
public final class CandidateMethod { public final class CandidateMethod {
@ -43,7 +42,7 @@ public final class CandidateMethod {
private final Set<CandidateMethod> referencedCandidateMethods = new HashSet<>(); private final Set<CandidateMethod> referencedCandidateMethods = new HashSet<>();
public State getCurrentState() { public State getCurrentState() {
return currentState; return currentState;
} }
@ -59,7 +58,7 @@ public final class CandidateMethod {
public void deterministic() { public void deterministic() {
if (currentState == State.DISALLOWED) { if (currentState == State.DISALLOWED) {
throw new IllegalArgumentException("Method "+ internalMethodName +" attempted to transition from DISALLOWED to DETERMINISTIC"); throw new IllegalArgumentException("Method " + internalMethodName + " attempted to transition from DISALLOWED to DETERMINISTIC");
} }
currentState = State.DETERMINISTIC; currentState = State.DETERMINISTIC;
} }
@ -79,7 +78,7 @@ public final class CandidateMethod {
public String getInternalMethodName() { public String getInternalMethodName() {
return internalMethodName; return internalMethodName;
} }
public void addReferencedCandidateMethod(final CandidateMethod referenceCandidateMethod) { public void addReferencedCandidateMethod(final CandidateMethod referenceCandidateMethod) {
referencedCandidateMethods.add(referenceCandidateMethod); referencedCandidateMethods.add(referenceCandidateMethod);
} }
@ -94,8 +93,9 @@ public final class CandidateMethod {
/** /**
* This factory constructor is only called for methods that are known to be deterministic in advance * This factory constructor is only called for methods that are known to be deterministic in advance
*
* @param methodSignature * @param methodSignature
* @return * @return
*/ */
public static CandidateMethod proven(String methodSignature) { public static CandidateMethod proven(String methodSignature) {
final CandidateMethod provenCandidateMethod = new CandidateMethod(methodSignature); final CandidateMethod provenCandidateMethod = new CandidateMethod(methodSignature);

View File

@ -1,11 +1,11 @@
package net.corda.sandbox; package net.corda.sandbox;
import static net.corda.sandbox.Utils.*; import static net.corda.sandbox.Utils.*;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
/** /**
*
* @author ben * @author ben
*/ */
public final class SandboxAwareClassWriter extends ClassWriter { public final class SandboxAwareClassWriter extends ClassWriter {
@ -25,17 +25,15 @@ public final class SandboxAwareClassWriter extends ClassWriter {
* without actually loading any class, or to take into account the class * without actually loading any class, or to take into account the class
* that is currently being generated by this ClassWriter, which can of * that is currently being generated by this ClassWriter, which can of
* course not be loaded since it is under construction. * course not be loaded since it is under construction.
* *
* @param type1 * @param type1 the internal name of a class.
* the internal name of a class. * @param type2 the internal name of another class.
* @param type2
* the internal name of another class.
* @return the internal name of the common super class of the two given * @return the internal name of the common super class of the two given
* classes. * classes.
*/ */
@Override @Override
public String getCommonSuperClass(final String type1, final String type2) { public String getCommonSuperClass(final String type1, final String type2) {
if (OBJECT.equals(type1) || OBJECT.equals(type2) if (OBJECT.equals(type1) || OBJECT.equals(type2)
|| OBJECT.equals(unsandboxNameIfNeedBe(type1)) || OBJECT.equals(unsandboxNameIfNeedBe(type2))) { || OBJECT.equals(unsandboxNameIfNeedBe(type1)) || OBJECT.equals(unsandboxNameIfNeedBe(type2))) {
return OBJECT; return OBJECT;
} }
@ -58,7 +56,7 @@ public final class SandboxAwareClassWriter extends ClassWriter {
c = Class.forName(type1.replace('/', '.'), false, loader); c = Class.forName(type1.replace('/', '.'), false, loader);
d = Class.forName(type2.replace('/', '.'), false, loader); d = Class.forName(type2.replace('/', '.'), false, loader);
} catch (Exception e) { } catch (Exception e) {
c = Class.forName(unsandboxNameIfNeedBe(type1).replace('/', '.'), false, loader); c = Class.forName(unsandboxNameIfNeedBe(type1).replace('/', '.'), false, loader);
d = Class.forName(unsandboxNameIfNeedBe(type2).replace('/', '.'), false, loader); d = Class.forName(unsandboxNameIfNeedBe(type2).replace('/', '.'), false, loader);

View File

@ -3,7 +3,6 @@ package net.corda.sandbox;
import org.objectweb.asm.commons.Remapper; import org.objectweb.asm.commons.Remapper;
/** /**
*
* @author ben * @author ben
*/ */
public final class SandboxRemapper extends Remapper { public final class SandboxRemapper extends Remapper {

View File

@ -4,7 +4,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
*
* @author ben * @author ben
*/ */
public final class Utils { public final class Utils {
@ -12,7 +11,7 @@ public final class Utils {
public final static String SANDBOX_PREFIX_INTERNAL = "sandbox/"; public final static String SANDBOX_PREFIX_INTERNAL = "sandbox/";
public final static String CLASSFILE_NAME_SUFFIX = "^(.*)\\.class$"; public final static String CLASSFILE_NAME_SUFFIX = "^(.*)\\.class$";
public static final Pattern JAVA_LANG_PATTERN_INTERNAL = Pattern.compile("^java/lang/(.*)"); public static final Pattern JAVA_LANG_PATTERN_INTERNAL = Pattern.compile("^java/lang/(.*)");
public static final Pattern SANDBOX_PATTERN_INTERNAL = Pattern.compile("^" + SANDBOX_PREFIX_INTERNAL + "(.*)"); public static final Pattern SANDBOX_PATTERN_INTERNAL = Pattern.compile("^" + SANDBOX_PREFIX_INTERNAL + "(.*)");
@ -28,13 +27,13 @@ public final class Utils {
public static final Pattern CLASSNAME_PATTERN_QUALIFIED = Pattern.compile("([^\\.]+)\\."); public static final Pattern CLASSNAME_PATTERN_QUALIFIED = Pattern.compile("([^\\.]+)\\.");
public static final String OBJECT = "java/lang/Object"; public static final String OBJECT = "java/lang/Object";
public static final String THROWABLE = "java/lang/Throwable"; public static final String THROWABLE = "java/lang/Throwable";
public static final String ERROR = "java/lang/Error"; public static final String ERROR = "java/lang/Error";
public static final String THREAD_DEATH = "java/lang/ThreadDeath"; public static final String THREAD_DEATH = "java/lang/ThreadDeath";
// Hide constructor // Hide constructor
private Utils() { private Utils() {
} }
@ -43,6 +42,7 @@ public final class Utils {
* Helper method that converts from the internal class name format (as used in the * Helper method that converts from the internal class name format (as used in the
* Constant Pool) to a fully-qualified class name. No obvious library method to do this * Constant Pool) to a fully-qualified class name. No obvious library method to do this
* appears to exist, hence this code. If one exists, rip this out. * appears to exist, hence this code. If one exists, rip this out.
*
* @param classInternalName * @param classInternalName
* @return * @return
*/ */
@ -52,12 +52,11 @@ public final class Utils {
} }
/** /**
* This method takes in an internal method name but needs to return a qualified * This method takes in an internal method name but needs to return a qualified
* classname (suitable for loading) * classname (suitable for loading)
* *
*
* @param internalMethodName * @param internalMethodName
* @return * @return
*/ */
public static String convertInternalMethodNameToQualifiedClassName(final String internalMethodName) { public static String convertInternalMethodNameToQualifiedClassName(final String internalMethodName) {
final Matcher classMatch = CLASSNAME_PATTERN_QUALIFIED.matcher(internalMethodName); final Matcher classMatch = CLASSNAME_PATTERN_QUALIFIED.matcher(internalMethodName);
@ -72,6 +71,7 @@ public final class Utils {
* Helper method that converts from a fully-qualified class name to the internal class * Helper method that converts from a fully-qualified class name to the internal class
* name format (as used in the Constant Pool). No obvious library method to do this * name format (as used in the Constant Pool). No obvious library method to do this
* appears to exist, hence this code. If one exists, rip this out. * appears to exist, hence this code. If one exists, rip this out.
*
* @param qualifiedClassName * @param qualifiedClassName
* @return * @return
*/ */
@ -81,7 +81,7 @@ public final class Utils {
} }
/** /**
* This method potentially rewrites the classname. * This method potentially rewrites the classname.
* *
* @param internalClassname - specified in internal form * @param internalClassname - specified in internal form
* @return * @return
@ -102,9 +102,8 @@ public final class Utils {
} }
/** /**
*
* @param qualifiedTypeName * @param qualifiedTypeName
* @return * @return
*/ */
public static String sandboxQualifiedTypeName(final String qualifiedTypeName) { public static String sandboxQualifiedTypeName(final String qualifiedTypeName) {
final String internal = convertQualifiedClassNameToInternalForm(qualifiedTypeName); final String internal = convertQualifiedClassNameToInternalForm(qualifiedTypeName);
@ -118,7 +117,7 @@ public final class Utils {
/** /**
* This method removes the sandboxing prefix from a method or type name, if it has * This method removes the sandboxing prefix from a method or type name, if it has
* one, otherwise it returns the input string. * one, otherwise it returns the input string.
* *
* @param internalClassname * @param internalClassname
* @return the internal classname, unsandboxed if that was required * @return the internal classname, unsandboxed if that was required
*/ */
@ -131,7 +130,6 @@ public final class Utils {
} }
/** /**
*
* @param desc - internal * @param desc - internal
* @return the rewritten desc string * @return the rewritten desc string
*/ */
@ -169,9 +167,9 @@ public final class Utils {
* loading. This should not attempt to load a classname that starts with java. as * loading. This should not attempt to load a classname that starts with java. as
* the only permissable classes have already been transformed into sandboxed * the only permissable classes have already been transformed into sandboxed
* methods * methods
* *
* @param qualifiedClassName * @param qualifiedClassName
* @return * @return
*/ */
public static boolean shouldAttemptToTransitivelyLoad(final String qualifiedClassName) { public static boolean shouldAttemptToTransitivelyLoad(final String qualifiedClassName) {
return !JAVA_PATTERN_QUALIFIED.asPredicate().test(qualifiedClassName); return !JAVA_PATTERN_QUALIFIED.asPredicate().test(qualifiedClassName);
@ -179,7 +177,7 @@ public final class Utils {
/** /**
* Helper method that determines whether this class requires sandboxing * Helper method that determines whether this class requires sandboxing
* *
* @param clazzName - specified in internal form * @param clazzName - specified in internal form
* @return true if the class should be sandboxed * @return true if the class should be sandboxed
*/ */

View File

@ -2,6 +2,7 @@ package net.corda.sandbox;
import net.corda.sandbox.visitors.CostInstrumentingMethodVisitor; import net.corda.sandbox.visitors.CostInstrumentingMethodVisitor;
import net.corda.sandbox.visitors.WhitelistCheckingClassVisitor; import net.corda.sandbox.visitors.WhitelistCheckingClassVisitor;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URI; import java.net.URI;
@ -9,13 +10,13 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.file.*; import java.nio.file.*;
import java.util.*; import java.util.*;
import org.objectweb.asm.*; import org.objectweb.asm.*;
import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.ClassRemapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public final class WhitelistClassLoader extends ClassLoader { public final class WhitelistClassLoader extends ClassLoader {
@ -61,8 +62,8 @@ public final class WhitelistClassLoader extends ClassLoader {
} }
/** /**
* Static factory method. Throws URISyntaxException currently, as this method is * Static factory method. Throws URISyntaxException currently, as this method is
* called with user data, so a checked exception is not unreasonable. Could use a * called with user data, so a checked exception is not unreasonable. Could use a
* runtime exception instead. * runtime exception instead.
* *
* @param auxiliaryClassPath * @param auxiliaryClassPath
@ -70,7 +71,7 @@ public final class WhitelistClassLoader extends ClassLoader {
* methods to be deterministic, instead the classloader * methods to be deterministic, instead the classloader
* will remove all non-deterministic methods. * will remove all non-deterministic methods.
* @return a suitably constructed whitelisting classloader * @return a suitably constructed whitelisting classloader
* @throws URISyntaxException * @throws URISyntaxException
*/ */
public static WhitelistClassLoader of(final String auxiliaryClassPath, final boolean stripNonDeterministic) throws URISyntaxException { public static WhitelistClassLoader of(final String auxiliaryClassPath, final boolean stripNonDeterministic) throws URISyntaxException {
final WhitelistClassLoader out = new WhitelistClassLoader(stripNonDeterministic); final WhitelistClassLoader out = new WhitelistClassLoader(stripNonDeterministic);
@ -96,10 +97,10 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Static factory method. Used for recursive classloading * Static factory method. Used for recursive classloading
* *
* @param other * @param other
* @return a suitably constructed whitelisting classloader based on the state * @return a suitably constructed whitelisting classloader based on the state
* of the passed classloader * of the passed classloader
*/ */
public static WhitelistClassLoader of(final WhitelistClassLoader other) { public static WhitelistClassLoader of(final WhitelistClassLoader other) {
final WhitelistClassLoader out = new WhitelistClassLoader(other); final WhitelistClassLoader out = new WhitelistClassLoader(other);
@ -110,7 +111,7 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Helper method that adds a jar to the path to be searched * Helper method that adds a jar to the path to be searched
* *
* @param knownGoodJar * @param knownGoodJar
*/ */
void addJarToSandbox(final Path knownGoodJar) { void addJarToSandbox(final Path knownGoodJar) {
fileSystemSearchPath.add(knownGoodJar); fileSystemSearchPath.add(knownGoodJar);
@ -120,9 +121,9 @@ public final class WhitelistClassLoader extends ClassLoader {
* Setup the auxiliary classpath so that classes that are not on the original * Setup the auxiliary classpath so that classes that are not on the original
* classpath can be scanned for. * classpath can be scanned for.
* Note that this this method hardcodes Unix conventions, so won't work on e.g. Windows * Note that this this method hardcodes Unix conventions, so won't work on e.g. Windows
* *
* @param auxiliaryClassPath * @param auxiliaryClassPath
* @throws URISyntaxException * @throws URISyntaxException
*/ */
void setupClasspath(final String auxiliaryClassPath) throws URISyntaxException { void setupClasspath(final String auxiliaryClassPath) throws URISyntaxException {
for (String entry : auxiliaryClassPath.split(":")) { for (String entry : auxiliaryClassPath.split(":")) {
@ -136,11 +137,10 @@ public final class WhitelistClassLoader extends ClassLoader {
} }
/** /**
*
* @param qualifiedClassName * @param qualifiedClassName
* @return a class object that has been whitelist checked and is known to be * @return a class object that has been whitelist checked and is known to be
* deterministic * deterministic
* @throws ClassNotFoundException * @throws ClassNotFoundException
*/ */
@Override @Override
public Class<?> findClass(final String qualifiedClassName) throws ClassNotFoundException { public Class<?> findClass(final String qualifiedClassName) throws ClassNotFoundException {
@ -244,10 +244,10 @@ public final class WhitelistClassLoader extends ClassLoader {
* around a limitation of the ASM library that does not integrate cleanly with Java 7 * around a limitation of the ASM library that does not integrate cleanly with Java 7
* NIO.2 Path APIs. This method also performs a couple of basic sanity check on the * NIO.2 Path APIs. This method also performs a couple of basic sanity check on the
* class file (e.g. that it exists, is a regular file and is readable). * class file (e.g. that it exists, is a regular file and is readable).
* *
* @param internalClassName * @param internalClassName
* @return a path object that corresponds to a class that has been found * @return a path object that corresponds to a class that has been found
* @throws ClassNotFoundException * @throws ClassNotFoundException
*/ */
Path locateClassfileDir(final String internalClassName) throws ClassNotFoundException { Path locateClassfileDir(final String internalClassName) throws ClassNotFoundException {
// Check the primaryClasspathSearchPath // Check the primaryClasspathSearchPath
@ -300,7 +300,7 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Creates a jar archive of all the transformed classes that this classloader * Creates a jar archive of all the transformed classes that this classloader
* has loaded. * has loaded.
* *
* @return true on success, false on failure * @return true on success, false on failure
* @throws java.io.IOException * @throws java.io.IOException
* @throws java.net.URISyntaxException * @throws java.net.URISyntaxException
@ -328,7 +328,8 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Getter method for the reason for failure * Getter method for the reason for failure
* @return *
* @return
*/ */
public WhitelistClassloadingException reason() { public WhitelistClassloadingException reason() {
return candidacyStatus.getReason(); return candidacyStatus.getReason();
@ -336,7 +337,8 @@ public final class WhitelistClassLoader extends ClassLoader {
/** /**
* Getter method for the method candidacy status * Getter method for the method candidacy status
* @return *
* @return
*/ */
public CandidacyStatus getCandidacyStatus() { public CandidacyStatus getCandidacyStatus() {
return candidacyStatus; return candidacyStatus;

View File

@ -4,7 +4,7 @@ package net.corda.sandbox;
* *
*/ */
public class WhitelistClassloadingException extends Exception { public class WhitelistClassloadingException extends Exception {
public WhitelistClassloadingException() { public WhitelistClassloadingException() {
super(); super();
} }
@ -22,10 +22,10 @@ public class WhitelistClassloadingException extends Exception {
} }
protected WhitelistClassloadingException(String message, Throwable cause, protected WhitelistClassloadingException(String message, Throwable cause,
boolean enableSuppression, boolean enableSuppression,
boolean writableStackTrace) { boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace); super(message, cause, enableSuppression, writableStackTrace);
} }
} }

View File

@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory;
/** /**
* This class is the runtime representation of a running contract. * This class is the runtime representation of a running contract.
* *
* @author ben * @author ben
*/ */
public class Contract { public class Contract {

View File

@ -3,17 +3,17 @@ package net.corda.sandbox.costing;
/** /**
* This interface is to decouple the actual executable code from the entry point and * This interface is to decouple the actual executable code from the entry point and
* how vetted deterministic code will be used inside the sandbox * how vetted deterministic code will be used inside the sandbox
* *
* @author ben * @author ben
*/ */
public interface ContractExecutor { public interface ContractExecutor {
/** /**
* Executes a smart contract * Executes a smart contract
* *
* @param contract the contract to be executed * @param contract the contract to be executed
*/ */
void execute(Contract contract); void execute(Contract contract);
/** /**
* Checks to see if the supplied Contract is suitable * Checks to see if the supplied Contract is suitable
* *

View File

@ -4,7 +4,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public class RuntimeCostAccounter { public class RuntimeCostAccounter {

View File

@ -2,6 +2,7 @@ package net.corda.sandbox.tools;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import net.corda.sandbox.visitors.SandboxPathVisitor; import net.corda.sandbox.visitors.SandboxPathVisitor;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -18,7 +19,6 @@ import joptsimple.OptionSet;
* This class takes in an exploded set of JRE classes, and a whitelist, and rewrites all * This class takes in an exploded set of JRE classes, and a whitelist, and rewrites all
* classes (note: not methods) that have at least one whitelisted method to create a * classes (note: not methods) that have at least one whitelisted method to create a
* sandboxed version of the class. * sandboxed version of the class.
*
*/ */
// java8.scan.java.lang_and_util java8.interfaces_for_compat java8 sandbox // java8.scan.java.lang_and_util java8.interfaces_for_compat java8 sandbox
public final class SandboxCreator { public final class SandboxCreator {
@ -30,7 +30,7 @@ public final class SandboxCreator {
private final String outputJarName; private final String outputJarName;
private final WhitelistClassLoader wlcl; private final WhitelistClassLoader wlcl;
private final boolean hasInputJar; private final boolean hasInputJar;
private final static OptionParser parser = new OptionParser(); private final static OptionParser parser = new OptionParser();
private static void usage() { private static void usage() {
@ -53,7 +53,7 @@ public final class SandboxCreator {
static String unpackJar(final String zipFilePath) throws IOException { static String unpackJar(final String zipFilePath) throws IOException {
final Path tmpDir = Files.createTempDirectory(Paths.get("/tmp"), "wlcl-extract"); final Path tmpDir = Files.createTempDirectory(Paths.get("/tmp"), "wlcl-extract");
try (final ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { try (final ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) {
ZipEntry entry = zipIn.getNextEntry(); ZipEntry entry = zipIn.getNextEntry();
@ -68,13 +68,13 @@ public final class SandboxCreator {
entry = zipIn.getNextEntry(); entry = zipIn.getNextEntry();
} }
} }
return tmpDir.toString(); return tmpDir.toString();
} }
void cleanup() { void cleanup() {
if (hasInputJar) { if (hasInputJar) {
} }
} }
@ -107,10 +107,9 @@ public final class SandboxCreator {
} }
/** /**
*
* @param basePath * @param basePath
* @param packageName * @param packageName
* @throws IOException * @throws IOException
*/ */
void walk() throws IOException { void walk() throws IOException {
final Path scanDir = Paths.get(basePathName); final Path scanDir = Paths.get(basePathName);

View File

@ -9,7 +9,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
*
* @author ben * @author ben
*/ */
public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
@ -34,9 +33,10 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
} }
/** /**
* This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically * This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically
* stripping the synchronization out of any sandboxed code. * stripping the synchronization out of any sandboxed code.
* @param opcode *
* @param opcode
*/ */
@Override @Override
public void visitInsn(final int opcode) { public void visitInsn(final int opcode) {
@ -60,7 +60,7 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
* For our purposes this is a NEWARRAY opcode. * For our purposes this is a NEWARRAY opcode.
* *
* @param opcode * @param opcode
* @param operand * @param operand
*/ */
@Override @Override
public void visitIntInsn(final int opcode, final int operand) { public void visitIntInsn(final int opcode, final int operand) {
@ -103,11 +103,11 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter {
/** /**
* This method is called when visiting an opcode with a single operand, that * This method is called when visiting an opcode with a single operand, that
* is a type (represented here as a String). * is a type (represented here as a String).
* * <p>
* For our purposes this is either a NEW opcode or a ANEWARRAY * For our purposes this is either a NEW opcode or a ANEWARRAY
* *
* @param opcode * @param opcode
* @param type * @param type
*/ */
@Override @Override
public void visitTypeInsn(final int opcode, final String type) { public void visitTypeInsn(final int opcode, final String type) {

View File

@ -11,5 +11,5 @@ class DefinitelyDisallowedMethodVisitor extends MethodVisitor {
DefinitelyDisallowedMethodVisitor(MethodVisitor baseMethodVisitor) { DefinitelyDisallowedMethodVisitor(MethodVisitor baseMethodVisitor) {
super(Opcodes.ASM5, baseMethodVisitor); super(Opcodes.ASM5, baseMethodVisitor);
} }
} }

View File

@ -2,15 +2,17 @@ package net.corda.sandbox.visitors;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* This helper class visits each file (represented as a Path) in some directory * This helper class visits each file (represented as a Path) in some directory
* tree containing classes to be sandboxed. * tree containing classes to be sandboxed.
* *
* @author ben * @author ben
*/ */
public final class SandboxPathVisitor extends SimpleFileVisitor<Path> { public final class SandboxPathVisitor extends SimpleFileVisitor<Path> {
@ -30,10 +32,10 @@ public final class SandboxPathVisitor extends SimpleFileVisitor<Path> {
public FileVisitResult visitFile(final Path path, final BasicFileAttributes attr) { public FileVisitResult visitFile(final Path path, final BasicFileAttributes attr) {
// Check that this is a class file // Check that this is a class file
if (!path.toString().matches(Utils.CLASSFILE_NAME_SUFFIX)) { if (!path.toString().matches(Utils.CLASSFILE_NAME_SUFFIX)) {
System.out.println("Skipping: "+ path); System.out.println("Skipping: " + path);
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
// Check to see if this path corresponds to an allowedClass // Check to see if this path corresponds to an allowedClass
final String classFileName = startFrom.relativize(path).toString().replace(".class", ""); final String classFileName = startFrom.relativize(path).toString().replace(".class", "");

View File

@ -2,10 +2,12 @@ package net.corda.sandbox.visitors;
import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.WhitelistClassLoader;
import net.corda.sandbox.CandidacyStatus; import net.corda.sandbox.CandidacyStatus;
import java.util.Arrays; import java.util.Arrays;
import net.corda.sandbox.CandidateMethod; import net.corda.sandbox.CandidateMethod;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -14,6 +16,7 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.objectweb.asm.Opcodes.*; import static org.objectweb.asm.Opcodes.*;
/** /**
@ -57,7 +60,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor {
/** /**
* We initially take the method passed in and store an internal representation of * We initially take the method passed in and store an internal representation of
* the method signature in the our CandidacyStatus working set. * the method signature in the our CandidacyStatus working set.
* * <p>
* We then get an ASM MethodVisitor (which can read the byte code of the method) and pass that to our * We then get an ASM MethodVisitor (which can read the byte code of the method) and pass that to our
* custom method visitor which perform additional checks. * custom method visitor which perform additional checks.
* *
@ -66,7 +69,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor {
* @param desc * @param desc
* @param signature * @param signature
* @param exceptions * @param exceptions
* @return * @return
*/ */
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
@ -77,7 +80,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor {
// Force new access control flags - for now just strictfp for deterministic // Force new access control flags - for now just strictfp for deterministic
// compliance to IEEE 754 // compliance to IEEE 754
final int maskedAccess = access | ACC_STRICT; final int maskedAccess = access | ACC_STRICT;
final String internalName = classname + "." + name + ":" + desc; final String internalName = classname + "." + name + ":" + desc;
internalMethodNames.add(internalName); internalMethodNames.add(internalName);
candidacyStatus.putIfAbsent(internalName); candidacyStatus.putIfAbsent(internalName);
@ -151,10 +154,10 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor {
} }
/** /**
* Take the name of a class and attempts to load it using a WLCL. * Take the name of a class and attempts to load it using a WLCL.
* *
* @param qualifiedClassname * @param qualifiedClassname
* @return * @return
*/ */
CandidateMethod.State resolveState(final String qualifiedClassname) { CandidateMethod.State resolveState(final String qualifiedClassname) {
Class<?> clz = null; Class<?> clz = null;

View File

@ -13,7 +13,6 @@ import org.objectweb.asm.Label;
/** /**
* A MethodVisitor which checks method instructions in order to determine if this * A MethodVisitor which checks method instructions in order to determine if this
* method is deterministic or not * method is deterministic or not
*
*/ */
final class WhitelistCheckingMethodVisitor extends MethodVisitor { final class WhitelistCheckingMethodVisitor extends MethodVisitor {
@ -29,7 +28,7 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor {
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that * Visits a method instruction. A method instruction is an instruction that
* invokes a method. * invokes a method.
* <p> * <p>
* Some method instructions are by their nature un-deterministic, so we set those methods to have a * Some method instructions are by their nature un-deterministic, so we set those methods to have a
@ -84,15 +83,15 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor {
} }
/** /**
* Currently a no-op. * Currently a no-op.
* * <p>
* The JVMspec seems to permit the possibility of using a backwards branch in a * The JVMspec seems to permit the possibility of using a backwards branch in a
* tableswitch to try to create an infinite loop. However, it seems to be * tableswitch to try to create an infinite loop. However, it seems to be
* impossible in practice - the specification of StackMapFrame seems to prevent * impossible in practice - the specification of StackMapFrame seems to prevent
* it in modern classfile formats, and even by explicitly generating a version * it in modern classfile formats, and even by explicitly generating a version
* 49 (Java 5) classfile, the verifier seems to be specifically resistant to a * 49 (Java 5) classfile, the verifier seems to be specifically resistant to a
* backwards branch from a tableswitch. * backwards branch from a tableswitch.
* * <p>
* We could still add a belt-and-braces static instrumentation to protect * We could still add a belt-and-braces static instrumentation to protect
* against this but it currently seems unnecessary - at worse it is a branch that * against this but it currently seems unnecessary - at worse it is a branch that
* should count against the branch limit, or an explicit disallow of a backwards * should count against the branch limit, or an explicit disallow of a backwards
@ -102,7 +101,7 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor {
* @param min * @param min
* @param max * @param max
* @param dflt * @param dflt
* @param labels * @param labels
*/ */
@Override @Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
@ -112,11 +111,11 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor {
/** /**
* Visits an invokedynamic instruction - which is specifically disallowed for * Visits an invokedynamic instruction - which is specifically disallowed for
* deterministic apps. * deterministic apps.
* *
* @param name * @param name
* @param desc * @param desc
* @param bsm * @param bsm
* @param bsmArgs * @param bsmArgs
*/ */
@Override @Override
public void visitInvokeDynamicInsn(final String name, final String desc, final Handle bsm, final Object... bsmArgs) { public void visitInvokeDynamicInsn(final String name, final String desc, final Handle bsm, final Object... bsmArgs) {

View File

@ -4,7 +4,7 @@ package sandbox.net.corda.sandbox.costing;
* A helper class that just forwards any static sandboxed calls to the real runtime * A helper class that just forwards any static sandboxed calls to the real runtime
* cost accounting class. This removes the need to special case the accounting * cost accounting class. This removes the need to special case the accounting
* method calls during rewriting of method names * method calls during rewriting of method names
* *
* @author ben * @author ben
*/ */
public class RuntimeCostAccounter { public class RuntimeCostAccounter {

View File

@ -22,7 +22,7 @@ public class TestUtils {
// Copy resource jar to tmp dir // Copy resource jar to tmp dir
tmpdir = Files.createTempDirectory("wlcl-tmp-test"); tmpdir = Files.createTempDirectory("wlcl-tmp-test");
Path copiedJar = tmpdir.resolve("tmp-resource.jar"); Path copiedJar = tmpdir.resolve("tmp-resource.jar");
try(final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { try (final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) {
Files.copy(in, copiedJar, StandardCopyOption.REPLACE_EXISTING); Files.copy(in, copiedJar, StandardCopyOption.REPLACE_EXISTING);
} }
final FileSystem fs = FileSystems.newFileSystem(copiedJar, null); final FileSystem fs = FileSystems.newFileSystem(copiedJar, null);
@ -33,20 +33,20 @@ public class TestUtils {
public static Path copySandboxJarToTmpDir(final String resourcePathToJar) throws IOException { public static Path copySandboxJarToTmpDir(final String resourcePathToJar) throws IOException {
Path sandboxJar = tmpdir.resolve("tmp-sandbox.jar"); Path sandboxJar = tmpdir.resolve("tmp-sandbox.jar");
try(final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { try (final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) {
Files.copy(in, sandboxJar, StandardCopyOption.REPLACE_EXISTING); Files.copy(in, sandboxJar, StandardCopyOption.REPLACE_EXISTING);
} }
final FileSystem sandboxFs = FileSystems.newFileSystem(sandboxJar, null); final FileSystem sandboxFs = FileSystems.newFileSystem(sandboxJar, null);
tmpFileSystems.add(sandboxFs); tmpFileSystems.add(sandboxFs);
return sandboxFs.getRootDirectories().iterator().next(); return sandboxFs.getRootDirectories().iterator().next();
} }
public static Path getJarFSRoot() { public static Path getJarFSRoot() {
return jarFSDir; return jarFSDir;
} }
public static void cleanupTmpJar() throws IOException { public static void cleanupTmpJar() throws IOException {
for (FileSystem fs: tmpFileSystems) { for (FileSystem fs : tmpFileSystems) {
fs.close(); fs.close();
} }
tmpFileSystems.clear(); tmpFileSystems.clear();
@ -92,15 +92,15 @@ public class TestUtils {
// Helper for finding the correct offsets if they change // Helper for finding the correct offsets if they change
public static void printBytes(byte[] data) { public static void printBytes(byte[] data) {
byte[] datum = new byte[1]; byte[] datum = new byte[1];
for (int i=0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
datum[0] = data[i]; datum[0] = data[i];
System.out.println(i +" : "+ DatatypeConverter.printHexBinary(datum)); System.out.println(i + " : " + DatatypeConverter.printHexBinary(datum));
} }
} }
public static int findOffset(byte[] classBytes, byte[] originalSeq) { public static int findOffset(byte[] classBytes, byte[] originalSeq) {
int offset = 0; int offset = 0;
for (int i=415; i < classBytes.length; i++) { for (int i = 415; i < classBytes.length; i++) {
if (classBytes[i] != originalSeq[offset]) { if (classBytes[i] != originalSeq[offset]) {
offset = 0; offset = 0;
continue; continue;
@ -110,7 +110,7 @@ public class TestUtils {
} }
offset++; offset++;
} }
return -1; return -1;
} }
@ -119,7 +119,7 @@ public class TestUtils {
return wlcl.instrumentWithCosts(basic, hashSet); return wlcl.instrumentWithCosts(basic, hashSet);
} }
public static final class MyClassloader extends ClassLoader { public static final class MyClassloader extends ClassLoader {
public Class<?> byPath(Path p) throws IOException { public Class<?> byPath(Path p) throws IOException {

View File

@ -1,10 +1,13 @@
package net.corda.sandbox; package net.corda.sandbox;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.*; import org.junit.*;
public class WhitelistClassLoaderTest { public class WhitelistClassLoaderTest {
@ -123,8 +126,8 @@ public class WhitelistClassLoaderTest {
final Class<?> clz = wlcl.loadClass("resource.ThrowExceptions"); final Class<?> clz = wlcl.loadClass("resource.ThrowExceptions");
assertNotNull("ThrowExceptions class could not be transformed and loaded", clz); assertNotNull("ThrowExceptions class could not be transformed and loaded", clz);
} }
// TODO Test cases that terminate when other resource limits are broken // TODO Test cases that terminate when other resource limits are broken
@Test @Test
public void when_too_much_memory_is_allocated_then_thread_dies() throws Exception { public void when_too_much_memory_is_allocated_then_thread_dies() throws Exception {

View File

@ -11,7 +11,6 @@ import java.util.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
/** /**
*
* @author ben * @author ben
*/ */
public class DeterministicClassInstrumenterTest { public class DeterministicClassInstrumenterTest {
@ -66,7 +65,7 @@ public class DeterministicClassInstrumenterTest {
// TestUtils.printBytes(basic); // TestUtils.printBytes(basic);
final int origOffset = TestUtils.findOffset(basic, originalSeq); final int origOffset = TestUtils.findOffset(basic, originalSeq);
final int tmfdOffset = TestUtils.findOffset(tfmd, tfmdSeq); final int tmfdOffset = TestUtils.findOffset(tfmd, tfmdSeq);
for (int i = 0; i < originalSeq.length; i++) { for (int i = 0; i < originalSeq.length; i++) {
assertEquals(originalSeq[i], basic[origOffset + i]); assertEquals(originalSeq[i], basic[origOffset + i]);
assertEquals(tfmdSeq[i], tfmd[tmfdOffset + i]); assertEquals(tfmdSeq[i], tfmd[tmfdOffset + i]);

View File

@ -1,19 +1,24 @@
package net.corda.sandbox.costing; package net.corda.sandbox.costing;
import net.corda.sandbox.TestUtils; import net.corda.sandbox.TestUtils;
import static net.corda.sandbox.TestUtils.*; import static net.corda.sandbox.TestUtils.*;
import net.corda.sandbox.Utils; import net.corda.sandbox.Utils;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
/** /**
*
* @author ben * @author ben
*/ */
public class SandboxedRewritingTest { public class SandboxedRewritingTest {

View File

@ -1,7 +1,6 @@
package sandbox.greymalkin; package sandbox.greymalkin;
/** /**
*
* @author ben * @author ben
*/ */
// Simple hack for now, generalise to lambdas later... // Simple hack for now, generalise to lambdas later...