Skip to content

Commit

Permalink
make dynamic proxy safety
Browse files Browse the repository at this point in the history
  • Loading branch information
SmartDengg committed Feb 11, 2019
1 parent 037e081 commit 4bede5c
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 30 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.github.SmartDengg.interface-buoy:interface-buoy-gradle:1.0.0'
// classpath 'com.github.SmartDengg.interface-buoy:interface-buoy-gradle:1.0.0'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
14 changes: 7 additions & 7 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ dependencies {
implementation 'com.android.tools.build:gradle:3.3.0'
}

//sourceSets {
// main {
// groovy.srcDirs = ['../interface-buoy-gradle/src/main/groovy']
// java.srcDirs = ['../interface-buoy-gradle/src/main/java']
// resources.srcDirs = ['../interface-buoy-gradle/src/main/resources']
// }
//}
sourceSets {
main {
groovy.srcDirs = ['../interface-buoy-gradle/src/main/groovy']
java.srcDirs = ['../interface-buoy-gradle/src/main/java']
resources.srcDirs = ['../interface-buoy-gradle/src/main/resources']
}
}
3 changes: 2 additions & 1 deletion interface-buoy-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.github.SmartDengg.interface-buoy:interface-buoy-runtime:1.0.0'
// implementation 'com.github.SmartDengg.interface-buoy:interface-buoy-runtime:1.0.0'
implementation project(':interface-buoy-runtime')
}


Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.smartdengg.interfacebuoy.sample;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* 创建时间: 2019/01/11 15:52 <br>
* 作者: SmartDengg <br>
Expand All @@ -9,6 +13,10 @@ public class InvokeInterfaceTest {

private Callback callback;

private void m(Callback callback) {
ProxyHandler.wrap(callback, Callback.class);
}

private void m0(Callback callback) {
if (callback != null) {
callback.on(this);
Expand Down Expand Up @@ -61,4 +69,22 @@ interface Callback {

String get();
}

public static final class ProxyHandler {

static <T> T wrap(final T reference, Class<? extends T> interfacee) {

if (interfacee.isInterface()) {
return (T) Proxy.newProxyInstance(interfacee.getClassLoader(), new Class[] { interfacee },
new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (reference == null) return null;
return method.invoke(reference, args);
}
});
}
return reference;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import com.smartdengg.interfacebuoy.compiler.InterfaceBuoy;

Expand All @@ -13,6 +14,7 @@
*/
public class MainActivity extends Activity {

private static final String TAG = MainActivity.class.getSimpleName();
Callback callback;

@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
Expand All @@ -22,10 +24,13 @@ public class MainActivity extends Activity {

setCallback(new Callback() {
@Override public void on(View view) {
/*no-op*/
Log.d(TAG, "hello world");
}
});

//Test null interface reference
//setCallback(null);

findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
callback.on(v);
Expand Down
2 changes: 1 addition & 1 deletion interface-buoy-app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">nonnull-interface-gadle-plugin</string>
<string name="app_name">interface buoy</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class InterfaceBuoyTransform extends Transform {

@Override
String getName() {
return 'interfacebuoy'
return 'interfaceBuoy'
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
&& ((MethodInsnNode) node).name.equals(name)
&& ((MethodInsnNode) node).desc.equals(desc))) {

insertBeforeInvokeInterface(node, convertSignature(owner, name, desc));
insertBeforeInvokeInterface(node, Type.getObjectType(owner).getClassName(),
convertSignature(owner, name, desc));

iterator.remove();
break;
Expand All @@ -91,16 +92,17 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
super.visitMethodInsn(opcode, owner, name, desc, itf);
}

private void insertBeforeInvokeInterface(AbstractInsnNode node, String name) {
private void insertBeforeInvokeInterface(AbstractInsnNode node, String className, String desc) {
AbstractInsnNode previous = node.getPrevious();
if (previous instanceof MethodInsnNode) {
insertBeforeInvokeInterface(previous, name);
insertBeforeInvokeInterface(previous, className, desc);
} else {
super.visitLdcInsn(name);
super.visitLdcInsn(className);
super.visitLdcInsn(desc);
super.visitMethodInsn(INVOKESTATIC, //
"com/smartdengg/interfacebuoy/compiler/InterfaceBuoy", //
"wrap", //
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", //
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;",
false);

if (previous != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@ public final class InterfaceBuoy {

private static final String TAG = "BUOY";

public static <T> T wrap(T instance, Object value, String desc) {
Class<?>[] interfaces = instance.getClass().getInterfaces();
if (Utils.validateInterface(interfaces)) {
public static <T> T wrap(T instance, Object value, String interfaceName, String desc) {

if (loggable) {
Log.d(TAG, "BUOY INTERFACE: " + desc);
Log.d(TAG, "VALUE = " + Strings.toString(value));
try {
Class<?> interfacee = Class.forName(interfaceName);
if (Utils.validateInterface(interfacee)) {

if (loggable) {
Log.d(TAG, "BUOY INTERFACE: " + desc);
Log.d(TAG, "VALUE = " + Strings.toString(value));
}

//noinspection unchecked
return (T) Proxy.newProxyInstance(interfacee.getClassLoader(), new Class[] { interfacee },
new InvocationHandlerAdapter(instance));
}
} catch (Exception ignore) {

//noinspection unchecked
return (T) Proxy.newProxyInstance(instance.getClass().getClassLoader(),
new Class[] { interfaces[0] }, new InvocationHandlerAdapter(instance));
}
return instance;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ private Utils() {
throw new AssertionError("no instance");
}

static boolean validateInterface(Class<?>[] interfaces) {
return interfaces != null
&& interfaces.length == 1
&& interfaces[0].getInterfaces().length == 0;
static boolean validateInterface(Class<?> interfacee) {
return interfacee != null && interfacee.isInterface() && interfacee.getInterfaces().length == 0;
}
}

0 comments on commit 4bede5c

Please sign in to comment.