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