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
;
10 import java
.util
.HashSet
;
14 * Visits method and field instructions, checking for references to
15 * blacklisted classes.
18 public class ObjectAccessVisitor
extends ClassVisitor
{
20 private static final String REJECT
= "reject";
22 private static final String REJECT_DESCRIPTOR
= "(Ljava/lang/String;)V";
24 private static final String CHECK_RESTRICTED
= "checkRestricted";
26 private static final String CHECK_RESTRICTED_DESCRIPTOR
=
27 "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
29 private final boolean isUserCode
;
30 private final boolean treatRestrictedListViolationsAsErrors
;
31 private final String callingClassName
;
32 private final String callingClassCodeSource
;
33 private final Set
<String
> referencedClasses
= new HashSet
<String
>();
35 public ObjectAccessVisitor(
36 ClassVisitor classVisitor
, boolean isUserCode
,
37 boolean treatRestrictedListViolationsAsErrors
, String callingClassName
, URL callingClassCodeSource
) {
38 super(Opcodes
.ASM4
, classVisitor
);
39 this.isUserCode
= isUserCode
;
40 this.treatRestrictedListViolationsAsErrors
= treatRestrictedListViolationsAsErrors
;
41 this.callingClassName
= callingClassName
;
42 this.callingClassCodeSource
=
43 callingClassCodeSource
== null ?
"unknown location" : callingClassCodeSource
.toString();
47 public MethodVisitor
visitMethod(int access
, String name
, String desc
, String signature
,
48 String
[] exceptions
) {
49 MethodVisitor mv
= super.visitMethod(access
, name
, desc
, signature
, exceptions
);
50 return (mv
== null) ?
null : new MethodTranslator(mv
, access
, name
, desc
);
53 private class MethodTranslator
extends NonRecordingGeneratorAdapter
{
54 MethodTranslator(MethodVisitor methodVisitor
, int access
, String name
, String desc
) {
55 super(methodVisitor
, access
, name
, desc
);
59 public void visitFieldInsn(int opcode
, String owner
, String name
, String desc
) {
61 super.visitFieldInsn(opcode
, owner
, name
, desc
);
65 public void visitMethodInsn(int opcode
, String owner
, String name
, String desc
) {
67 super.visitMethodInsn(opcode
, owner
, name
, desc
);
70 private void maybeReject(String klass
) {
71 if (BlackList
.getBlackList().contains(klass
)) {
72 super.push(klass
.replace('/', '.'));
73 super.visitMethodInsn(Opcodes
.INVOKESTATIC
, AgentImpl
.AGENT_RUNTIME
,
74 REJECT
, REJECT_DESCRIPTOR
);
75 } else if (isUserCode
&& !referencedClasses
.contains(klass
)) {
76 referencedClasses
.add(klass
);
77 super.push(treatRestrictedListViolationsAsErrors
);
78 super.push(klass
.replace('/', '.'));
79 super.push(callingClassName
);
80 super.push(callingClassCodeSource
);
81 super.visitMethodInsn(Opcodes
.INVOKESTATIC
, AgentImpl
.AGENT_RUNTIME
,
82 CHECK_RESTRICTED
, CHECK_RESTRICTED_DESCRIPTOR
);