1 // Copyright 2009 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.tools
.development
.agent
.impl
;
5 import org
.objectweb
.asm
.ClassVisitor
;
6 import org
.objectweb
.asm
.MethodVisitor
;
7 import org
.objectweb
.asm
.Opcodes
;
8 import org
.objectweb
.asm
.Type
;
9 import org
.objectweb
.asm
.commons
.GeneratorAdapter
;
13 import java
.util
.HashMap
;
14 import java
.util
.HashSet
;
15 import java
.util
.Arrays
;
18 * Intercepts reflective operations and adds checks against the WhiteList.
21 public class ReflectionVisitor
extends ClassVisitor
{
23 public ReflectionVisitor(final ClassVisitor classVisitor
) {
24 super(Opcodes
.ASM4
, classVisitor
);
27 private static final Map
<String
, Set
<String
>> interceptedMethods
=
28 new HashMap
<String
,Set
<String
>>();
31 interceptedMethods
.put("java/lang/reflect/Method",
32 new HashSet
<String
>(Arrays
.asList("invoke")));
34 interceptedMethods
.put("java/lang/reflect/Field",
35 new HashSet
<String
>(Arrays
.asList(
56 interceptedMethods
.put("java/lang/reflect/Constructor",
57 new HashSet
<String
>(Arrays
.asList(
61 interceptedMethods
.put("java/lang/Class",
62 new HashSet
<String
>(Arrays
.asList(
68 public MethodVisitor
visitMethod(int access
, String name
, String desc
, String signature
,
69 String
[] exceptions
) {
70 MethodVisitor mv
= super.visitMethod(access
, name
, desc
, signature
, exceptions
);
71 return (mv
== null) ?
null : new MethodTranslator(mv
, access
, name
, desc
);
74 private class MethodTranslator
extends GeneratorAdapter
{
75 MethodTranslator(MethodVisitor methodVisitor
, int access
, String name
, String desc
) {
76 super(methodVisitor
, access
, name
, desc
);
80 public void visitMethodInsn(int opcode
, String owner
, String name
, String desc
) {
81 Set
<String
> methods
= interceptedMethods
.get(owner
);
82 if (methods
== null || !methods
.contains(name
)) {
83 super.visitMethodInsn(opcode
, owner
, name
, desc
);
87 String newDesc
= desc
;
89 if (opcode
== Opcodes
.INVOKEVIRTUAL
) {
90 final Type
[] argTypes
= Type
.getArgumentTypes(desc
);
91 final Type
[] newArgTypes
= new Type
[argTypes
.length
+ 1];
92 newArgTypes
[0] = Type
.getType("L" + owner
+ ";");
93 System
.arraycopy(argTypes
, 0, newArgTypes
, 1, argTypes
.length
);
94 newDesc
= Type
.getMethodDescriptor(Type
.getReturnType(desc
), newArgTypes
);
97 super.visitMethodInsn(Opcodes
.INVOKESTATIC
, AgentImpl
.AGENT_RUNTIME
, name
, newDesc
);