• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.obfuscate;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.util.*;
25 import proguard.util.ListUtil;
26 
27 
28 /**
29  * This MappingKeeper applies the mappings that it receives to its class pool,
30  * so these mappings are ensured in a subsequent obfuscation step.
31  *
32  * @author Eric Lafortune
33  */
34 public class MappingKeeper implements MappingProcessor
35 {
36     private final ClassPool      classPool;
37     private final WarningPrinter warningPrinter;
38 
39     // A field acting as a parameter.
40     private Clazz clazz;
41 
42 
43     /**
44      * Creates a new MappingKeeper.
45      * @param classPool      the class pool in which class names and class
46      *                       member names have to be mapped.
47      * @param warningPrinter the optional warning printer to which warnings
48      *                       can be printed.
49      */
MappingKeeper(ClassPool classPool, WarningPrinter warningPrinter)50     public MappingKeeper(ClassPool      classPool,
51                          WarningPrinter warningPrinter)
52     {
53         this.classPool      = classPool;
54         this.warningPrinter = warningPrinter;
55     }
56 
57 
58     // Implementations for MappingProcessor.
59 
processClassMapping(String className, String newClassName)60     public boolean processClassMapping(String className,
61                                        String newClassName)
62     {
63         // Find the class.
64         String name = ClassUtil.internalClassName(className);
65 
66         clazz = classPool.getClass(name);
67         if (clazz != null)
68         {
69             String newName = ClassUtil.internalClassName(newClassName);
70 
71             // Print out a warning if the mapping conflicts with a name that
72             // was set before.
73             if (warningPrinter != null)
74             {
75                 String currentNewName = ClassObfuscator.newClassName(clazz);
76                 if (currentNewName != null &&
77                     !currentNewName.equals(newName))
78                 {
79                     warningPrinter.print(name,
80                                          currentNewName,
81                                          "Warning: " +
82                                          className +
83                                          " is not being kept as '" +
84                                          ClassUtil.externalClassName(currentNewName) +
85                                          "', but remapped to '" +
86                                          newClassName + "'");
87                 }
88             }
89 
90             ClassObfuscator.setNewClassName(clazz, newName);
91 
92             // The class members have to be kept as well.
93             return true;
94         }
95 
96         return false;
97     }
98 
99 
processFieldMapping(String className, String fieldType, String fieldName, String newFieldName)100     public void processFieldMapping(String className,
101                                     String fieldType,
102                                     String fieldName,
103                                     String newFieldName)
104     {
105         if (clazz != null)
106         {
107             // Find the field.
108             String name       = fieldName;
109             String descriptor = ClassUtil.internalType(fieldType);
110 
111             Field field = clazz.findField(name, descriptor);
112             if (field != null)
113             {
114                 // Print out a warning if the mapping conflicts with a name that
115                 // was set before.
116                 if (warningPrinter != null)
117                 {
118                     String currentNewName = MemberObfuscator.newMemberName(field);
119                     if (currentNewName != null &&
120                         !currentNewName.equals(newFieldName))
121                     {
122                         warningPrinter.print(ClassUtil.internalClassName(className),
123                                              "Warning: " +
124                                              className +
125                                              ": field '" + fieldType + " " + fieldName +
126                                              "' is not being kept as '" + currentNewName +
127                                              "', but remapped to '" + newFieldName + "'");
128                     }
129                 }
130 
131                 // Make sure the mapping name will be kept.
132                 MemberObfuscator.setFixedNewMemberName(field, newFieldName);
133             }
134         }
135     }
136 
137 
processMethodMapping(String className, int firstLineNumber, int lastLineNumber, String methodReturnType, String methodName, String methodArguments, String newMethodName)138     public void processMethodMapping(String className,
139                                      int    firstLineNumber,
140                                      int    lastLineNumber,
141                                      String methodReturnType,
142                                      String methodName,
143                                      String methodArguments,
144                                      String newMethodName)
145     {
146         if (clazz != null)
147         {
148             // Find the method.
149             String descriptor = ClassUtil.internalMethodDescriptor(methodReturnType,
150                                                                    ListUtil.commaSeparatedList(methodArguments));
151 
152             Method method = clazz.findMethod(methodName, descriptor);
153             if (method != null)
154             {
155                 // Print out a warning if the mapping conflicts with a name that
156                 // was set before.
157                 if (warningPrinter != null)
158                 {
159                     String currentNewName = MemberObfuscator.newMemberName(method);
160                     if (currentNewName != null &&
161                         !currentNewName.equals(newMethodName))
162                     {
163                         warningPrinter.print(ClassUtil.internalClassName(className),
164                                              "Warning: " +
165                                              className +
166                                              ": method '" + methodReturnType + " " + methodName + ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN + methodArguments + ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE +
167                                              "' is not being kept as '" + currentNewName +
168                                              "', but remapped to '" + newMethodName + "'");
169                     }
170                 }
171 
172                 // Make sure the mapping name will be kept.
173                 MemberObfuscator.setFixedNewMemberName(method, newMethodName);
174             }
175         }
176     }
177 }
178