[Git][java-team/proguard][upstream] 2 commits: New upstream version 6.0.2
Emmanuel Bourg
gitlab at salsa.debian.org
Mon Dec 10 23:21:09 GMT 2018
Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / proguard
Commits:
dea12d6d by Emmanuel Bourg at 2018-12-10T23:15:23Z
New upstream version 6.0.2
- - - - -
89a9f2bf by Emmanuel Bourg at 2018-12-10T23:15:49Z
New upstream version 6.0.3
- - - - -
28 changed files:
- annotations/pom.xml
- ant/pom.xml
- buildscripts/pom.xml
- core/pom.xml
- core/src/proguard/ClassSpecificationVisitorFactory.java
- core/src/proguard/DataEntryReaderFactory.java
- core/src/proguard/DataEntryWriterFactory.java
- core/src/proguard/ProGuard.java
- core/src/proguard/backport/LambdaExpression.java
- core/src/proguard/backport/LambdaExpressionCollector.java
- core/src/proguard/classfile/ClassConstants.java
- core/src/proguard/classfile/JavaConstants.java
- core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
- core/src/proguard/classfile/constant/visitor/BootstrapMethodArgumentVisitor.java → core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java
- core/src/proguard/classfile/editor/AccessFixer.java
- core/src/proguard/classfile/util/ClassUtil.java
- + core/src/proguard/classfile/visitor/MultiConstantVisitor.java
- core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
- core/src/proguard/classfile/visitor/SimilarMemberVisitor.java
- core/src/proguard/io/JarWriter.java
- core/src/proguard/obfuscate/Obfuscator.java
- core/src/proguard/optimize/Optimizer.java
- core/src/proguard/preverify/CodePreverifier.java
- gradle/pom.xml
- gui/pom.xml
- gui/src/proguard/gui/GUIResources.properties
- retrace/pom.xml
- wtk/pom.xml
Changes:
=====================================
annotations/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-annotations</artifactId>
=====================================
ant/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-anttask</artifactId>
=====================================
buildscripts/pom.xml
=====================================
@@ -7,7 +7,7 @@
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<packaging>pom</packaging>
<name>[${project.groupId}] ${project.artifactId}</name>
<description>ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier.</description>
=====================================
core/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-base</artifactId>
=====================================
core/src/proguard/ClassSpecificationVisitorFactory.java
=====================================
@@ -545,7 +545,7 @@ public class ClassSpecificationVisitorFactory
StringMatcher nameMatcher = name == null ? null :
new ListParser(new NameParser(variableStringMatchers)).parse(name);
- StringMatcher descriptorMatcher = name == null ? null :
+ StringMatcher descriptorMatcher = descriptor == null ? null :
new ListParser(new ClassNameParser(variableStringMatchers)).parse(descriptor);
StringMatcher attributesMatcher = attributeNames == null ? null :
=====================================
core/src/proguard/DataEntryReaderFactory.java
=====================================
@@ -95,31 +95,31 @@ public class DataEntryReaderFactory
}
// Unzip any apks, if necessary.
- reader = wrapInJarReader(reader, false, isApk, apkFilter, ".apk");
+ reader = wrapInJarReader(reader, false, false, isApk, apkFilter, ".apk");
if (!isApk)
{
// Unzip any jars, if necessary.
- reader = wrapInJarReader(reader, false, isJar, jarFilter, ".jar");
+ reader = wrapInJarReader(reader, false, false, isJar, jarFilter, ".jar");
if (!isJar)
{
// Unzip any aars, if necessary.
- reader = wrapInJarReader(reader, false, isAar, aarFilter, ".aar");
+ reader = wrapInJarReader(reader, false, false, isAar, aarFilter, ".aar");
if (!isAar)
{
// Unzip any wars, if necessary.
- reader = wrapInJarReader(reader, false, isWar, warFilter, ".war");
+ reader = wrapInJarReader(reader, true, false, isWar, warFilter, ".war");
if (!isWar)
{
// Unzip any ears, if necessary.
- reader = wrapInJarReader(reader, false, isEar, earFilter, ".ear");
+ reader = wrapInJarReader(reader, false, false, isEar, earFilter, ".ear");
if (!isEar)
{
// Unzip any jmods, if necessary.
- reader = wrapInJarReader(reader, true, isJmod, jmodFilter, ".jmod");
+ reader = wrapInJarReader(reader, true, true, isJmod, jmodFilter, ".jmod");
if (!isJmod)
{
// Unzip any zips, if necessary.
- reader = wrapInJarReader(reader, false, isZip, zipFilter, ".zip");
+ reader = wrapInJarReader(reader, false, false, isZip, zipFilter, ".zip");
}
}
}
@@ -132,12 +132,14 @@ public class DataEntryReaderFactory
/**
- * Wraps the given DataEntryReader in a JarReader, filtering it if necessary.
+ * Wraps the given DataEntryReader in a JarReader, filtering it if
+ * necessary.
* @param reader the data entry reader that can read the
* entries contained in the jar file.
- * @param isJmod specifies whether to strip the "classes/"
- * prefix from contained .class data entries
- * and the jmod magic bytes from the zip.
+ * @param stripClassesPrefix specifies whether to strip the ""classes/"
+ * prefix from contained .class data entries.
+ *@param stripJmodHeader specifies whether to strip the jmod magic
+ * bytes from the zip.
* @param isJar specifies whether the data entries should
* always be unzipped.
* @param jarFilter otherwise, an optional filter on the data
@@ -148,21 +150,22 @@ public class DataEntryReaderFactory
* entries.
*/
private static DataEntryReader wrapInJarReader(DataEntryReader reader,
- boolean isJmod,
+ boolean stripClassesPrefix,
+ boolean stripJmodHeader,
boolean isJar,
List jarFilter,
String jarExtension)
{
- if (isJmod)
+ if (stripClassesPrefix)
{
reader = new FilteredDataEntryReader(
- new DataEntryNameFilter(new ExtensionMatcher(".class")),
- new PrefixStrippingDataEntryReader("classes/", reader),
+ new DataEntryNameFilter(new ExtensionMatcher(ClassConstants.CLASS_FILE_EXTENSION)),
+ new PrefixStrippingDataEntryReader(ClassConstants.JMOD_CLASS_FILE_PREFIX, reader),
reader);
}
// Unzip any jars, if necessary.
- DataEntryReader jarReader = new JarReader(reader, isJmod);
+ DataEntryReader jarReader = new JarReader(reader, stripJmodHeader);
if (isJar)
{
=====================================
core/src/proguard/DataEntryWriterFactory.java
=====================================
@@ -129,19 +129,30 @@ public class DataEntryWriterFactory
isJmod ||
isZip);
+ // If the output is an archive, we'll flatten (unpack the contents of)
+ // higher level input archives, e.g. when writing into a jar file, we
+ // flatten zip files.
+ boolean flattenApks = false;
+ boolean flattenJars = flattenApks || isApk;
+ boolean flattenAars = flattenJars || isJar;
+ boolean flattenWars = flattenAars || isAar;
+ boolean flattenEars = flattenWars || isWar;
+ boolean flattenJmods = flattenEars || isEar;
+ boolean flattenZips = flattenJmods || isJmod;
+
// Set up the filtered jar writers.
- writer = wrapInJarWriter(writer, false, null, isZip, zipFilter, ".zip", isApk || isJar || isAar || isWar || isEar || isJmod);
- writer = wrapInJarWriter(writer, true, ClassConstants.JMOD_HEADER, isJmod, jmodFilter, ".jmod", isApk || isJar || isAar || isWar || isEar);
- writer = wrapInJarWriter(writer, false, null, isEar, earFilter, ".ear", isApk || isJar || isAar || isWar);
- writer = wrapInJarWriter(writer, true, null, isWar, warFilter, ".war", isApk || isJar || isAar);
- writer = wrapInJarWriter(writer, false, null, isAar, aarFilter, ".aar", isApk || isJar);
- writer = wrapInJarWriter(writer, false, null, isJar, jarFilter, ".jar", isApk);
- writer = wrapInJarWriter(writer, false, null, isApk, apkFilter, ".apk", false);
+ writer = wrapInJarWriter(writer, flattenZips, isZip, ".zip", zipFilter, null, null);
+ writer = wrapInJarWriter(writer, flattenJmods, isJmod, ".jmod", jmodFilter, ClassConstants.JMOD_HEADER, ClassConstants.JMOD_CLASS_FILE_PREFIX);
+ writer = wrapInJarWriter(writer, flattenEars, isEar, ".ear", earFilter, null, null);
+ writer = wrapInJarWriter(writer, flattenWars, isWar, ".war", warFilter, null, ClassConstants.WAR_CLASS_FILE_PREFIX);
+ writer = wrapInJarWriter(writer, flattenAars, isAar, ".aar", aarFilter, null, null);
+ writer = wrapInJarWriter(writer, flattenJars, isJar, ".jar", jarFilter, null, null);
+ writer = wrapInJarWriter(writer, flattenApks, isApk, ".apk", apkFilter, null, null);
// Set up for writing out the program classes.
writer = new ClassDataEntryWriter(programClassPool, writer);
- // Add a filter, if specified.
+ // Add a data entry filter, if specified.
writer = filter != null ?
new FilteredDataEntryWriter(
new DataEntryNameFilter(
@@ -166,46 +177,61 @@ public class DataEntryWriterFactory
* Wraps the given DataEntryWriter in a JarWriter, filtering if necessary.
*/
private DataEntryWriter wrapInJarWriter(DataEntryWriter writer,
- boolean addClassesPrefix,
- byte[] header,
- boolean isJar,
+ boolean flatten,
+ boolean isOutputJar,
+ String jarFilterExtension,
List jarFilter,
- String jarExtension,
- boolean dontWrap)
+ byte[] jarHeader,
+ String classFilePrefix)
{
- // Zip up jars, if necessary.
- DataEntryWriter jarWriter =
- dontWrap ?
- new ParentDataEntryWriter(writer) :
- new JarWriter(header, writer);
-
- // Add a "classes/" prefix for class files, if specified.
- if (addClassesPrefix)
+ // Flatten jars or zip them up.
+ DataEntryWriter jarWriter;
+ if (flatten)
{
- writer = new FilteredDataEntryWriter(
- new DataEntryNameFilter(
- new ExtensionMatcher(".class")),
- new PrefixAddingDataEntryWriter("classes/",
- writer),
- writer);
+ // Unpack the jar.
+ jarWriter = new ParentDataEntryWriter(writer);
+ }
+ else
+ {
+ // Pack the jar.
+ jarWriter = new JarWriter(jarHeader, writer);
+
+ // Add a prefix for class files inside the jar, if specified.
+ if (classFilePrefix != null)
+ {
+ jarWriter =
+ new FilteredDataEntryWriter(
+ new DataEntryNameFilter(
+ new ExtensionMatcher(ClassConstants.CLASS_FILE_EXTENSION)),
+ new PrefixAddingDataEntryWriter(classFilePrefix,
+ jarWriter),
+ jarWriter);
+ }
}
- // Add a filter, if specified.
- DataEntryWriter filteredJarWriter = jarFilter != null ?
+ // Either zip up the jar or delegate to the original writer.
+ return
new FilteredDataEntryWriter(
new DataEntryParentFilter(
new DataEntryNameFilter(
- new ListParser(new FileNameParser()).parse(jarFilter))),
- jarWriter) :
-
- jarWriter;
-
- // Only zip up jars, unless the output is a jar file itself.
- return new FilteredDataEntryWriter(
- new DataEntryParentFilter(
- new DataEntryNameFilter(
- new ExtensionMatcher(jarExtension))),
- filteredJarWriter,
- isJar ? jarWriter : writer);
+ new ExtensionMatcher(jarFilterExtension))),
+
+ // The parent of the data entry is a jar.
+ // Write the data entry to the jar.
+ // Apply the jar filter, if specified, to the parent.
+ jarFilter != null ?
+ new FilteredDataEntryWriter(
+ new DataEntryParentFilter(
+ new DataEntryNameFilter(
+ new ListParser(new FileNameParser()).parse(jarFilter))),
+ jarWriter) :
+ jarWriter,
+
+ // The parent of the data entry is not a jar.
+ // Write the entry to a jar anyway if the output is a jar.
+ // Otherwise just delegate to the original writer.
+ isOutputJar ?
+ jarWriter :
+ writer);
}
}
=====================================
core/src/proguard/ProGuard.java
=====================================
@@ -43,7 +43,7 @@ import java.io.*;
*/
public class ProGuard
{
- public static final String VERSION = "ProGuard, version 6.0.1";
+ public static final String VERSION = "ProGuard, version 6.0.3";
private final Configuration configuration;
private ClassPool programClassPool = new ClassPool();
=====================================
core/src/proguard/backport/LambdaExpression.java
=====================================
@@ -3,6 +3,20 @@
* of Java bytecode.
*
* Copyright (c) 2002-2018 GuardSquare NV
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.backport;
=====================================
core/src/proguard/backport/LambdaExpressionCollector.java
=====================================
@@ -185,7 +185,8 @@ implements ClassVisitor,
for (int i = 0; i < bridgeMethodCount; i++)
{
MethodTypeConstant methodTypeConstant =
- (MethodTypeConstant) programClass.getConstant(argumentIndex++);
+ getMethodTypeConstant(programClass,
+ bootstrapMethodInfo.u2methodArguments[argumentIndex++]);
lambdaExpression.bridgeMethodDescriptors =
ArrayUtil.add(lambdaExpression.bridgeMethodDescriptors,
=====================================
core/src/proguard/classfile/ClassConstants.java
=====================================
@@ -27,9 +27,12 @@ package proguard.classfile;
*/
public class ClassConstants
{
- public static final byte[] JMOD_HEADER = new byte[] { 'J', 'M', 1, 0 };
+ public static final String WAR_CLASS_FILE_PREFIX = "classes/";
- public static final String CLASS_FILE_EXTENSION = ".class";
+ public static final byte[] JMOD_HEADER = new byte[] { 'J', 'M', 1, 0 };
+ public static final String JMOD_CLASS_FILE_PREFIX = "classes/";
+
+ public static final String CLASS_FILE_EXTENSION = ".class";
public static final int MAGIC = 0xCAFEBABE;
@@ -51,6 +54,8 @@ public class ClassConstants
public static final int CLASS_VERSION_1_8_MINOR = 0;
public static final int CLASS_VERSION_1_9_MAJOR = 53;
public static final int CLASS_VERSION_1_9_MINOR = 0;
+ public static final int CLASS_VERSION_10_MAJOR = 54;
+ public static final int CLASS_VERSION_10_MINOR = 0;
public static final int CLASS_VERSION_1_0 = (CLASS_VERSION_1_0_MAJOR << 16) | CLASS_VERSION_1_0_MINOR;
public static final int CLASS_VERSION_1_2 = (CLASS_VERSION_1_2_MAJOR << 16) | CLASS_VERSION_1_2_MINOR;
@@ -61,6 +66,7 @@ public class ClassConstants
public static final int CLASS_VERSION_1_7 = (CLASS_VERSION_1_7_MAJOR << 16) | CLASS_VERSION_1_7_MINOR;
public static final int CLASS_VERSION_1_8 = (CLASS_VERSION_1_8_MAJOR << 16) | CLASS_VERSION_1_8_MINOR;
public static final int CLASS_VERSION_1_9 = (CLASS_VERSION_1_9_MAJOR << 16) | CLASS_VERSION_1_9_MINOR;
+ public static final int CLASS_VERSION_10 = (CLASS_VERSION_10_MAJOR << 16) | CLASS_VERSION_10_MINOR;
public static final int ACC_PUBLIC = 0x0001;
public static final int ACC_PRIVATE = 0x0002;
=====================================
core/src/proguard/classfile/JavaConstants.java
=====================================
@@ -44,6 +44,7 @@ public interface JavaConstants
public static final String CLASS_VERSION_1_7_ALIAS = "7";
public static final String CLASS_VERSION_1_8_ALIAS = "8";
public static final String CLASS_VERSION_1_9_ALIAS = "9";
+ public static final String CLASS_VERSION_10 = "10";
public static final String ACC_PUBLIC = "public";
public static final String ACC_PRIVATE = "private";
@@ -92,4 +93,4 @@ public interface JavaConstants
public static final String TYPE_LONG = "long";
public static final String TYPE_DOUBLE = "double";
public static final String TYPE_ARRAY = "[]";
-}
\ No newline at end of file
+}
=====================================
core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
=====================================
@@ -23,7 +23,6 @@ package proguard.classfile.attribute.visitor;
import proguard.classfile.Clazz;
import proguard.classfile.attribute.BootstrapMethodInfo;
-
/**
* This interface specifies the methods for a visitor of
* <code>BootstrapMethodInfo</code> objects. Note that there is only a single
=====================================
core/src/proguard/classfile/constant/visitor/BootstrapMethodArgumentVisitor.java → core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java
=====================================
@@ -28,19 +28,18 @@ import proguard.classfile.attribute.visitor.BootstrapMethodInfoVisitor;
* This BootstrapMethodInfoVisitor lets a given ConstantVisitor visit all
* constant pool entries of the bootstrap methods it visits.
*
- *
* @author Eric Lafortune
*/
-public class BootstrapMethodArgumentVisitor
+public class AllBootstrapMethodArgumentVisitor
implements BootstrapMethodInfoVisitor
{
private ConstantVisitor constantVisitor;
/**
- * Creates a new BootstrapMethodArgumentVisitor that will delegate to the
- * given constant visitor.
+ * Creates a new AllBootstrapMethodArgumentVisitor that will delegate to
+ * the given constant visitor.
*/
- public BootstrapMethodArgumentVisitor(ConstantVisitor constantVisitor)
+ public AllBootstrapMethodArgumentVisitor(ConstantVisitor constantVisitor)
{
this.constantVisitor = constantVisitor;
}
@@ -50,7 +49,6 @@ implements BootstrapMethodInfoVisitor
public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
{
- // Check bootstrap method.
bootstrapMethodInfo.methodArgumentsAccept(clazz, constantVisitor);
}
}
=====================================
core/src/proguard/classfile/editor/AccessFixer.java
=====================================
@@ -21,8 +21,13 @@
package proguard.classfile.editor;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.visitor.AllElementValueVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -33,164 +38,155 @@ import proguard.classfile.visitor.*;
* @author Eric Lafortune
*/
public class AccessFixer
-extends ReferencedClassVisitor
implements ClassVisitor
{
- private final ConstantVisitor referencedClassStorer = new MyReferencedClassStorer();
+ private final ClassVisitor referencedClassFixer =
+ new ReferencedClassVisitor(
+ new MyReferencedClassAccessFixer());
+ private final ClassVisitor referencedMemberFixer =
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new AllInstructionVisitor(
+ new MyReferencedMemberVisitor(
+ new MyReferencedMemberAccessFixer()))));
- /**
- * Creates a new AccessFixer.
- */
- public AccessFixer()
- {
- // Unfortunately, the inner class must be static to be passed to the
- // super constructor. We therefore can't let it refer to this class;
- // we'll let this class refer to the inner class instead.
- super(new MyAccessFixer());
- }
+ private final ClassVisitor referencedAnnotationMethodFixer =
+ new AllAttributeVisitor(true,
+ new AllElementValueVisitor(
+ new MyReferencedMemberVisitor(
+ new MyReferencedMemberAccessFixer())));
+ private final ClassVisitor methodHierarchyFixer =
+ new AllMethodVisitor(
+ new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC,
+ new InitializerMethodFilter(null,
+ new SimilarMemberVisitor(false, true, false, true,
+ new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC,
+ new MyReferencedMemberAccessFixer())))));
- // Overridden methods for ClassVisitor.
+
+ // Fields acting as parameters for the visitors.
- public void visitProgramClass(ProgramClass programClass)
- {
- // Remember the referencing class.
- ((MyAccessFixer)classVisitor).referencingClass = programClass;
+ private Clazz referencingClass;
+ private int referencingMethodAccessFlags;
+ private Clazz referencedClass;
- // Start visiting and fixing the referenced classes and class members.
- super.visitProgramClass(programClass);
- }
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
- public void visitLibraryClass(LibraryClass libraryClass)
+ public void visitProgramClass(ProgramClass programClass)
{
// Remember the referencing class.
- ((MyAccessFixer)classVisitor).referencingClass = libraryClass;
+ referencingClass = programClass;
- // Start visiting and fixing the referenced classes and class members.
- super.visitLibraryClass(libraryClass);
- }
+ // Fix the referenced classes.
+ referencedClassFixer.visitProgramClass(programClass);
+ // Fix the referenced class members.
+ referencedMemberFixer.visitProgramClass(programClass);
- // Overridden methods for MemberVisitor.
+ // Fix the referenced annotation methods.
+ referencedAnnotationMethodFixer.visitProgramClass(programClass);
- public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
- {
- // Fix the referenced classes and class members.
- super.visitProgramMember(programClass, programMethod);
-
- // Fix overridden or implemented methods higher up the hierarchy.
- // We can ignore private and static methods and initializers.
- if ((programMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
- ClassConstants.ACC_STATIC)) == 0 &&
- !ClassUtil.isInitializer(programMethod.getName(programClass)))
- {
- programClass.hierarchyAccept(false, true, false, false,
- new NamedMethodVisitor(programMethod.getName(programClass),
- programMethod.getDescriptor(programClass),
- new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
- ClassConstants.ACC_STATIC,
- (MemberVisitor)classVisitor)));
- }
+ // Fix overridden and overriding methods up and down the hierarchy.
+ // They are referenced implicitly and need to be accessible too.
+ referencingMethodAccessFlags = 0;
+ referencedClass = null;
+
+ methodHierarchyFixer.visitProgramClass(programClass);
}
- public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ /**
+ * This ReferencedMemberVisitor is an InstructionVisitor that also
+ * remembers the access flags of the referencing methods, and the
+ * referenced class.
+ */
+ private class MyReferencedMemberVisitor
+ extends ReferencedMemberVisitor
+ implements InstructionVisitor
{
- // Fix the referenced classes and class members.
- super.visitLibraryMember(libraryClass, libraryMethod);
-
- // Fix overridden or implemented methods higher up the hierarchy.
- // We can ignore private and static methods and initializers.
- if ((libraryMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
- ClassConstants.ACC_STATIC)) == 0 &&
- !ClassUtil.isInitializer(libraryMethod.getName(libraryClass)))
+ public MyReferencedMemberVisitor(MemberVisitor memberVisitor)
{
- libraryClass.hierarchyAccept(false, true, false, false,
- new NamedMethodVisitor(libraryMethod.getName(libraryClass),
- libraryMethod.getDescriptor(libraryClass),
- new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
- ClassConstants.ACC_STATIC,
- (MemberVisitor)classVisitor)));
+ super(memberVisitor);
}
- }
- // Overridden methods for ConstantVisitor.
+ // Implementations for InstructionVisitor.
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
- {
- // Fix the access flags of the referenced class, if any.
- super.visitStringConstant(clazz, stringConstant);
-
- // Fix the access flags of the referenced class member, if any.
- stringConstant.referencedMemberAccept((MemberVisitor)classVisitor);
- }
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
- public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
- {
- // Remember the referenced class. Note that we're interested in the
- // class of the invocation, not in the class in which the member was
- // actually found, unless it is an array type.
- if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz)))
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
- // For an array type, the class will be java.lang.Object.
- ((MyAccessFixer)classVisitor).referencedClass =
- refConstant.referencedClass;
- }
- else
- {
- // Remember the referenced class.
- clazz.constantPoolEntryAccept(refConstant.u2classIndex,
- referencedClassStorer);
+ // Remember the access flags.
+ referencingMethodAccessFlags = method.getAccessFlags();
+
+ // Fix the referenced classes and class members.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
}
- // Fix the access flags of the class of the referenced class member.
- super.visitAnyRefConstant(clazz, refConstant);
- // Fix the access flags of the referenced class member.
- refConstant.referencedMemberAccept((MemberVisitor)classVisitor);
- }
+ // Overridden methods for ConstantVisitor.
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Remember the referenced class. Note that we're interested in the
+ // class of the invocation, not in the class in which the member was
+ // actually found, unless it is an array type.
+ if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz)))
+ {
+ // For an array type, the class will be java.lang.Object.
+ referencedClass = refConstant.referencedClass;
+ }
+ else
+ {
+ // Remember the referenced class.
+ clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+ }
+
+ // Fix the access flags of referenced class member.
+ super.visitAnyRefConstant(clazz, refConstant);
+ }
- /**
- * This ConstantVisitor stores the classes referenced by the class
- * constants that it visits.
- */
- private class MyReferencedClassStorer
- extends SimplifiedVisitor
- implements ConstantVisitor
- {
- // Implementations for ConstantVisitor.
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Remember the referenced class.
- ((MyAccessFixer)classVisitor).referencedClass =
- classConstant.referencedClass;
+ referencedClass = classConstant.referencedClass;
+ }
+
+
+ // Implementations for ElementValueVisitor.
+
+ public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
+ {
+ // Set the referencing access flags and set the referenced class.
+ referencingMethodAccessFlags = ClassConstants.ACC_STATIC;
+ referencedClass = elementValue.referencedClass;
+
+ // Fix the access flags of referenced annotation method.
+ super.visitAnyElementValue(clazz, annotation, elementValue);
}
}
/**
- * This ClassVisitor and MemberVisitor fixes the access flags of the
- * classes and class members that it visits, relative to the referencing
- * class.
- *
- * This class must be static so it can be passed to the super constructor
- * of the outer class.
+ * This ClassVisitor fixes the access flags of the classes that it visits,
+ * relative to the referencing class.
*/
- private static class MyAccessFixer
- extends SimplifiedVisitor
- implements ClassVisitor,
- MemberVisitor
+ private class MyReferencedClassAccessFixer
+ extends SimplifiedVisitor
+ implements ClassVisitor,
+ AttributeVisitor,
+ InnerClassesInfoVisitor
{
- private Clazz referencingClass;
- private Clazz referencedClass;
-
-
// Implementations for ClassVisitor.
public void visitLibraryClass(LibraryClass libraryClass) {}
@@ -198,25 +194,86 @@ implements ClassVisitor
public void visitProgramClass(ProgramClass programClass)
{
+ // Do we need to update the access flags?
int currentAccessFlags = programClass.getAccessFlags();
int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ if (currentAccessLevel < AccessUtil.PUBLIC)
+ {
+ // Compute the required access level.
+ int requiredAccessLevel =
+ inSamePackage(programClass, referencingClass) ?
+ AccessUtil.PACKAGE_VISIBLE :
+ AccessUtil.PUBLIC;
+
+ // Fix the class access flags if necessary.
+ if (currentAccessLevel < requiredAccessLevel)
+ {
+ programClass.u2accessFlags =
+ AccessUtil.replaceAccessFlags(currentAccessFlags,
+ AccessUtil.accessFlags(requiredAccessLevel));
+ }
+ }
+
+ // Also check the InnerClasses attribute, if any.
+ programClass.attributesAccept(this);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
- // Compute the required access level.
- int requiredAccessLevel =
- inSamePackage(programClass, referencingClass) ?
- AccessUtil.PACKAGE_VISIBLE :
- AccessUtil.PUBLIC;
- // Fix the class access flags if necessary.
- if (currentAccessLevel < requiredAccessLevel)
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ }
+
+
+ // Implementations for InnerClassesInfoVisitor.
+
+ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+ {
+ // Is this an inner class?
+ int innerClassIndex = innerClassesInfo.u2innerClassIndex;
+ if (innerClassIndex != 0)
{
- programClass.u2accessFlags =
- AccessUtil.replaceAccessFlags(currentAccessFlags,
- AccessUtil.accessFlags(requiredAccessLevel));
+ String innerClassName = clazz.getClassName(innerClassIndex);
+ if (innerClassName.equals(clazz.getName()))
+ {
+ // Do we need to update the access flags?
+ int currentAccessFlags = innerClassesInfo.u2innerClassAccessFlags;
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ if (currentAccessLevel < AccessUtil.PUBLIC)
+ {
+ // Compute the required access level.
+ int requiredAccessLevel =
+ inSamePackage(clazz, referencingClass) ?
+ AccessUtil.PACKAGE_VISIBLE :
+ AccessUtil.PUBLIC;
+
+ // Fix the inner class access flags if necessary.
+ if (currentAccessLevel < requiredAccessLevel)
+ {
+ innerClassesInfo.u2innerClassAccessFlags =
+ AccessUtil.replaceAccessFlags(currentAccessFlags,
+ AccessUtil.accessFlags(requiredAccessLevel));
+ }
+ }
+ }
}
}
+ }
+ /**
+ * This MemberVisitor fixes the access flags of the class members that it
+ * visits, relative to the referencing class and method.
+ */
+ private class MyReferencedMemberAccessFixer
+ extends SimplifiedVisitor
+ implements MemberVisitor
+ {
// Implementations for MemberVisitor.
public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) {}
@@ -224,39 +281,44 @@ implements ClassVisitor
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
+ // Do we need to update the access flags?
int currentAccessFlags = programMember.getAccessFlags();
int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
-
- // Compute the required access level.
- // For protected access, we're taking into account the class in the
- // invocation and the class that actually contains the member.
- int requiredAccessLevel =
- programClass.equals(referencingClass) ? AccessUtil.PRIVATE :
- inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
- referencedClass != null &&
- referencingClass.extends_(referencedClass) &&
- referencingClass.extends_(programClass) ? AccessUtil.PROTECTED :
- AccessUtil.PUBLIC;
-
- // Fix the class member access flags if necessary.
- if (currentAccessLevel < requiredAccessLevel)
+ if (currentAccessLevel < AccessUtil.PUBLIC)
{
- programMember.u2accessFlags =
- AccessUtil.replaceAccessFlags(currentAccessFlags,
- AccessUtil.accessFlags(requiredAccessLevel));
+ // Compute the required access level.
+ // For protected access, the referencing method may not be
+ // static. We're also taking into account the class in the
+ // invocation and the class that actually contains the member.
+ int requiredAccessLevel =
+ programClass.equals(referencingClass) ? AccessUtil.PRIVATE :
+ inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
+ (referencingMethodAccessFlags & ClassConstants.ACC_STATIC) == 0 &&
+ (referencedClass == null ||
+ referencingClass.extends_(referencedClass)) &&
+ referencingClass.extends_(programClass) ? AccessUtil.PROTECTED :
+ AccessUtil.PUBLIC;
+
+ // Fix the class member access flags if necessary.
+ if (currentAccessLevel < requiredAccessLevel)
+ {
+ programMember.u2accessFlags =
+ AccessUtil.replaceAccessFlags(currentAccessFlags,
+ AccessUtil.accessFlags(requiredAccessLevel));
+ }
}
}
+ }
- // Small utility methods.
+ // Small utility methods.
- /**
- * Returns whether the two given classes are in the same package.
- */
- private boolean inSamePackage(Clazz class1, Clazz class2)
- {
- return ClassUtil.internalPackageName(class1.getName()).equals(
- ClassUtil.internalPackageName(class2.getName()));
- }
+ /**
+ * Returns whether the two given classes are in the same package.
+ */
+ private boolean inSamePackage(Clazz class1, Clazz class2)
+ {
+ return ClassUtil.internalPackageName(class1.getName()).equals(
+ ClassUtil.internalPackageName(class2.getName()));
}
}
=====================================
core/src/proguard/classfile/util/ClassUtil.java
=====================================
@@ -106,6 +106,7 @@ public class ClassUtil
externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_8) ? ClassConstants.CLASS_VERSION_1_8 :
externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_9_ALIAS) ||
externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_9) ? ClassConstants.CLASS_VERSION_1_9 :
+ externalClassVersion.equals(JavaConstants.CLASS_VERSION_10) ? ClassConstants.CLASS_VERSION_10 :
0;
}
@@ -128,6 +129,7 @@ public class ClassUtil
case ClassConstants.CLASS_VERSION_1_7: return JavaConstants.CLASS_VERSION_1_7;
case ClassConstants.CLASS_VERSION_1_8: return JavaConstants.CLASS_VERSION_1_8;
case ClassConstants.CLASS_VERSION_1_9: return JavaConstants.CLASS_VERSION_1_9;
+ case ClassConstants.CLASS_VERSION_10: return JavaConstants.CLASS_VERSION_10;
default: return null;
}
}
@@ -141,14 +143,14 @@ public class ClassUtil
public static void checkVersionNumbers(int internalClassVersion) throws UnsupportedOperationException
{
if (internalClassVersion < ClassConstants.CLASS_VERSION_1_0 ||
- internalClassVersion > ClassConstants.CLASS_VERSION_1_9)
+ internalClassVersion > ClassConstants.CLASS_VERSION_10)
{
throw new UnsupportedOperationException("Unsupported version number ["+
internalMajorClassVersion(internalClassVersion)+"."+
internalMinorClassVersion(internalClassVersion)+"] (maximum "+
- ClassConstants.CLASS_VERSION_1_9_MAJOR+"."+
- ClassConstants.CLASS_VERSION_1_9_MINOR+", Java "+
- JavaConstants.CLASS_VERSION_1_9+")");
+ ClassConstants.CLASS_VERSION_10_MAJOR+"."+
+ ClassConstants.CLASS_VERSION_10_MINOR+", Java "+
+ JavaConstants.CLASS_VERSION_10+")");
}
}
=====================================
core/src/proguard/classfile/visitor/MultiConstantVisitor.java
=====================================
@@ -0,0 +1,74 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2018 GuardSquare NV
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.util.ArrayUtil;
+
+
+/**
+ * This ConstantVisitor delegates all visits to each ConstantVisitor in a given list.
+ *
+ * @author Johan Leys
+ */
+public class MultiConstantVisitor
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ private ConstantVisitor[] constantVisitors;
+ private int constantVisitorCount;
+
+
+ public MultiConstantVisitor()
+ {
+ this.constantVisitors = new ConstantVisitor[16];
+ }
+
+
+ public MultiConstantVisitor(ConstantVisitor... constantVisitors)
+ {
+ this.constantVisitors = constantVisitors;
+ this.constantVisitorCount = this.constantVisitors.length;
+ }
+
+
+ public void addClassVisitor(ConstantVisitor constantVisitor)
+ {
+ constantVisitors =
+ ArrayUtil.add(constantVisitors,
+ constantVisitorCount++,
+ constantVisitor);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ for (int index = 0; index < constantVisitorCount; index++)
+ {
+ constant.accept(clazz, constantVisitors[index]);
+ }
+ }
+}
=====================================
core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
=====================================
@@ -38,7 +38,7 @@ extends SimplifiedVisitor
implements ConstantVisitor,
ElementValueVisitor
{
- private final MemberVisitor memberVisitor;
+ protected final MemberVisitor memberVisitor;
public ReferencedMemberVisitor(MemberVisitor memberVisitor)
=====================================
core/src/proguard/classfile/visitor/SimilarMemberVisitor.java
=====================================
@@ -25,7 +25,7 @@ import proguard.classfile.*;
/**
* This <code>MemberVisitor</code> lets a given <code>MemberVisitor</code>
* visit all members that have the same name and type as the visited methods
- * in the class hierarchy of a given target class.
+ * in the class hierarchy of the members' classes or of a given target class.
*
* @author Eric Lafortune
*/
@@ -40,6 +40,37 @@ implements MemberVisitor
private final MemberVisitor memberVisitor;
+ /**
+ * Creates a new SimilarMemberVisitor.
+ * @param visitThisMember specifies whether to visit the class
+ * members in the members' classes themselves.
+ * @param visitSuperMembers specifies whether to visit the class
+ * members in the super classes of the
+ * members' classes.
+ * @param visitInterfaceMembers specifies whether to visit the class
+ * members in the interface classes of the
+ * members' classes.
+ * @param visitOverridingMembers specifies whether to visit the class
+ * members in the subclasses of the members'
+ * classes.
+ * @param memberVisitor the <code>MemberVisitor</code> to which
+ * visits will be delegated.
+ */
+ public SimilarMemberVisitor(boolean visitThisMember,
+ boolean visitSuperMembers,
+ boolean visitInterfaceMembers,
+ boolean visitOverridingMembers,
+ MemberVisitor memberVisitor)
+ {
+ this(null,
+ visitThisMember,
+ visitSuperMembers,
+ visitInterfaceMembers,
+ visitOverridingMembers,
+ memberVisitor);
+ }
+
+
/**
* Creates a new SimilarMemberVisitor.
* @param targetClass the class in whose hierarchy to look for
@@ -78,6 +109,8 @@ implements MemberVisitor
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
+ Clazz targetClass = targetClass(programClass);
+
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
@@ -90,6 +123,8 @@ implements MemberVisitor
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
+ Clazz targetClass = targetClass(libraryClass);
+
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
@@ -102,6 +137,8 @@ implements MemberVisitor
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
+ Clazz targetClass = targetClass(programClass);
+
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
@@ -114,6 +151,8 @@ implements MemberVisitor
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
+ Clazz targetClass = targetClass(libraryClass);
+
targetClass.hierarchyAccept(visitThisMember,
visitSuperMembers,
visitInterfaceMembers,
@@ -122,4 +161,14 @@ implements MemberVisitor
libraryMethod.getDescriptor(libraryClass),
memberVisitor));
}
+
+
+ /**
+ * Returns the target class, or the given class if the target class is
+ * null.
+ */
+ private Clazz targetClass(Clazz clazz)
+ {
+ return targetClass != null ? targetClass : clazz;
+ }
}
\ No newline at end of file
=====================================
core/src/proguard/io/JarWriter.java
=====================================
@@ -26,7 +26,8 @@ import java.io.*;
import java.util.Date;
/**
- * This DataEntryWriter sends data entries to a given jar/zip file.
+ * This DataEntryWriter sends data entries to a the jar/zip files specified by
+ * their parents.
*
* @author Eric Lafortune
*/
=====================================
core/src/proguard/obfuscate/Obfuscator.java
=====================================
@@ -23,7 +23,7 @@ package proguard.obfuscate;
import proguard.*;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -98,10 +98,29 @@ public class Obfuscator
libraryClassPool.classesAccept(nameMarker);
libraryClassPool.classesAccept(new AllMemberVisitor(nameMarker));
+ // We also keep the names of the abstract methods of functional
+ // interfaces referenced from bootstrap method arguments (additional
+ // interfaces with LambdaMetafactory.altMetafactory).
+ // The functional method names have to match the names in the
+ // dynamic method invocations with LambdaMetafactory.
+ programClassPool.classesAccept(
+ new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
+ new AllAttributeVisitor(
+ new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
+ new AllBootstrapMethodInfoVisitor(
+ new AllBootstrapMethodArgumentVisitor(
+ new ConstantTagFilter(ClassConstants.CONSTANT_Class,
+ new ReferencedClassVisitor(
+ new FunctionalInterfaceFilter(
+ new ClassHierarchyTraveler(true, false, true, false,
+ new AllMethodVisitor(
+ new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0,
+ nameMarker))))))))))));
+
// We also keep the names of the abstract methods of functional
// interfaces that are returned by dynamic method invocations.
- // The functional method names then have to match the names
- // in the dynamic method invocations with LambdaMetafactory.
+ // The functional method names have to match the names in the
+ // dynamic method invocations with LambdaMetafactory.
programClassPool.classesAccept(
new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
new AllConstantVisitor(
=====================================
core/src/proguard/optimize/Optimizer.java
=====================================
@@ -347,18 +347,33 @@ public class Optimizer
new MethodrefTraveler(
new ReferencedMemberVisitor(keepMarker))))))));
- // We also keep all bootstrap method arguments that point to methods.
- // These arguments are typically the method handles for
- // java.lang.invoke.LambdaMetafactory#metafactory, which provides the
- // implementations for closures.
+ // We also keep classes and methods referenced from bootstrap
+ // method arguments.
programClassPool.classesAccept(
new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
new AllAttributeVisitor(
new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
new AllBootstrapMethodInfoVisitor(
- new BootstrapMethodArgumentVisitor(
- new MethodrefTraveler(
- new ReferencedMemberVisitor(keepMarker))))))));
+ new AllBootstrapMethodArgumentVisitor(
+ new MultiConstantVisitor(
+ // Class constants refer to additional functional
+ // interfaces (with LambdaMetafactory.altMetafactory).
+ new ConstantTagFilter(ClassConstants.CONSTANT_Class,
+ new ReferencedClassVisitor(
+ new FunctionalInterfaceFilter(
+ new ClassHierarchyTraveler(true, false, true, false,
+ new MultiClassVisitor(
+ keepMarker,
+ new AllMethodVisitor(
+ new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0,
+ keepMarker))
+ ))))),
+
+ // Method handle constants refer to synthetic lambda
+ // methods (with LambdaMetafactory.metafactory and
+ // altMetafactory).
+ new MethodrefTraveler(
+ new ReferencedMemberVisitor(keepMarker)))))))));
// We also keep the classes and abstract methods of functional
// interfaces that are returned by dynamic method invocations.
=====================================
core/src/proguard/preverify/CodePreverifier.java
=====================================
@@ -26,7 +26,7 @@ import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.editor.*;
import proguard.classfile.instruction.InstructionConstants;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.ClassPrinter;
import proguard.evaluation.*;
import proguard.evaluation.value.*;
@@ -271,29 +271,41 @@ implements AttributeVisitor
int offset,
TracedVariables variables)
{
- int maximumVariablesSize = variables.size();
int typeCount = 0;
- int typeIndex = 0;
-
- // Count the the number of verification types, ignoring any nulls at
- // the end.
- for (int index = 0; index < maximumVariablesSize; index++)
+ if (offset == AT_METHOD_ENTRY)
+ {
+ // Count the number of parameters, including any parameters
+ // that are unused and overwritten right away.
+ typeCount = ClassUtil.internalMethodParameterCount(
+ programMethod.getDescriptor(programClass),
+ programMethod.getAccessFlags());
+ }
+ else
{
- Value value = variables.getValue(index);
+ typeCount = 0;
- typeIndex++;
+ int maximumVariablesSize = variables.size();
+ int typeIndex = 0;
- // Remember the maximum live type index.
- if (value != null &&
- (offset == AT_METHOD_ENTRY ||
- livenessAnalyzer.isAliveBefore(offset, index)))
+ // Count the the number of verification types, ignoring any nulls at
+ // the end.
+ for (int index = 0; index < maximumVariablesSize; index++)
{
- typeCount = typeIndex;
+ Value value = variables.getValue(index);
- // Category 2 types that are alive are stored as single entries.
- if (value.isCategory2())
+ typeIndex++;
+
+ // Remember the maximum live type index.
+ if (value != null &&
+ livenessAnalyzer.isAliveBefore(offset, index))
{
- index++;
+ typeCount = typeIndex;
+
+ // Category 2 types that are alive are stored as single entries.
+ if (value.isCategory2())
+ {
+ index++;
+ }
}
}
}
@@ -301,7 +313,7 @@ implements AttributeVisitor
// Create and fill out the verification types.
VerificationType[] types = new VerificationType[typeCount];
- typeIndex = 0;
+ int typeIndex = 0;
// Note the slightly different terminating condition, because the
// types may have been truncated.
@@ -332,7 +344,12 @@ implements AttributeVisitor
}
else
{
- type = VerificationTypeFactory.createTopType();
+ // A null value at method entry means that there was a branch to
+ // offset 0 that has cleared the value. Then pick a dummy value so
+ // it never matches the next frame at offset 0.
+ type = offset == AT_METHOD_ENTRY ?
+ VerificationTypeFactory.createUninitializedThisType() :
+ VerificationTypeFactory.createTopType();
}
types[typeIndex++] = type;
=====================================
gradle/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-gradle</artifactId>
=====================================
gui/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-gui</artifactId>
=====================================
gui/src/proguard/gui/GUIResources.properties
=====================================
@@ -25,7 +25,7 @@ preverification = Preverification
#
# Panel titles.
#
-welcome = Welcome to ProGuard, version 6.0.1
+welcome = Welcome to ProGuard, version 6.0.3
options = Options
keepAdditional = Keep additional classes and class members
keepNamesAdditional = Keep additional class names and class member names
@@ -130,7 +130,7 @@ skipNonPublicLibraryClassMembers = Skip non-public library class members
keepDirectories = Keep directories
forceProcessing = Force processing
target = Target
-targets = 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8
+targets = 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,10
printSeeds = Print seeds
printConfiguration = Print configuration
dump = Print class files
=====================================
retrace/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-retrace</artifactId>
=====================================
wtk/pom.xml
=====================================
@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-parent</artifactId>
- <version>6.0.1</version>
+ <version>6.0.3</version>
<relativePath>../buildscripts/pom.xml</relativePath>
</parent>
<artifactId>proguard-wtk-plugin</artifactId>
View it on GitLab: https://salsa.debian.org/java-team/proguard/compare/6eedd5704c39f5c456396f5b207af6c7e96a6a1f...89a9f2bf8739471013a7fd818a442c6ed896e271
--
View it on GitLab: https://salsa.debian.org/java-team/proguard/compare/6eedd5704c39f5c456396f5b207af6c7e96a6a1f...89a9f2bf8739471013a7fd818a442c6ed896e271
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20181210/7881eee0/attachment.html>
More information about the pkg-java-commits
mailing list