Skip to content

Commit

Permalink
Add test to check that class loader context or protection domain are …
Browse files Browse the repository at this point in the history
…not leaked.
  • Loading branch information
raphw committed Jun 23, 2021
1 parent f688942 commit 07411f0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,15 @@ public Invoker run() {
* An unsafe invoker that uses Byte Buddy's invocation context. This is only meant to be used if dynamic class generation
* is not supported, e.g. on an Android device.
*/
enum Unsafe implements Invoker {
@HashCodeAndEqualsPlugin.Enhance
class Unsafe implements Invoker {

/**
* The singleton instance.
* A private constructor to avoid instantiation from a foreign location to avoid leaking Byte Buddy's context.
*/
INSTANCE;
private Unsafe() {
/* do nothing */
}

/**
* {@inheritDoc}
Expand Down Expand Up @@ -1305,7 +1308,7 @@ protected static Invoker invoker() {
.getConstructor(NO_PARAMETER)
.newInstance(NO_ARGUMENT);
} catch (UnsupportedOperationException ignored) {
return Invoker.Unsafe.INSTANCE;
return new Invoker.Unsafe();
} catch (Exception exception) {
throw new IllegalStateException("Failed to create invoker for " + Invoker.class.getName(), exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void testNonStaticDispatcher() throws Exception {

@Test
public void testNonStaticAdjustedDispatcher() throws Exception {
assertThat(JavaDispatcher.of(NonStaticAdjustedSample.class).run().getMethod(Object.class, "equals", new Class<?>[]{Object.class}),
assertThat(JavaDispatcher.of(NonStaticAdjustedSample.class, null, generate).run().getMethod(Object.class, "equals", new Class<?>[]{Object.class}),
is(Object.class.getMethod("equals", Object.class)));
}

Expand Down Expand Up @@ -144,13 +144,35 @@ public void testProxy() {

@Test(expected = IllegalArgumentException.class)
public void testJavaSecurity() {
JavaDispatcher.of(ProtectionDomain.class);
JavaDispatcher.of(ProtectionDomain.class, null, generate);
}

@JavaVersionRule.Enforce(9)
@Test(expected = UnsupportedOperationException.class)
public void testMethodHandleLookup() {
JavaDispatcher.of(MethodHandles.class).run().lookup();
JavaDispatcher.of(MethodHandles.class, null, generate).run().lookup();
}

@Test(expected = IllegalAccessException.class)
public void testInvokerNotCreatable() throws Exception {
JavaDispatcher.Invoker.Unsafe.class.getDeclaredConstructor().newInstance();
}

@Test
@JavaVersionRule.Enforce(9)
public void testCallerNotLeakingContext() throws Exception {
Class<?> caller = JavaDispatcher.of(JavaDispatcherCaller.class, JavaDispatcherTest.class.getClassLoader(), generate).run().caller();
assertThat(caller.getClassLoader(), not(sameInstance(JavaDispatcherTest.class.getClassLoader())));
assertThat(caller.getProtectionDomain(), not(sameInstance(JavaDispatcherTest.class.getProtectionDomain())));
}

@SuppressWarnings({"unchecked", "unused"})
public static Class<?> caller() throws Exception {
Class<?> type = Class.forName("java.lang.StackWalker");
Class<?> option = Class.forName("java.lang.StackWalker$Option");
return (Class<?>) type.getMethod("getCallerClass").invoke(type.getMethod("getInstance", option).invoke(
null,
Enum.valueOf((Class) option, "RETAIN_CLASS_REFERENCE")));
}

@JavaDispatcher.Proxied("java.lang.Object")
Expand Down Expand Up @@ -268,4 +290,11 @@ public interface MethodHandles {
@JavaDispatcher.IsStatic
Object lookup();
}

@JavaDispatcher.Proxied("net.bytebuddy.utility.dispatcher.JavaDispatcherTest")
public interface JavaDispatcherCaller {

@JavaDispatcher.IsStatic
Class<?> caller() throws Exception;
}
}

0 comments on commit 07411f0

Please sign in to comment.